2 Calf Box, an open source musical instrument.
3 Copyright (C) 2010-2013 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/>.
21 #include "config-api.h"
49 int cmd_quit(struct cbox_menu_item_command
*item
, void *context
)
54 int cmd_load_scene(struct cbox_menu_item_command
*item
, void *context
)
57 struct cbox_scene
*scene
= app
.engine
->scenes
[0];
58 cbox_scene_clear(scene
);
59 if (!cbox_scene_load(scene
, item
->item
.item_context
, &error
))
60 cbox_print_error(error
);
64 int cmd_load_instrument(struct cbox_menu_item_command
*item
, void *context
)
67 struct cbox_scene
*scene
= app
.engine
->scenes
[0];
68 cbox_scene_clear(scene
);
69 struct cbox_layer
*layer
= cbox_layer_new_with_instrument(scene
, (char *)item
->item
.item_context
, &error
);
73 if (!cbox_scene_add_layer(scene
, layer
, &error
))
74 cbox_print_error(error
);
78 cbox_print_error(error
);
83 int cmd_load_layer(struct cbox_menu_item_command
*item
, void *context
)
86 struct cbox_scene
*scene
= app
.engine
->scenes
[0];
87 cbox_scene_clear(scene
);
88 struct cbox_layer
*layer
= cbox_layer_new_from_config(scene
, (char *)item
->item
.item_context
, &error
);
92 if (!cbox_scene_add_layer(scene
, layer
, &error
))
93 cbox_print_error(error
);
97 cbox_print_error(error
);
103 gchar
*scene_format_value(const struct cbox_menu_item_static
*item
, void *context
)
105 if (app
.current_scene_name
)
106 return strdup(app
.current_scene_name
);
108 return strdup("- No scene -");
111 gchar
*transport_format_value(const struct cbox_menu_item_static
*item
, void *context
)
114 // struct cbox_bbt bbt;
115 // cbox_master_to_bbt(app.engine->master, &bbt);
116 if (app
.engine
->master
->spb
== NULL
)
117 return g_strdup("N/A");
118 if (!strcmp((const char *)item
->item
.item_context
, "pos"))
119 return g_strdup_printf("%d", (int)app
.engine
->master
->spb
->song_pos_samples
);
121 return g_strdup_printf("%d", (int)app
.engine
->master
->spb
->song_pos_ppqn
);
124 struct cbox_config_section_cb_data
126 struct cbox_menu
*menu
;
127 cbox_menu_item_execute_func func
;
131 static void config_key_process(void *user_data
, const char *key
)
133 struct cbox_config_section_cb_data
*data
= user_data
;
135 if (!strncmp(key
, data
->prefix
, strlen(data
->prefix
)))
137 char *title
= cbox_config_get_string(key
, "title");
139 cbox_menu_add_item(data
->menu
, cbox_menu_item_new_command(title
, data
->func
, strdup(key
+ strlen(data
->prefix
))));
141 cbox_menu_add_item(data
->menu
, cbox_menu_item_new_command(key
, data
->func
, strdup(key
+ strlen(data
->prefix
))));
145 struct cbox_menu
*create_scene_menu(struct cbox_menu_item_menu
*item
, void *menu_context
)
147 struct cbox_menu
*scene_menu
= cbox_menu_new();
148 struct cbox_config_section_cb_data cb
= { .menu
= scene_menu
};
150 cbox_menu_add_item(scene_menu
, cbox_menu_item_new_static("Scenes", NULL
, NULL
));
151 cb
.prefix
= "scene:";
152 cb
.func
= cmd_load_scene
;
153 cbox_config_foreach_section(config_key_process
, &cb
);
154 cbox_menu_add_item(scene_menu
, cbox_menu_item_new_static("Layers", NULL
, NULL
));
155 cb
.prefix
= "layer:";
156 cb
.func
= cmd_load_layer
;
157 cbox_config_foreach_section(config_key_process
, &cb
);
158 cbox_menu_add_item(scene_menu
, cbox_menu_item_new_static("Instruments", NULL
, NULL
));
159 cb
.prefix
= "instrument:";
160 cb
.func
= cmd_load_instrument
;
161 cbox_config_foreach_section(config_key_process
, &cb
);
163 cbox_menu_add_item(scene_menu
, cbox_menu_item_new_menu("OK", NULL
, NULL
));
168 ///////////////////////////////////////////////////////////////////////////////
170 static struct cbox_command_target
*find_module_target(const char *type
, GError
**error
)
172 struct cbox_scene
*scene
= app
.engine
->scenes
[0];
173 for (int i
= 0; i
< scene
->instrument_count
; i
++)
175 if (!strcmp(scene
->instruments
[i
]->module
->engine_name
, type
))
176 return &scene
->instruments
[i
]->module
->cmd_target
;
178 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot find a module of type '%s'", type
);
183 int cmd_stream_rewind(struct cbox_menu_item_command
*item
, void *context
)
185 GError
*error
= NULL
;
186 struct cbox_command_target
*target
= find_module_target("stream_player", &error
);
188 cbox_execute_on(target
, NULL
, "/seek", "i", &error
, 0);
189 cbox_print_error_if(error
);
193 int cmd_stream_play(struct cbox_menu_item_command
*item
, void *context
)
195 GError
*error
= NULL
;
196 struct cbox_command_target
*target
= find_module_target("stream_player", &error
);
198 cbox_execute_on(target
, NULL
, "/play", "", &error
);
199 cbox_print_error_if(error
);
203 int cmd_stream_stop(struct cbox_menu_item_command
*item
, void *context
)
205 GError
*error
= NULL
;
206 struct cbox_command_target
*target
= find_module_target("stream_player", &error
);
208 cbox_execute_on(target
, NULL
, "/stop", "", &error
);
209 cbox_print_error_if(error
);
213 int cmd_stream_unload(struct cbox_menu_item_command
*item
, void *context
)
215 GError
*error
= NULL
;
216 struct cbox_command_target
*target
= find_module_target("stream_player", &error
);
218 cbox_execute_on(target
, NULL
, "/unload", "", &error
);
219 cbox_print_error_if(error
);
223 gboolean
result_parser_status(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
225 cbox_osc_command_dump(cmd
);
229 int cmd_stream_status(struct cbox_menu_item_command
*item
, void *context
)
231 struct cbox_command_target response
= { NULL
, result_parser_status
};
232 GError
*error
= NULL
;
233 struct cbox_command_target
*target
= find_module_target("stream_player", &error
);
235 cbox_execute_on(target
, &response
, "/status", "", &error
);
236 cbox_print_error_if(error
);
240 int cmd_stream_load(struct cbox_menu_item_command
*item
, void *context
)
242 GError
*error
= NULL
;
243 struct cbox_command_target
*target
= find_module_target("stream_player", &error
);
245 cbox_execute_on(target
, NULL
, "/load", "si", &error
, (gchar
*)item
->item
.item_context
, 0);
246 cbox_print_error_if(error
);
250 struct cbox_menu
*create_stream_menu(struct cbox_menu_item_menu
*item
, void *menu_context
)
252 struct cbox_menu
*menu
= cbox_menu_new();
254 cbox_menu_add_item(menu
, cbox_menu_item_new_static("Module commands", NULL
, NULL
));
255 cbox_menu_add_item(menu
, cbox_menu_item_new_command("Play stream", cmd_stream_play
, NULL
));
256 cbox_menu_add_item(menu
, cbox_menu_item_new_command("Stop stream", cmd_stream_stop
, NULL
));
257 cbox_menu_add_item(menu
, cbox_menu_item_new_command("Rewind stream", cmd_stream_rewind
, NULL
));
258 cbox_menu_add_item(menu
, cbox_menu_item_new_command("Describe stream", cmd_stream_status
, NULL
));
259 cbox_menu_add_item(menu
, cbox_menu_item_new_command("Unload stream", cmd_stream_unload
, NULL
));
262 if (glob("*.wav", GLOB_TILDE_CHECK
, NULL
, &g
) == 0)
264 for (int i
= 0; i
< g
.gl_pathc
; i
++)
266 cbox_menu_add_item(menu
, cbox_menu_item_new_command(g_strdup_printf("Load: %s", g
.gl_pathv
[i
]), cmd_stream_load
, g_strdup(g
.gl_pathv
[i
])));
272 cbox_menu_add_item(menu
, cbox_menu_item_new_menu("OK", NULL
, NULL
));
277 ///////////////////////////////////////////////////////////////////////////////
279 static void restart_song()
281 cbox_master_stop(app
.engine
->master
);
282 cbox_master_seek_ppqn(app
.engine
->master
, 0);
283 cbox_master_play(app
.engine
->master
);
286 int cmd_pattern_none(struct cbox_menu_item_command
*item
, void *context
)
288 cbox_song_clear(app
.engine
->master
->song
);
289 cbox_engine_update_song_playback(app
.engine
);
293 int cmd_pattern_simple(struct cbox_menu_item_command
*item
, void *context
)
295 cbox_song_use_looped_pattern(app
.engine
->master
->song
, cbox_midi_pattern_new_metronome(app
.engine
->master
->song
, 1, app
.engine
->master
->ppqn_factor
));
300 int cmd_pattern_normal(struct cbox_menu_item_command
*item
, void *context
)
302 cbox_song_use_looped_pattern(app
.engine
->master
->song
, cbox_midi_pattern_new_metronome(app
.engine
->master
->song
, app
.engine
->master
->timesig_nom
, app
.engine
->master
->ppqn_factor
));
307 int cmd_load_drumpattern(struct cbox_menu_item_command
*item
, void *context
)
309 cbox_song_use_looped_pattern(app
.engine
->master
->song
, cbox_midi_pattern_load(app
.engine
->master
->song
, item
->item
.item_context
, 1, app
.engine
->master
->ppqn_factor
));
314 int cmd_load_drumtrack(struct cbox_menu_item_command
*item
, void *context
)
316 cbox_song_use_looped_pattern(app
.engine
->master
->song
, cbox_midi_pattern_load_track(app
.engine
->master
->song
, item
->item
.item_context
, 1, app
.engine
->master
->ppqn_factor
));
321 int cmd_load_pattern(struct cbox_menu_item_command
*item
, void *context
)
323 cbox_song_use_looped_pattern(app
.engine
->master
->song
, cbox_midi_pattern_load(app
.engine
->master
->song
, item
->item
.item_context
, 0, app
.engine
->master
->ppqn_factor
));
328 int cmd_load_track(struct cbox_menu_item_command
*item
, void *context
)
330 cbox_song_use_looped_pattern(app
.engine
->master
->song
, cbox_midi_pattern_load_track(app
.engine
->master
->song
, item
->item
.item_context
, 0, app
.engine
->master
->ppqn_factor
));
335 struct cbox_menu
*create_pattern_menu(struct cbox_menu_item_menu
*item
, void *menu_context
)
337 struct cbox_menu
*menu
= cbox_menu_new();
338 struct cbox_config_section_cb_data cb
= { .menu
= menu
};
340 cbox_menu_add_item(menu
, cbox_menu_item_new_static("Pattern commands", NULL
, NULL
));
341 cbox_menu_add_item(menu
, cbox_menu_item_new_command("No pattern", cmd_pattern_none
, NULL
));
342 cbox_menu_add_item(menu
, cbox_menu_item_new_command("Simple metronome", cmd_pattern_simple
, NULL
));
343 cbox_menu_add_item(menu
, cbox_menu_item_new_command("Normal metronome", cmd_pattern_normal
, NULL
));
345 cbox_menu_add_item(menu
, cbox_menu_item_new_static("Drum tracks", NULL
, NULL
));
346 cb
.prefix
= "drumtrack:";
347 cb
.func
= cmd_load_drumtrack
;
348 cbox_config_foreach_section(config_key_process
, &cb
);
350 cbox_menu_add_item(menu
, cbox_menu_item_new_static("Melodic tracks", NULL
, NULL
));
351 cb
.prefix
= "track:";
352 cb
.func
= cmd_load_track
;
353 cbox_config_foreach_section(config_key_process
, &cb
);
355 cbox_menu_add_item(menu
, cbox_menu_item_new_static("Drum patterns", NULL
, NULL
));
356 cb
.prefix
= "drumpattern:";
357 cb
.func
= cmd_load_drumpattern
;
358 cbox_config_foreach_section(config_key_process
, &cb
);
360 cbox_menu_add_item(menu
, cbox_menu_item_new_static("Melodic patterns", NULL
, NULL
));
361 cb
.prefix
= "pattern:";
362 cb
.func
= cmd_load_pattern
;
363 cbox_config_foreach_section(config_key_process
, &cb
);
365 cbox_menu_add_item(menu
, cbox_menu_item_new_menu("OK", NULL
, NULL
));
370 struct cbox_menu
*create_main_menu()
372 struct cbox_menu
*main_menu
= cbox_menu_new();
373 cbox_menu_add_item(main_menu
, cbox_menu_item_new_static("Current scene:", scene_format_value
, NULL
));
374 cbox_menu_add_item(main_menu
, cbox_menu_item_new_dynamic_menu("Set scene", create_scene_menu
, NULL
));
375 cbox_menu_add_item(main_menu
, cbox_menu_item_new_dynamic_menu("Module control", create_stream_menu
, NULL
));
376 cbox_menu_add_item(main_menu
, cbox_menu_item_new_dynamic_menu("Pattern control", create_pattern_menu
, NULL
));
378 cbox_menu_add_item(main_menu
, cbox_menu_item_new_static("Variables", NULL
, NULL
));
379 // cbox_menu_add_item(main_menu, cbox_menu_item_new_int("foo:", &var1, 0, 127, NULL));
380 // cbox_menu_add_item(main_menu, "bar:", menu_item_value_double, &mx_double_var2, &var2);
381 cbox_menu_add_item(main_menu
, cbox_menu_item_new_static("pos:", transport_format_value
, "pos"));
382 cbox_menu_add_item(main_menu
, cbox_menu_item_new_static("bbt:", transport_format_value
, "bbt"));
383 cbox_menu_add_item(main_menu
, cbox_menu_item_new_static("Commands", NULL
, NULL
));
384 cbox_menu_add_item(main_menu
, cbox_menu_item_new_command("Quit", cmd_quit
, NULL
));