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
);
77 cbox_layer_set_instrument(layer
, instr
);
83 cbox_instrument_destroy_if_unused(instr
);
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
);
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
))
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
)))
140 else if (!strcmp(cmd
->command
, "/enable") && !strcmp(cmd
->arg_types
, "i"))
142 layer
->enabled
= 0 != CBOX_ARG_I(cmd
, 0);
145 else if (!strcmp(cmd
->command
, "/consume") && !strcmp(cmd
->arg_types
, "i"))
147 layer
->consume
= 0 != CBOX_ARG_I(cmd
, 0);
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);
155 else if (!strcmp(cmd
->command
, "/disable_aftertouch") && !strcmp(cmd
->arg_types
, "i"))
157 layer
->disable_aftertouch
= 0 != CBOX_ARG_I(cmd
, 0);
160 else if (!strcmp(cmd
->command
, "/transpose") && !strcmp(cmd
->arg_types
, "i"))
162 layer
->transpose
= CBOX_ARG_I(cmd
, 0);
165 else if (!strcmp(cmd
->command
, "/fixed_note") && !strcmp(cmd
->arg_types
, "i"))
167 layer
->fixed_note
= CBOX_ARG_I(cmd
, 0);
170 else if (!strcmp(cmd
->command
, "/low_note") && !strcmp(cmd
->arg_types
, "i"))
172 layer
->low_note
= CBOX_ARG_I(cmd
, 0);
175 else if (!strcmp(cmd
->command
, "/high_note") && !strcmp(cmd
->arg_types
, "i"))
177 layer
->high_note
= CBOX_ARG_I(cmd
, 0);
180 else if (!strcmp(cmd
->command
, "/in_channel") && !strcmp(cmd
->arg_types
, "i"))
182 layer
->in_channel
= CBOX_ARG_I(cmd
, 0) - 1;
185 else if (!strcmp(cmd
->command
, "/out_channel") && !strcmp(cmd
->arg_types
, "i"))
187 layer
->out_channel
= CBOX_ARG_I(cmd
, 0) - 1;
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
);
204 l
->instrument
= NULL
;
212 l
->disable_aftertouch
= FALSE
;
213 l
->invert_sustain
= FALSE
;
215 l
->ignore_scene_transpose
= FALSE
;
217 CBOX_OBJECT_REGISTER(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 if (!layer
) goto error
;
225 struct cbox_instrument
*instr
= cbox_scene_get_instrument_by_name(scene
, instrument_name
, TRUE
, error
);
228 cbox_force_error(error
);
229 g_prefix_error(error
, "Cannot get instrument %s for new layer: ", instrument_name
);
233 cbox_layer_set_instrument(layer
, instr
);
238 cbox_instrument_destroy_if_unused(instr
);
242 struct cbox_layer
*cbox_layer_new_from_config(struct cbox_scene
*scene
, const char *layer_name
, GError
**error
)
244 struct cbox_layer
*layer
= cbox_layer_new(scene
);
248 layer
->scene
= scene
;
249 if (!cbox_layer_load(layer
, layer_name
, error
))