diff --git a/template/calfbox/py/cbox.py b/template/calfbox/py/cbox.py index acefc6e..9f0d456 100644 --- a/template/calfbox/py/cbox.py +++ b/template/calfbox/py/cbox.py @@ -1114,6 +1114,10 @@ class SamplerProgram(DocObj): return {self.get_global() : self.get_global().get_hierarchy()} def get_control_inits(self): return self.get_thing("/control_inits", '/control_init', [(int, int)]) + def get_control_labels(self): + return self.get_thing("/control_labels", '/control_label', {int : str}) + def get_key_labels(self): + return self.get_thing("/key_labels", '/key_label', {int : str}) def get_keyswitch_groups(self): return self.get_thing("/keyswitch_groups", '/key_range', [(int, int)]) def new_group(self): diff --git a/template/calfbox/sampler_layer.c b/template/calfbox/sampler_layer.c index 4386738..bea11ec 100644 --- a/template/calfbox/sampler_layer.c +++ b/template/calfbox/sampler_layer.c @@ -482,8 +482,7 @@ struct sampler_layer_param_entry sampler_layer_params[] = { FIELD_NONFUNCTIONAL("master_label") //ARIA FIELD_NONFUNCTIONAL("global_label") //ARIA FIELD_NONFUNCTIONAL("sw_label") //Keyswitch. ARIA - FIELD_NONFUNCTIONAL("label_cc#") //ARIA - FIELD_NONFUNCTIONAL("label_key#") //sfizz opcode + //label_cc and label_key are in sfzloader.c because they are under { "genericmod_#_#_#_#", -1, slpt_generic_modulation, 0, 0, NULL, NULL, NULL }, }; @@ -2105,4 +2104,3 @@ void sampler_layer_update(struct sampler_layer *l) cbox_rt_execute_cmd_async(l->module->module.rt, &rtcmd, lcmd); } - diff --git a/template/calfbox/sampler_prg.c b/template/calfbox/sampler_prg.c index 4be0ea6..abe22e4 100644 --- a/template/calfbox/sampler_prg.c +++ b/template/calfbox/sampler_prg.c @@ -191,12 +191,25 @@ static gboolean sampler_program_process_cmd(struct cbox_command_target *ct, stru return FALSE; for (GSList *p = program->ctrl_label_list; p; p = p->next) { - const struct sampler_ctrllabel *cin = (const struct sampler_ctrllabel *)&p->data; + const struct sampler_ctrllabel *cin = (const struct sampler_ctrllabel *)p->data; if (!cbox_execute_on(fb, NULL, "/control_label", "is", error, (int)cin->controller, cin->label)) return FALSE; } return TRUE; } + if (!strcmp(cmd->command, "/key_labels") && !strcmp(cmd->arg_types, "")) + //Because "key" is a programming keyword as well we use "pitch" instead internally + { + if (!cbox_check_fb_channel(fb, cmd->command, error)) + return FALSE; + for (GSList *p = program->pitch_label_list; p; p = p->next) + { + const struct sampler_pitchlabel *cin = (const struct sampler_pitchlabel *)p->data; + if (!cbox_execute_on(fb, NULL, "/key_label", "is", error, (int)cin->pitch, cin->label)) + return FALSE; + } + return TRUE; + } if (!strcmp(cmd->command, "/add_control_init") && !strcmp(cmd->arg_types, "ii")) { sampler_program_add_controller_init(program, CBOX_ARG_I(cmd, 0), CBOX_ARG_I(cmd, 1)); @@ -280,6 +293,7 @@ struct sampler_program *sampler_program_new(struct sampler_module *m, int prog_n prg->rll = NULL; prg->ctrl_init_list = NULL; prg->ctrl_label_list = NULL; + prg->pitch_label_list = NULL; prg->global = sampler_layer_new(m, prg, NULL); prg->global->default_child = sampler_layer_new(m, prg, prg->global); prg->global->default_child->default_child = sampler_layer_new(m, prg, prg->global->default_child); @@ -297,11 +311,11 @@ struct sampler_program *sampler_program_new(struct sampler_module *m, int prog_n struct sampler_program *sampler_program_new_from_cfg(struct sampler_module *m, const char *cfg_section, const char *name, int pgm_id, GError **error) { int i; - + char *name2 = NULL, *sfz_path = NULL, *spath = NULL, *tar_name = NULL; const char *sfz = NULL; struct cbox_tarfile *tarfile = NULL; - + g_clear_error(error); tar_name = cbox_config_get_string(cfg_section, "tar"); if (!strncmp(cfg_section, "spgm:!", 6)) @@ -337,7 +351,7 @@ struct sampler_program *sampler_program_new_from_cfg(struct sampler_module *m, c } } else - { + { if (tar_name) { tarfile = cbox_tarpool_get_tarfile(app.tarpool, tar_name, error); @@ -357,7 +371,7 @@ struct sampler_program *sampler_program_new_from_cfg(struct sampler_module *m, c if (tarfile && !sfz_path) sfz_path = "."; } - + if (sfz && !sfz_path && !spath && !tarfile) { char *lastslash = strrchr(sfz, '/'); @@ -380,7 +394,7 @@ struct sampler_program *sampler_program_new_from_cfg(struct sampler_module *m, c ); if (!prg) return NULL; - + if (sfz) { if (sfz_path) @@ -397,7 +411,7 @@ struct sampler_program *sampler_program_new_from_cfg(struct sampler_module *m, c } else { prg->source_file = g_strdup_printf("config:%s", cfg_section); } - + for (i = 0; ; i++) { gchar *s = g_strdup_printf("group%d", 1 + i); @@ -405,7 +419,7 @@ struct sampler_program *sampler_program_new_from_cfg(struct sampler_module *m, c g_free(s); if (!group_section) break; - + gchar *swhere = g_strdup_printf("sgroup:%s", group_section); struct sampler_layer *g = sampler_layer_new_from_section(m, prg, prg->global->default_child, swhere); if (!g) @@ -426,7 +440,7 @@ struct sampler_program *sampler_program_new_from_cfg(struct sampler_module *m, c struct sampler_layer *l = sampler_layer_new_from_section(m, prg, g, where); if (!l) g_warning("Sample layer '%s' cannot be created - skipping", layer_section); - else + else { sampler_layer_update(l); if (!l->data.computed.eff_waveform) @@ -451,11 +465,11 @@ struct sampler_program *sampler_program_new_from_cfg(struct sampler_module *m, c if (!layer_section) break; where = g_strdup_printf("slayer:%s", layer_section); - + struct sampler_layer *l = sampler_layer_new_from_section(m, prg, NULL, where); if (!l) g_warning("Sample layer '%s' cannot be created - skipping", layer_section); - else + else { sampler_layer_update(l); if (!l->data.computed.eff_waveform) @@ -469,7 +483,7 @@ struct sampler_program *sampler_program_new_from_cfg(struct sampler_module *m, c g_free(where); } prg->all_layers = g_slist_reverse(prg->all_layers); - sampler_program_update_layers(prg); + sampler_program_update_layers(prg); return prg; } @@ -506,6 +520,21 @@ static void sampler_ctrl_label_destroy(gpointer value) free(label); } +void sampler_program_add_pitch_label(struct sampler_program *prg, uint16_t pitch, gchar *text) +{ + struct sampler_pitchlabel *label = calloc(1, sizeof(struct sampler_pitchlabel)); + label->pitch = pitch; + label->label = text; + prg->pitch_label_list = g_slist_append(prg->pitch_label_list, label); +} + +static void sampler_pitch_label_destroy(gpointer value) +{ + struct sampler_pitchlabel *label = value; + free(label->label); + free(label); +} + void sampler_program_add_controller_label(struct sampler_program *prg, uint16_t controller, gchar *text) { struct sampler_ctrllabel *label = calloc(1, sizeof(struct sampler_ctrllabel)); @@ -576,6 +605,7 @@ void sampler_program_destroyfunc(struct cbox_objhdr *hdr_ptr) g_slist_free(prg->all_layers); g_slist_free(prg->ctrl_init_list); g_slist_free_full(prg->ctrl_label_list, sampler_ctrl_label_destroy); + g_slist_free_full(prg->pitch_label_list, sampler_pitch_label_destroy); if (prg->tarfile) cbox_tarpool_release_tarfile(app.tarpool, prg->tarfile); free(prg); @@ -605,7 +635,6 @@ struct sampler_program *sampler_program_clone(struct sampler_program *prg, struc sampler_program_update_layers(newprg); if (newprg->tarfile) newprg->tarfile->refs++; - + return newprg; } - diff --git a/template/calfbox/sampler_prg.h b/template/calfbox/sampler_prg.h index 3fb2c64..630e447 100644 --- a/template/calfbox/sampler_prg.h +++ b/template/calfbox/sampler_prg.h @@ -78,6 +78,11 @@ struct sampler_ctrllabel { gchar *label; }; +struct sampler_pitchlabel { + uint16_t pitch; + gchar *label; +}; + struct sampler_program { CBOX_OBJECT_HEADER() @@ -90,6 +95,7 @@ struct sampler_program GSList *all_layers; GSList *ctrl_init_list; GSList *ctrl_label_list; + GSList *pitch_label_list; struct sampler_rll *rll; gchar *sample_dir; // can be empty, cannot be NULL gchar *source_file; // can be empty, cannot be NULL @@ -113,6 +119,7 @@ extern void sampler_program_delete_layer(struct sampler_program *prg, struct sam extern void sampler_program_add_group(struct sampler_program *prg, struct sampler_layer *l); extern void sampler_program_add_controller_init(struct sampler_program *prg, uint16_t controller, uint8_t value); extern void sampler_program_add_controller_label(struct sampler_program *prg, uint16_t controller, gchar *label); // keeps ownership +extern void sampler_program_add_pitch_label(struct sampler_program *prg, uint16_t pitch, gchar *label); // keeps ownership extern void sampler_program_remove_controller_init(struct sampler_program *prg, uint16_t controller, int which); extern void sampler_program_update_layers(struct sampler_program *prg); extern struct sampler_program *sampler_program_clone(struct sampler_program *prg, struct sampler_module *m, int prog_no, GError **error); diff --git a/template/calfbox/sfzloader.c b/template/calfbox/sfzloader.c index 0375c77..918d52f 100644 --- a/template/calfbox/sfzloader.c +++ b/template/calfbox/sfzloader.c @@ -192,6 +192,11 @@ static gboolean load_sfz_key_value(struct sfz_parser_client *client, const char int ctrl = atoi(key + 8); sampler_program_add_controller_label(ls->program, ctrl, g_strdup(value)); } + else if (!strncmp(key, "label_key", 8)) + { + int pitch = atoi(key + 8); + sampler_program_add_pitch_label(ls->program, pitch, g_strdup(value)); + } else if (!strncmp(key, "set_cc", 6)) { int ctrl = atoi(key + 6); @@ -291,4 +296,3 @@ gboolean sampler_module_load_program_sfz(struct sampler_module *m, struct sample sampler_program_update_layers(prg); return TRUE; } -