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"
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
);
41 cv
= cbox_config_get_string(section
, "instrument");
44 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Instrument not specified for layer %s", name
);
47 instr
= cbox_scene_get_instrument_by_name(layer
->scene
, cv
, TRUE
, error
);
50 cbox_force_error(error
);
51 g_prefix_error(error
, "Cannot get instrument %s for layer %s: ", cv
, name
);
55 layer
->enabled
= cbox_config_get_int(section
, "enabled", TRUE
);
57 layer
->high_note
= 127;
59 cv
= cbox_config_get_string(section
, "low_note");
61 layer
->low_note
= note_from_string(cv
);
63 cv
= cbox_config_get_string(section
, "high_note");
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 layer
->ignore_program_changes
= cbox_config_get_int(section
, "ignore_program_changes", FALSE
);
78 cbox_layer_set_instrument(layer
, instr
);
84 cbox_instrument_destroy_if_unused(instr
);
90 void cbox_layer_set_instrument(struct cbox_layer
*layer
, struct cbox_instrument
*instrument
)
92 if (layer
->instrument
)
94 layer
->instrument
->refcount
--;
95 cbox_instrument_destroy_if_unused(layer
->instrument
);
96 layer
->instrument
= NULL
;
98 layer
->instrument
= instrument
;
99 layer
->instrument
->refcount
++;
102 static gboolean
cbox_layer_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
);
104 static void cbox_layer_destroyfunc(struct cbox_objhdr
*objhdr
)
106 struct cbox_layer
*layer
= CBOX_H2O(objhdr
);
107 if (layer
->instrument
&& !--(layer
->instrument
->refcount
))
109 if (layer
->instrument
->scene
)
110 cbox_scene_remove_instrument(layer
->instrument
->scene
, layer
->instrument
);
112 cbox_instrument_destroy_if_unused(layer
->instrument
);
117 gboolean
cbox_layer_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
119 struct cbox_layer
*layer
= ct
->user_data
;
120 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
122 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
125 if (!(cbox_execute_on(fb
, NULL
, "/enable", "i", error
, (int)layer
->enabled
) &&
126 cbox_execute_on(fb
, NULL
, "/instrument_name", "s", error
, layer
->instrument
->module
->instance_name
) &&
127 cbox_execute_on(fb
, NULL
, "/instrument_uuid", "o", error
, layer
->instrument
) &&
128 cbox_execute_on(fb
, NULL
, "/consume", "i", error
, (int)layer
->consume
) &&
129 cbox_execute_on(fb
, NULL
, "/ignore_scene_transpose", "i", error
, (int)layer
->ignore_scene_transpose
) &&
130 cbox_execute_on(fb
, NULL
, "/ignore_program_changes", "i", error
, (int)layer
->ignore_program_changes
) &&
131 cbox_execute_on(fb
, NULL
, "/disable_aftertouch", "i", error
, (int)layer
->disable_aftertouch
) &&
132 cbox_execute_on(fb
, NULL
, "/transpose", "i", error
, (int)layer
->transpose
) &&
133 cbox_execute_on(fb
, NULL
, "/fixed_note", "i", error
, (int)layer
->fixed_note
) &&
134 cbox_execute_on(fb
, NULL
, "/low_note", "i", error
, (int)layer
->low_note
) &&
135 cbox_execute_on(fb
, NULL
, "/high_note", "i", error
, (int)layer
->high_note
) &&
136 cbox_execute_on(fb
, NULL
, "/in_channel", "i", error
, layer
->in_channel
+ 1) &&
137 cbox_execute_on(fb
, NULL
, "/out_channel", "i", error
, layer
->out_channel
+ 1) &&
138 CBOX_OBJECT_DEFAULT_STATUS(layer
, fb
, error
)))
142 else if (!strcmp(cmd
->command
, "/enable") && !strcmp(cmd
->arg_types
, "i"))
144 layer
->enabled
= 0 != CBOX_ARG_I(cmd
, 0);
147 else if (!strcmp(cmd
->command
, "/consume") && !strcmp(cmd
->arg_types
, "i"))
149 layer
->consume
= 0 != CBOX_ARG_I(cmd
, 0);
152 else if (!strcmp(cmd
->command
, "/ignore_scene_transpose") && !strcmp(cmd
->arg_types
, "i"))
154 layer
->ignore_scene_transpose
= 0 != CBOX_ARG_I(cmd
, 0);
157 else if (!strcmp(cmd
->command
, "/ignore_program_changes") && !strcmp(cmd
->arg_types
, "i"))
159 layer
->ignore_program_changes
= 0 != CBOX_ARG_I(cmd
, 0);
162 else if (!strcmp(cmd
->command
, "/disable_aftertouch") && !strcmp(cmd
->arg_types
, "i"))
164 layer
->disable_aftertouch
= 0 != CBOX_ARG_I(cmd
, 0);
167 else if (!strcmp(cmd
->command
, "/transpose") && !strcmp(cmd
->arg_types
, "i"))
169 layer
->transpose
= CBOX_ARG_I(cmd
, 0);
172 else if (!strcmp(cmd
->command
, "/fixed_note") && !strcmp(cmd
->arg_types
, "i"))
174 layer
->fixed_note
= CBOX_ARG_I(cmd
, 0);
177 else if (!strcmp(cmd
->command
, "/low_note") && !strcmp(cmd
->arg_types
, "i"))
179 layer
->low_note
= CBOX_ARG_I(cmd
, 0);
182 else if (!strcmp(cmd
->command
, "/high_note") && !strcmp(cmd
->arg_types
, "i"))
184 layer
->high_note
= CBOX_ARG_I(cmd
, 0);
187 else if (!strcmp(cmd
->command
, "/in_channel") && !strcmp(cmd
->arg_types
, "i"))
189 layer
->in_channel
= CBOX_ARG_I(cmd
, 0) - 1;
192 else if (!strcmp(cmd
->command
, "/out_channel") && !strcmp(cmd
->arg_types
, "i"))
194 layer
->out_channel
= CBOX_ARG_I(cmd
, 0) - 1;
197 else // otherwise, treat just like an command on normal (non-aux) output
198 return cbox_object_default_process_cmd(ct
, fb
, cmd
, error
);
201 CBOX_CLASS_DEFINITION_ROOT(cbox_layer
)
203 struct cbox_layer
*cbox_layer_new(struct cbox_scene
*scene
)
205 struct cbox_document
*doc
= CBOX_GET_DOCUMENT(scene
);
206 struct cbox_layer
*l
= malloc(sizeof(struct cbox_layer
));
208 CBOX_OBJECT_HEADER_INIT(l
, cbox_layer
, doc
);
209 cbox_command_target_init(&l
->cmd_target
, cbox_layer_process_cmd
, l
);
211 l
->instrument
= NULL
;
219 l
->disable_aftertouch
= FALSE
;
220 l
->invert_sustain
= FALSE
;
222 l
->ignore_scene_transpose
= FALSE
;
223 l
->ignore_program_changes
= FALSE
;
225 CBOX_OBJECT_REGISTER(l
);
229 struct cbox_layer
*cbox_layer_new_with_instrument(struct cbox_scene
*scene
, const char *instrument_name
, GError
**error
)
231 struct cbox_layer
*layer
= cbox_layer_new(scene
);
232 struct cbox_instrument
*instr
= NULL
;
233 if (!layer
) goto error
;
234 instr
= cbox_scene_get_instrument_by_name(scene
, instrument_name
, TRUE
, error
);
237 cbox_force_error(error
);
238 g_prefix_error(error
, "Cannot get instrument %s for new layer: ", instrument_name
);
242 cbox_layer_set_instrument(layer
, instr
);
248 cbox_instrument_destroy_if_unused(instr
);
252 struct cbox_layer
*cbox_layer_new_from_config(struct cbox_scene
*scene
, const char *layer_name
, GError
**error
)
254 struct cbox_layer
*layer
= cbox_layer_new(scene
);
258 layer
->scene
= scene
;
259 if (!cbox_layer_load(layer
, layer_name
, error
))