Fix more warnings. Use -Wall flag to enable those warnings to show up in first place.
[calfbox.git] / layer.c
blob18fb475d740a2218b897e6b2362e820c648d0ec7
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 "config-api.h"
20 #include "errors.h"
21 #include "instr.h"
22 #include "layer.h"
23 #include "midi.h"
24 #include "module.h"
25 #include "rt.h"
26 #include "scene.h"
27 #include <glib.h>
29 gboolean cbox_layer_load(struct cbox_layer *layer, const char *name, GError **error)
31 const char *cv = NULL;
32 struct cbox_instrument *instr = NULL;
33 gchar *section = g_strdup_printf("layer:%s", name);
35 if (!cbox_config_has_section(section))
37 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Missing section for layer %s", name);
38 goto error;
41 cv = cbox_config_get_string(section, "instrument");
42 if (!cv)
44 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Instrument not specified for layer %s", name);
45 goto error;
47 instr = cbox_scene_get_instrument_by_name(layer->scene, cv, TRUE, error);
48 if (!instr)
50 cbox_force_error(error);
51 g_prefix_error(error, "Cannot get instrument %s for layer %s: ", cv, name);
52 goto error;
55 layer->enabled = cbox_config_get_int(section, "enabled", TRUE);
56 layer->low_note = 0;
57 layer->high_note = 127;
59 cv = cbox_config_get_string(section, "low_note");
60 if (cv)
61 layer->low_note = note_from_string(cv);
63 cv = cbox_config_get_string(section, "high_note");
64 if (cv)
65 layer->high_note = note_from_string(cv);
67 layer->transpose = cbox_config_get_int(section, "transpose", 0);
68 layer->fixed_note = cbox_config_get_int(section, "fixed_note", -1);
69 layer->in_channel = cbox_config_get_int(section, "in_channel", 0) - 1;
70 layer->out_channel = cbox_config_get_int(section, "out_channel", 0) - 1;
71 layer->disable_aftertouch = !cbox_config_get_int(section, "aftertouch", TRUE);
72 layer->invert_sustain = cbox_config_get_int(section, "invert_sustain", FALSE);
73 layer->consume = cbox_config_get_int(section, "consume", FALSE);
74 layer->ignore_scene_transpose = cbox_config_get_int(section, "ignore_scene_transpose", FALSE);
75 g_free(section);
77 cbox_layer_set_instrument(layer, instr);
79 return 1;
81 error:
82 if (instr)
83 cbox_instrument_destroy_if_unused(instr);
85 g_free(section);
86 return 0;
89 void cbox_layer_set_instrument(struct cbox_layer *layer, struct cbox_instrument *instrument)
91 if (layer->instrument)
93 layer->instrument->refcount--;
94 cbox_instrument_destroy_if_unused(layer->instrument);
95 layer->instrument = NULL;
97 layer->instrument = instrument;
98 layer->instrument->refcount++;
101 static gboolean cbox_layer_process_cmd(struct cbox_command_target *ct, struct cbox_command_target *fb, struct cbox_osc_command *cmd, GError **error);
103 static void cbox_layer_destroyfunc(struct cbox_objhdr *objhdr)
105 struct cbox_layer *layer = CBOX_H2O(objhdr);
106 if (layer->instrument && !--(layer->instrument->refcount))
108 if (layer->instrument->scene)
109 cbox_scene_remove_instrument(layer->instrument->scene, layer->instrument);
111 cbox_instrument_destroy_if_unused(layer->instrument);
113 free(layer);
116 gboolean cbox_layer_process_cmd(struct cbox_command_target *ct, struct cbox_command_target *fb, struct cbox_osc_command *cmd, GError **error)
118 struct cbox_layer *layer = ct->user_data;
119 if (!strcmp(cmd->command, "/status") && !strcmp(cmd->arg_types, ""))
121 if (!cbox_check_fb_channel(fb, cmd->command, error))
122 return FALSE;
124 if (!(cbox_execute_on(fb, NULL, "/enable", "i", error, (int)layer->enabled) &&
125 cbox_execute_on(fb, NULL, "/instrument_name", "s", error, layer->instrument->module->instance_name) &&
126 cbox_execute_on(fb, NULL, "/instrument_uuid", "o", error, layer->instrument) &&
127 cbox_execute_on(fb, NULL, "/consume", "i", error, (int)layer->consume) &&
128 cbox_execute_on(fb, NULL, "/ignore_scene_transpose", "i", error, (int)layer->ignore_scene_transpose) &&
129 cbox_execute_on(fb, NULL, "/disable_aftertouch", "i", error, (int)layer->disable_aftertouch) &&
130 cbox_execute_on(fb, NULL, "/transpose", "i", error, (int)layer->transpose) &&
131 cbox_execute_on(fb, NULL, "/fixed_note", "i", error, (int)layer->fixed_note) &&
132 cbox_execute_on(fb, NULL, "/low_note", "i", error, (int)layer->low_note) &&
133 cbox_execute_on(fb, NULL, "/high_note", "i", error, (int)layer->high_note) &&
134 cbox_execute_on(fb, NULL, "/in_channel", "i", error, layer->in_channel + 1) &&
135 cbox_execute_on(fb, NULL, "/out_channel", "i", error, layer->out_channel + 1) &&
136 CBOX_OBJECT_DEFAULT_STATUS(layer, fb, error)))
137 return FALSE;
138 return TRUE;
140 else if (!strcmp(cmd->command, "/enable") && !strcmp(cmd->arg_types, "i"))
142 layer->enabled = 0 != CBOX_ARG_I(cmd, 0);
143 return TRUE;
145 else if (!strcmp(cmd->command, "/consume") && !strcmp(cmd->arg_types, "i"))
147 layer->consume = 0 != CBOX_ARG_I(cmd, 0);
148 return TRUE;
150 else if (!strcmp(cmd->command, "/ignore_scene_transpose") && !strcmp(cmd->arg_types, "i"))
152 layer->ignore_scene_transpose = 0 != CBOX_ARG_I(cmd, 0);
153 return TRUE;
155 else if (!strcmp(cmd->command, "/disable_aftertouch") && !strcmp(cmd->arg_types, "i"))
157 layer->disable_aftertouch = 0 != CBOX_ARG_I(cmd, 0);
158 return TRUE;
160 else if (!strcmp(cmd->command, "/transpose") && !strcmp(cmd->arg_types, "i"))
162 layer->transpose = CBOX_ARG_I(cmd, 0);
163 return TRUE;
165 else if (!strcmp(cmd->command, "/fixed_note") && !strcmp(cmd->arg_types, "i"))
167 layer->fixed_note = CBOX_ARG_I(cmd, 0);
168 return TRUE;
170 else if (!strcmp(cmd->command, "/low_note") && !strcmp(cmd->arg_types, "i"))
172 layer->low_note = CBOX_ARG_I(cmd, 0);
173 return TRUE;
175 else if (!strcmp(cmd->command, "/high_note") && !strcmp(cmd->arg_types, "i"))
177 layer->high_note = CBOX_ARG_I(cmd, 0);
178 return TRUE;
180 else if (!strcmp(cmd->command, "/in_channel") && !strcmp(cmd->arg_types, "i"))
182 layer->in_channel = CBOX_ARG_I(cmd, 0) - 1;
183 return TRUE;
185 else if (!strcmp(cmd->command, "/out_channel") && !strcmp(cmd->arg_types, "i"))
187 layer->out_channel = CBOX_ARG_I(cmd, 0) - 1;
188 return TRUE;
190 else // otherwise, treat just like an command on normal (non-aux) output
191 return cbox_object_default_process_cmd(ct, fb, cmd, error);
194 CBOX_CLASS_DEFINITION_ROOT(cbox_layer)
196 struct cbox_layer *cbox_layer_new(struct cbox_scene *scene)
198 struct cbox_document *doc = CBOX_GET_DOCUMENT(scene);
199 struct cbox_layer *l = malloc(sizeof(struct cbox_layer));
201 CBOX_OBJECT_HEADER_INIT(l, cbox_layer, doc);
202 cbox_command_target_init(&l->cmd_target, cbox_layer_process_cmd, l);
203 l->enabled = TRUE;
204 l->instrument = NULL;
205 l->low_note = 0;
206 l->high_note = 127;
208 l->transpose = 0;
209 l->fixed_note = -1;
210 l->in_channel = -1;
211 l->out_channel = -1;
212 l->disable_aftertouch = FALSE;
213 l->invert_sustain = FALSE;
214 l->consume = FALSE;
215 l->ignore_scene_transpose = FALSE;
216 l->scene = scene;
217 CBOX_OBJECT_REGISTER(l);
218 return l;
221 struct cbox_layer *cbox_layer_new_with_instrument(struct cbox_scene *scene, const char *instrument_name, GError **error)
223 struct cbox_layer *layer = cbox_layer_new(scene);
224 struct cbox_instrument *instr = NULL;
225 if (!layer) goto error;
226 instr = cbox_scene_get_instrument_by_name(scene, instrument_name, TRUE, error);
227 if (!instr)
229 cbox_force_error(error);
230 g_prefix_error(error, "Cannot get instrument %s for new layer: ", instrument_name);
231 CBOX_DELETE(layer);
232 return NULL;
234 cbox_layer_set_instrument(layer, instr);
235 return layer;
237 error:
238 CBOX_DELETE(layer);
239 if (instr)
240 cbox_instrument_destroy_if_unused(instr);
241 return NULL;
244 struct cbox_layer *cbox_layer_new_from_config(struct cbox_scene *scene, const char *layer_name, GError **error)
246 struct cbox_layer *layer = cbox_layer_new(scene);
247 if (!layer)
248 goto error;
250 layer->scene = scene;
251 if (!cbox_layer_load(layer, layer_name, error))
252 goto error;
254 return layer;
256 error:
257 CBOX_DELETE(layer);
258 return NULL;