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"
34 struct cbox_module module
;
36 struct cbox_module
**modules
;
40 void fxchain_move(struct fxchain_module
*m
, int oldpos
, int newpos
)
44 struct cbox_module
**modules
= malloc(sizeof(struct cbox_module
*) * m
->module_count
);
45 for (int i
= 0; i
< m
->module_count
; i
++)
53 s
= (i
< oldpos
|| i
> newpos
) ? i
: i
+ 1;
55 s
= (i
< newpos
|| i
> oldpos
) ? i
: i
- 1;
57 modules
[i
] = m
->modules
[s
];
59 free(cbox_rt_swap_pointers(m
->module
.rt
, (void **)&m
->modules
, modules
));
62 gboolean
fxchain_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
64 struct fxchain_module
*m
= (struct fxchain_module
*)ct
->user_data
;
65 const char *subcommand
= NULL
;
68 //EFFECT_PARAM("/module_count", "i", stages, int, , 1, 12) else
69 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
71 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
73 for (int i
= 0; i
< m
->module_count
; i
++)
77 res
= cbox_execute_on(fb
, NULL
, "/module", "ss", error
, m
->modules
[i
]->engine_name
, m
->modules
[i
]->instance_name
);
79 res
= cbox_execute_on(fb
, NULL
, "/module", "ss", error
, "", "");
82 res
= cbox_execute_on(fb
, NULL
, "/bypass", "ii", error
, i
+ 1, m
->modules
[i
] ? m
->modules
[i
]->bypass
: 0);
84 return CBOX_OBJECT_DEFAULT_STATUS(&m
->module
, fb
, error
);
86 else if (cbox_parse_path_part_int(cmd
, "/module/", &subcommand
, &index
, 1, m
->module_count
, error
))
90 return cbox_module_slot_process_cmd(&m
->modules
[index
- 1], fb
, cmd
, subcommand
, CBOX_GET_DOCUMENT(&m
->module
), m
->module
.rt
, m
->module
.engine
, error
);
92 else if (!strcmp(cmd
->command
, "/insert") && !strcmp(cmd
->arg_types
, "i"))
94 int pos
= CBOX_ARG_I(cmd
, 0) - 1;
95 struct cbox_module
**new_modules
= malloc((m
->module_count
+ 1) * sizeof(struct cbox_module
*));
96 memcpy(new_modules
, m
->modules
, pos
* sizeof(struct cbox_module
*));
97 new_modules
[pos
] = NULL
;
98 memcpy(new_modules
+ pos
+ 1, m
->modules
+ pos
, (m
->module_count
- pos
) * sizeof(struct cbox_module
*));
99 void *old_modules
= cbox_rt_swap_pointers_and_update_count(m
->module
.rt
, (void **)&m
->modules
, new_modules
, &m
->module_count
, m
->module_count
+ 1);
103 else if (!strcmp(cmd
->command
, "/delete") && !strcmp(cmd
->arg_types
, "i"))
105 int pos
= CBOX_ARG_I(cmd
, 0) - 1;
106 struct cbox_module
**new_modules
= malloc((m
->module_count
+ 1) * sizeof(struct cbox_module
*));
107 memcpy(new_modules
, m
->modules
, pos
* sizeof(struct cbox_module
*));
108 memcpy(new_modules
+ pos
, m
->modules
+ pos
+ 1, (m
->module_count
- pos
- 1) * sizeof(struct cbox_module
*));
109 struct cbox_module
*deleted_module
= m
->modules
[pos
];
110 void *old_modules
= cbox_rt_swap_pointers_and_update_count(m
->module
.rt
, (void **)&m
->modules
, new_modules
, &m
->module_count
, m
->module_count
- 1);
113 CBOX_DELETE(deleted_module
);
116 else if (!strcmp(cmd
->command
, "/move") && !strcmp(cmd
->arg_types
, "ii"))
118 int oldpos
= CBOX_ARG_I(cmd
, 0) - 1;
119 int newpos
= CBOX_ARG_I(cmd
, 1) - 1;
120 fxchain_move(m
, oldpos
, newpos
);
123 return cbox_object_default_process_cmd(ct
, fb
, cmd
, error
);
127 void fxchain_process_event(struct cbox_module
*module
, const uint8_t *data
, uint32_t len
)
129 // struct fxchain_module *m = module->user_data;
132 void fxchain_process_block(struct cbox_module
*module
, cbox_sample_t
**inputs
, cbox_sample_t
**outputs
)
134 struct fxchain_module
*m
= module
->user_data
;
136 float bufs
[2][2][CBOX_BLOCK_SIZE
];
139 for (i
= 0; i
< m
->module_count
; i
++)
141 float *input_bufs
[2], *output_bufs
[2];
142 for (int c
= 0; c
< 2; c
++)
144 input_bufs
[c
] = i
== 0 ? inputs
[c
] : bufs
[i
& 1][c
];
145 output_bufs
[c
] = i
== m
->module_count
- 1 ? outputs
[c
] : bufs
[(i
+ 1) & 1][c
];
147 if (m
->modules
[i
] && !m
->modules
[i
]->bypass
)
148 m
->modules
[i
]->process_block(m
->modules
[i
]->user_data
, input_bufs
, output_bufs
);
151 // this is not eficient at all, but empty modules aren't likely to be used except
152 // when setting up a chain.
153 for (int c
= 0; c
< 2; c
++)
154 memcpy(output_bufs
[c
], input_bufs
[c
], CBOX_BLOCK_SIZE
* sizeof(float));
160 static void fxchain_destroyfunc(struct cbox_module
*module
)
162 struct fxchain_module
*m
= module
->user_data
;
163 for (int i
= 0; i
< m
->module_count
; i
++)
165 CBOX_DELETE(m
->modules
[i
]);
166 m
->modules
[i
] = NULL
;
171 MODULE_CREATE_FUNCTION(fxchain
)
173 static int inited
= 0;
182 gchar
*name
= g_strdup_printf("effect%d", i
+ 1);
183 const char *fx_name
= cbox_config_get_string(cfg_section
, name
);
189 if (cfg_section
&& !fx_count
)
191 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "No effects defined");
195 struct fxchain_module
*m
= malloc(sizeof(struct fxchain_module
));
196 CALL_MODULE_INIT(m
, 2, 2, fxchain
);
197 m
->module
.process_event
= fxchain_process_event
;
198 m
->module
.process_block
= fxchain_process_block
;
199 m
->modules
= malloc(sizeof(struct cbox_module
*) * fx_count
);
200 m
->module_count
= fx_count
;
202 for (i
= 0; i
< fx_count
; i
++)
203 m
->modules
[i
] = NULL
;
205 for (i
= 0; i
< fx_count
; i
++)
207 gchar
*name
= g_strdup_printf("effect%d", i
+ 1);
208 const char *fx_preset_name
= cbox_config_get_string(cfg_section
, name
);
210 m
->modules
[i
] = cbox_module_new_from_fx_preset(fx_preset_name
, doc
, rt
, engine
, error
);
220 CBOX_DELETE(&m
->module
);
225 struct cbox_module_keyrange_metadata fxchain_keyranges
[] = {
228 struct cbox_module_livecontroller_metadata fxchain_controllers
[] = {
231 DEFINE_MODULE(fxchain
, 0, 2)