Attempt at implementing per-channel output setting in the sampler.
[calfbox.git] / recsrc.c
blobfb22edc2d77511f54b7de3a0baae4f47c3d59532
1 /*
2 Calf Box, an open source musical instrument.
3 Copyright (C) 2010-2011 Krzysztof Foltman
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "app.h"
20 #include "errors.h"
21 #include "recsrc.h"
22 #include "rt.h"
23 #include "scene.h"
24 #include "stm.h"
26 CBOX_CLASS_DEFINITION_ROOT(cbox_recorder)
28 static gboolean cbox_recording_source_process_cmd(struct cbox_command_target *ct, struct cbox_command_target *fb, struct cbox_osc_command *cmd, GError **error);
30 void cbox_recording_source_init(struct cbox_recording_source *src, struct cbox_scene *scene, uint32_t max_numsamples, int channels)
32 src->scene = scene;
33 src->handlers = NULL;
34 src->handler_count = 0;
35 src->max_numsamples = max_numsamples;
36 src->channels = channels;
37 cbox_command_target_init(&src->cmd_target, cbox_recording_source_process_cmd, src);
40 gboolean cbox_recording_source_attach(struct cbox_recording_source *src, struct cbox_recorder *rec, GError **error)
42 if (!rec->attach(rec, src, error))
43 return FALSE;
44 cbox_rt_array_insert(app.rt, (void ***)&src->handlers, &src->handler_count, 0, rec);
45 return TRUE;
48 int cbox_recording_source_detach(struct cbox_recording_source *src, struct cbox_recorder *rec, GError **error)
50 int index = -1;
51 for (int i = 0; i < src->handler_count; i++)
53 if (src->handlers[i] == rec)
55 index = i;
56 break;
59 if (index == -1)
61 if (error)
62 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Recorder is not attached to this source");
63 return 0;
66 cbox_rt_array_remove(app.rt, (void ***)&src->handlers, &src->handler_count, index);
67 // XXXKF: when converting to async API, the array_remove must be done synchronously or
68 // detach needs to be called in the cleanup part of the remove command, otherwise detach
69 // may be called on 'live' recorder, which may cause unpredictable results.
70 return rec->detach(rec, error);
73 void cbox_recording_source_push(struct cbox_recording_source *src, const float **buffers, uint32_t numsamples)
75 for (int i = 0; i < src->handler_count; i++)
76 src->handlers[i]->record_block(src->handlers[i], buffers, numsamples);
79 void cbox_recording_source_uninit(struct cbox_recording_source *src)
81 STM_ARRAY_FREE_OBJS(src->handlers, src->handler_count);
82 src->handler_count = 0;
85 gboolean cbox_recording_source_process_cmd(struct cbox_command_target *ct, struct cbox_command_target *fb, struct cbox_osc_command *cmd, GError **error)
87 struct cbox_recording_source *src = ct->user_data;
88 if (!strcmp(cmd->command, "/status") && !strcmp(cmd->arg_types, ""))
90 if (!cbox_check_fb_channel(fb, cmd->command, error))
91 return FALSE;
93 for (int i = 0; i < src->handler_count; i++)
95 if (!cbox_execute_on(fb, NULL, "/handler", "o", error, src->handlers[i]))
96 return FALSE;
98 return TRUE;
100 else
101 if (!strcmp(cmd->command, "/attach") && !strcmp(cmd->arg_types, "s"))
103 struct cbox_objhdr *objhdr = CBOX_ARG_O(cmd, 0, src->scene, cbox_recorder, error);
104 if (!objhdr)
105 return FALSE;
106 struct cbox_recorder *rec = CBOX_H2O(objhdr);
107 return cbox_recording_source_attach(src, rec, error);
109 else
110 if (!strcmp(cmd->command, "/detach") && !strcmp(cmd->arg_types, "s"))
112 struct cbox_objhdr *objhdr = CBOX_ARG_O(cmd, 0, src->scene, cbox_recorder, error);
113 if (!objhdr)
114 return FALSE;
115 struct cbox_recorder *rec = CBOX_H2O(objhdr);
116 return cbox_recording_source_detach(src, rec, error);
118 else
119 return cbox_set_command_error(error, cmd);
122 void cbox_recorder_destroyfunc(struct cbox_objhdr *objhdr)
124 struct cbox_recorder *recorder = CBOX_H2O(objhdr);
125 recorder->destroy(recorder);