diff --git a/effects.c b/effects.c index e54b617..c93a0da 100644 --- a/effects.c +++ b/effects.c @@ -1579,6 +1579,11 @@ static EffectSettings gnx3k_reverb_settings[] = { {"Level", REVERB_LEVEL, REVERB_POSITION, &values_0_to_99}, }; +static EffectSettings pedal1_assign_settings[] = { + {"Pedal Min 1", EXP_MIN, EXP_POSITION, &values_0_to_99,}, + {"Pedal Max 1", EXP_MAX, EXP_POSITION, &values_0_to_99,}, +}; + static EffectSettings lfo1_settings[] = { {"Heel", LFO_MIN, LFO1_POSITION, &values_0_to_99}, {"Toe", LFO_MAX, LFO1_POSITION, &values_0_to_99}, @@ -1953,16 +1958,19 @@ static EffectGroup rp355_chorusfx_group[] = { }; static EffectGroup rp355_pedal1_assign_group[] = { - { 0, "Placeholder", NULL, 0}, - }; + { 0, NULL, pedal1_assign_settings, G_N_ELEMENTS(pedal1_assign_settings)}, + { 0, "None", NULL, 0}, +}; static EffectGroup rp355_lfo2_group[] = { - { 0, "Placeholder", lfo2_settings, G_N_ELEMENTS(lfo2_settings)}, + { 0, NULL, lfo2_settings, G_N_ELEMENTS(lfo2_settings)}, + { 0, "None", NULL, 0}, }; static EffectGroup rp355_lfo1_group[] = { - { 0, "Placeholder", lfo1_settings, G_N_ELEMENTS(lfo1_settings)}, - }; + { 0, NULL, lfo1_settings, G_N_ELEMENTS(lfo1_settings)}, + { 0, "None", NULL, 0}, +}; static EffectGroup rp500_chorusfx_group[] = { {CHORUS_TYPE_CE, "CE Chorus", chorusfx_ce_settings, G_N_ELEMENTS(chorusfx_ce_settings)}, @@ -3362,6 +3370,11 @@ static Modifier modifiers[] = { {"Phaser Regen", PHASER_REGEN, CHORUSFX_POSITION, &values_0_to_99}, {"Phaser Waveform", PHASER_WAVE, CHORUSFX_POSITION, &values_waveform}, {"Phaser Level", PHASER_LEVEL, CHORUSFX_POSITION, &values_0_to_99}, + {"Phaser Intensity", MX_PHASER_INTENSITY, CHORUSFX_POSITION, &values_0_to_99}, + {"Trig Phaser Speed", TRIG_PHASER_SPEED, CHORUSFX_POSITION, &values_0_to_99}, + {"Trig Phaser Sens", TRIG_PHASER_SENS, CHORUSFX_POSITION, &values_0_to_99}, + {"Trig Phaser LFO", TRIG_PHASER_LFO_START, CHORUSFX_POSITION, &values_0_to_99}, + {"Trig Phaser Level", TRIG_PHASER_LEVEL, CHORUSFX_POSITION, &values_0_to_99}, {"Chorus Speed", CHORUS_SPEED, CHORUSFX_POSITION, &values_0_to_99}, {"Chorus Depth", CHORUS_DEPTH, CHORUSFX_POSITION, &values_0_to_99}, {"Chorus Level", CHORUS_LEVEL, CHORUSFX_POSITION, &values_0_to_99}, @@ -3972,6 +3985,7 @@ XmlSettings xml_settings[] = { {PHASER_REGEN, CHORUSFX_POSITION, "Phaser Regen", &values_0_to_99,}, {PHASER_WAVE, CHORUSFX_POSITION, "Phaser Waveform", &values_waveform, xml_waveform_labels, G_N_ELEMENTS(xml_waveform_labels)}, {PHASER_LEVEL, CHORUSFX_POSITION, "Phaser Level", &values_0_to_99,}, + {MX_PHASER_INTENSITY, CHORUSFX_POSITION, "Intensity", &values_1_to_4,}, {CHORUS_SPEED, CHORUSFX_POSITION, "Chorus Speed", &values_0_to_99,}, {CHORUS_DEPTH, CHORUSFX_POSITION, "Chorus Depth", &values_0_to_99,}, {CHORUS_LEVEL, CHORUSFX_POSITION, "Chorus Level", &values_0_to_99,}, diff --git a/gdigi.c b/gdigi.c index dc1ff24..77ac66d 100644 --- a/gdigi.c +++ b/gdigi.c @@ -462,6 +462,8 @@ void push_message (GString *msg) str[9], str[10], str[11], str[12]); } + break; + case NOTIFY_MODIFIER_GROUP_CHANGED: { int i; @@ -472,10 +474,18 @@ void push_message (GString *msg) } printf("\n"); } + debug_msg(DEBUG_MSG2HOST, "NOTIFY_MODIFIER_GROUP_CHANGED: Modifier group " "id %d changed", (str[9] << 8) | (str[10])); + + if (ModifierLinkableList) { + modifier_group_free(ModifierLinkableList); + ModifierLinkableList = NULL; + } + + send_message(REQUEST_MODIFIER_LINKABLE_LIST, "\x00\x01", 2); break; } default: @@ -526,9 +536,14 @@ void push_message (GString *msg) g_string_free(msg, TRUE); + GDK_THREADS_ENTER(); + create_modifier_group(EXP_POSITION, EXP_ASSIGN1); create_modifier_group(LFO1_POSITION, LFO_TYPE); create_modifier_group(LFO2_POSITION, LFO_TYPE); + + GDK_THREADS_LEAVE(); + return; @@ -1130,6 +1145,7 @@ GList *get_message_list(MessageID id) g_error("get_message_list() doesn't support followning id: %d", id); g_string_free(data, TRUE); g_list_free(list); + g_assert(!"BUG"); return NULL; } @@ -1420,6 +1436,7 @@ static gint get_digitech_devices(GList **devices) number++; *devices = g_list_append(*devices, GINT_TO_POINTER(card_num)); } + free(name); snd_card_next(&card_num); } @@ -1485,6 +1502,7 @@ int main(int argc, char *argv[]) { } if (device != NULL) { + /* enable GUI mode */ set_option(GUI_MODE_ON_OFF, USB_POSITION, 1); diff --git a/gui.c b/gui.c index a508599..a829942 100644 --- a/gui.c +++ b/gui.c @@ -563,6 +563,7 @@ void combo_box_changed_cb(GtkComboBox *widget, gpointer data) EffectSettingsGroup *settings = NULL; gchar *name = NULL; gint x; + g_object_get(G_OBJECT(widget), "active", &x, NULL); vbox = g_object_get_data(G_OBJECT(widget), "vbox"); @@ -625,15 +626,22 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt, gint id, gint p g_signal_connect(G_OBJECT(combo_box), "changed", G_CALLBACK(combo_box_changed_cb), group); g_object_set_data(G_OBJECT(combo_box), "vbox", vbox); } - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo_box), - NULL, group[x].label); + + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), group[x].label); cmbox_no++; if ((group[x].settings != NULL) && (group[x].settings_amt > 0)) { - widget = create_grid(group[x].settings, group[x].settings_amt, widget_table); + /* + * Create a grid for each combo box entry to contain per + * combo box entry settings. + */ + widget = create_grid(group[x].settings, + group[x].settings_amt, + widget_table); g_object_ref_sink(widget); - } else + } else { widget = NULL; + } settings = g_slice_new(EffectSettingsGroup); settings->id = id; @@ -644,11 +652,15 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt, gint id, gint p widget_tree_add(G_OBJECT(combo_box), id, position, group[x].type, x); name = g_strdup_printf("SettingsGroup%d", cmbox_no); - g_object_set_data_full(G_OBJECT(combo_box), name, settings, ((GDestroyNotify)effect_settings_group_free)); + g_object_set_data_full(G_OBJECT(combo_box), + name, settings, + ((GDestroyNotify)effect_settings_group_free)); g_free(name); } else { if ((group[x].settings != NULL) && (group[x].settings_amt > 0)) { - widget = create_grid(group[x].settings, group[x].settings_amt, widget_table); + widget = create_grid(group[x].settings, + group[x].settings_amt, + widget_table); gtk_box_pack_end(GTK_BOX(vbox), widget, FALSE, TRUE, 0); } } @@ -660,7 +672,67 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt, gint id, gint p } /** - * Given a linkable effect, build the combo box for the linkable parameters. + * Populate a combo box with text entries from the modifier group. + */ +void update_modifier_combo_box(GObject *combo_box, EffectGroup *group, gint amt, gint id, gint position) +{ + gint x; + EffectSettingsGroup *settings = NULL; + + for (x = 0; xid = id; + settings->type = group[x].type; + settings->position = position; + settings->child = NULL; + + name = g_strdup_printf("SettingsGroup%d", x); + g_object_set_data(G_OBJECT(combo_box), name, settings); + g_free(name); + + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), group[x].label); + widget_tree_add(combo_box, id, position, group[x].type, x); + } + + return; +} + +static void widget_tree_elem_free(GList *); + +static void clean_modifier_combo_box (GObject *ComboBox, GList *list) +{ + EffectSettingsGroup *settings = NULL; + WidgetTreeElem *el; + gchar *name; + GList *link, *next; + + link = g_list_first(list); + + while (link != NULL) { + next = link->next; + el = link->data; + if (el->value != -1) { + /* Useless assignment, but silences compiler warning. */ + link = g_list_remove_link(list, link); + + g_assert(ComboBox == el->widget); + name = g_strdup_printf("SettingsGroup%d", el->x); + settings = g_object_steal_data(G_OBJECT(ComboBox), name); + + g_free(name); + g_slice_free(EffectSettingsGroup, settings); + g_slice_free(WidgetTreeElem, el); + } + link = next; + } + gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(ComboBox)); +} + +/** + * Given a linkable effect, update the combo box for the linkable parameters. * * @param[in] pos Position * @param[in] id Id @@ -668,27 +740,30 @@ GtkWidget *create_widget_container(EffectGroup *group, gint amt, gint id, gint p void create_modifier_group (guint pos, guint id) { - guint i; + + GtkWidget *vbox; gpointer key; WidgetTreeElem *el; GList *list; - EffectSettingsGroup *settings = NULL, *orig_settings = NULL; GObject *AssignComboBox; - GtkWidget *child_widget = NULL; - gchar *name = NULL; debug_msg(DEBUG_GROUP, "Building modifier group for position %d id %d \"%s\"", pos, id, get_xml_settings(id, pos)->label); key = GINT_TO_POINTER((pos << 16) | id); list = g_tree_lookup(widget_tree, key); + + /* + * The list will be destroyed and recreated, but we don't want to + * handle the teardown ourselves. So steal it from the tree. + */ + g_tree_steal(widget_tree, key); if (!list) { g_warning("No widget tree entry for position %d id %d!\n", pos, id); return; } - /* The only element should be the one with the placeholder. */ el = g_list_nth_data(list, 0); if (!el) { g_warning("No effect settings group for position %d id %d!\n", @@ -697,46 +772,18 @@ create_modifier_group (guint pos, guint id) } AssignComboBox = el->widget; + g_assert(AssignComboBox != NULL); - name = g_strdup_printf("SettingsGroup%d", 0); - orig_settings = g_object_get_data(G_OBJECT(AssignComboBox), name); - if (orig_settings) { - child_widget = orig_settings->child; - /* Steal the data so we don't trigger the destroy method on the grid. */ - g_object_steal_data(AssignComboBox, name); - } - /* Remove the placeholder. */ - gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(AssignComboBox), 0); + vbox = g_object_get_data(AssignComboBox, "vbox"); + g_assert(vbox != NULL); + clean_modifier_combo_box(AssignComboBox, list); - for (i = 0; i < ModifierLinkableList->group_amt; i++) { - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(AssignComboBox), - NULL, - ModifierLinkableList->group[i].label); + update_modifier_combo_box(AssignComboBox, + ModifierLinkableList->group, + ModifierLinkableList->group_amt, + id, pos); - settings = g_slice_new(EffectSettingsGroup); - settings->type = ModifierLinkableList->group[i].type; - settings->id = id; - settings->position = pos; - settings->child = NULL; - if (child_widget) { - settings->child = child_widget; - g_object_ref_sink(settings->child); - } - - name = g_strdup_printf("SettingsGroup%d", i); - - debug_msg(DEBUG_GROUP, "%d: \"%s\"", - i, - ModifierLinkableList->group[i].label); - - widget_tree_add(G_OBJECT(AssignComboBox), id, pos, - ModifierLinkableList->group[i].type, i); - g_object_set_data_full(G_OBJECT(AssignComboBox), name, settings, - ((GDestroyNotify)effect_settings_group_free)); - } - - // Get the current setting. get_option(id, pos); } @@ -769,6 +816,7 @@ GtkWidget *create_vbox(Effect *widgets, gint amt, gchar *label) for (x = 0; x