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/>.
20 #include "config-api.h"
32 extern struct cbox_module_manifest sampler_module
;
33 extern struct cbox_module_manifest fluidsynth_module
;
34 extern struct cbox_module_manifest tonewheel_organ_module
;
35 extern struct cbox_module_manifest stream_player_module
;
36 extern struct cbox_module_manifest tone_control_module
;
37 extern struct cbox_module_manifest delay_module
;
38 extern struct cbox_module_manifest reverb_module
;
39 extern struct cbox_module_manifest parametric_eq_module
;
40 extern struct cbox_module_manifest phaser_module
;
41 extern struct cbox_module_manifest chorus_module
;
42 extern struct cbox_module_manifest fxchain_module
;
43 extern struct cbox_module_manifest jack_input_module
;
44 extern struct cbox_module_manifest feedback_reducer_module
;
45 extern struct cbox_module_manifest compressor_module
;
46 extern struct cbox_module_manifest gate_module
;
47 extern struct cbox_module_manifest distortion_module
;
48 extern struct cbox_module_manifest fuzz_module
;
49 extern struct cbox_module_manifest limiter_module
;
51 struct cbox_module_manifest
*cbox_module_list
[] = {
52 &tonewheel_organ_module
,
56 &stream_player_module
,
60 ¶metric_eq_module
,
68 &feedback_reducer_module
,
77 CBOX_CLASS_DEFINITION_ROOT(cbox_module
)
79 void cbox_module_manifest_dump(struct cbox_module_manifest
*manifest
)
81 static const char *ctl_classes
[] = { "Switch CC#", "Continuous CC#", "Cont. Param", "Discrete Param", "Enum" };
83 printf("Module: %s\n", manifest
->name
);
84 printf("Audio I/O: min %d inputs, min %d outputs\n", manifest
->min_inputs
, manifest
->min_outputs
);
86 printf("Live controllers:\n");
87 printf("Ch# Type Number Name \n");
88 printf("---- --------------- ------ ------------------------------\n");
89 for (i
= 0; i
< manifest
->num_live_controllers
; i
++)
91 struct cbox_module_livecontroller_metadata
*lc
= &manifest
->live_controllers
[i
];
92 if (lc
->channel
== 255)
98 printf("%-4d ", lc
->channel
);
99 printf("%15s %-6d %-30s\n", ctl_classes
[lc
->controller_class
], lc
->controller
, lc
->name
);
103 struct cbox_module_manifest
*cbox_module_manifest_get_by_name(const char *name
)
105 struct cbox_module_manifest
**mptr
;
107 for (mptr
= cbox_module_list
; *mptr
; mptr
++)
109 if (!strcmp((*mptr
)->name
, name
))
115 struct cbox_module
*cbox_module_manifest_create_module(struct cbox_module_manifest
*manifest
, const char *cfg_section
, struct cbox_document
*doc
, struct cbox_rt
*rt
, struct cbox_engine
*engine
, const char *instance_name
, GError
**error
)
117 g_clear_error(error
);
118 struct cbox_module
*module
= manifest
->create(manifest
->user_data
, cfg_section
, doc
, rt
, engine
, error
);
122 module
->instance_name
= g_strdup(instance_name
);
123 module
->input_samples
= malloc(sizeof(float) * CBOX_BLOCK_SIZE
* module
->inputs
);
124 module
->output_samples
= malloc(sizeof(float) * CBOX_BLOCK_SIZE
* module
->outputs
);
125 module
->engine_name
= manifest
->name
;
126 cbox_midi_buffer_init(&module
->midi_input
);
131 void cbox_module_init(struct cbox_module
*module
, struct cbox_document
*doc
, struct cbox_rt
*rt
, struct cbox_engine
*engine
, void *user_data
, int inputs
, int outputs
, cbox_process_cmd cmd_handler
, void (*destroy
)(struct cbox_module
*module
))
133 CBOX_OBJECT_HEADER_INIT(module
, cbox_module
, doc
);
134 module
->user_data
= user_data
;
136 module
->engine
= engine
;
137 module
->instance_name
= NULL
;
138 module
->input_samples
= NULL
;
139 module
->output_samples
= NULL
;
140 module
->inputs
= inputs
;
141 module
->outputs
= outputs
;
142 module
->aux_offset
= outputs
;
144 module
->srate
= engine
->io_env
.srate
;
145 module
->srate_inv
= 1.0 / module
->srate
;
147 cbox_command_target_init(&module
->cmd_target
, cmd_handler
, module
);
148 module
->process_event
= NULL
;
149 module
->process_block
= NULL
;
150 module
->destroy
= destroy
;
151 CBOX_OBJECT_REGISTER(module
);
154 struct cbox_module
*cbox_module_new_from_fx_preset(const char *name
, struct cbox_document
*doc
, struct cbox_rt
*rt
, struct cbox_engine
*engine
, GError
**error
)
156 gchar
*section
= g_strdup_printf("fxpreset:%s", name
);
157 const char *engine_name
;
158 struct cbox_module_manifest
*mptr
;
159 struct cbox_module
*effect
;
161 if (!cbox_config_has_section(section
))
163 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "No FX preset called '%s'", name
);
166 engine_name
= cbox_config_get_string(section
, "engine");
169 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "FX engine not specified for preset '%s'", name
);
172 mptr
= cbox_module_manifest_get_by_name(engine_name
);
175 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "FX preset '%s' refers to non-existing engine '%s'", name
, engine_name
);
178 effect
= cbox_module_manifest_create_module(mptr
, section
, doc
, rt
, engine
, name
, error
);
181 cbox_force_error(error
);
182 g_prefix_error(error
, "Could not instantiate FX preset '%s': ", name
);
193 gboolean
cbox_module_slot_process_cmd(struct cbox_module
**psm
,
194 struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, const char *subcmd
,
195 struct cbox_document
*doc
, struct cbox_rt
*rt
, struct cbox_engine
*engine
, GError
**error
)
197 struct cbox_module
*sm
= *psm
;
198 if (!strcmp(subcmd
, "/status") && !strcmp(cmd
->arg_types
, ""))
200 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
202 if (!(cbox_execute_on(fb
, NULL
, "/insert_engine", "s", error
, sm
? sm
->engine_name
: "") &&
203 cbox_execute_on(fb
, NULL
, "/insert_preset", "s", error
, sm
? sm
->instance_name
: "") &&
204 cbox_execute_on(fb
, NULL
, "/bypass", "i", error
, sm
? sm
->bypass
: 0)))
208 if (!strcmp(subcmd
, "/insert_preset") && !strcmp(cmd
->arg_types
, "s"))
210 struct cbox_module
*effect
= cbox_module_new_from_fx_preset(CBOX_ARG_S(cmd
, 0), doc
, rt
, engine
, error
);
213 cbox_rt_swap_pointers(rt
, (void **)psm
, effect
);
216 if (!strcmp(subcmd
, "/insert_engine") && !strcmp(cmd
->arg_types
, "s"))
218 struct cbox_module
*effect
= NULL
;
219 if (*CBOX_ARG_S(cmd
, 0))
221 struct cbox_module_manifest
*manifest
= cbox_module_manifest_get_by_name(CBOX_ARG_S(cmd
, 0));
224 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "No effect engine '%s'", CBOX_ARG_S(cmd
, 0));
227 effect
= cbox_module_manifest_create_module(manifest
, NULL
, doc
, rt
, engine
, "unnamed", error
);
231 cbox_rt_swap_pointers(rt
, (void **)psm
, effect
);
236 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "No engine on module in path '%s'", cmd
->command
);
239 if (!strncmp(subcmd
, "/engine/", 8))
241 if (!sm
->cmd_target
.process_cmd
)
243 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "The engine %s has no command target defined", sm
->engine_name
);
246 return cbox_execute_sub(&sm
->cmd_target
, fb
, cmd
, subcmd
+ 7, error
);
248 if (!strcmp(subcmd
, "/set_bypass") && !strcmp(cmd
->arg_types
, "i"))
250 sm
->bypass
= CBOX_ARG_I(cmd
, 0);
253 return cbox_object_default_process_cmd(&sm
->cmd_target
, fb
, cmd
, error
);
256 void cbox_module_swap_pointers_and_free(struct cbox_module
*sm
, void **pptr
, void *value
)
258 free(cbox_rt_swap_pointers(sm
->rt
, pptr
, value
));
261 void cbox_module_destroyfunc(struct cbox_objhdr
*hdr
)
263 struct cbox_module
*module
= CBOX_H2O(hdr
);
264 g_free(module
->instance_name
);
265 free(module
->input_samples
);
266 free(module
->output_samples
);
268 module
->destroy(module
);