diff --git a/effects.c b/effects.c index 57ed58c..9388322 100644 --- a/effects.c +++ b/effects.c @@ -3382,12 +3382,12 @@ static Modifier modifiers[] = { {"EQ Bass", EQ_BASS, EQ_A_POSITION, &values_eq_db}, {"EQ Mid", EQ_MID, EQ_A_POSITION, &values_eq_db}, {"EQ Treb", EQ_TREB, EQ_A_POSITION, &values_eq_db}, - {"EQ Treb", EQ_PRESENCE, EQ_A_POSITION, &values_eq_db}, + {"EQ Presence", EQ_PRESENCE, EQ_A_POSITION, &values_eq_db}, {"EQ B Enable", EQ_ENABLE, EQ_B_POSITION, &values_on_off}, {"EQ B Bass", EQ_BASS, EQ_B_POSITION, &values_eq_db}, {"EQ B Mid", EQ_MID, EQ_B_POSITION, &values_eq_db}, {"EQ B Treb", EQ_TREB, EQ_B_POSITION, &values_eq_db}, - {"EQ B Treb", EQ_PRESENCE, EQ_B_POSITION, &values_eq_db}, + {"EQ B Presence", EQ_PRESENCE, EQ_B_POSITION, &values_eq_db}, {"Gate Enable", NOISEGATE_ON_OFF, NOISEGATE_POSITION, &values_on_off}, {"Gate Pluck Sens", NOISEGATE_SWELL_SENS, NOISEGATE_POSITION, &values_0_to_99}, {"Gate Threshold", NOISEGATE_GATE_TRESHOLD, NOISEGATE_POSITION, &values_0_to_99}, @@ -3729,6 +3729,11 @@ static XmlLabel xml_waveform_labels[] = { {CHORUS_WAVEFORM_SQUARE, "Square"}, }; +static XmlLabel xml_chorus_vibrato_labels[] = { + {0, "Chorus"}, + {1, "Vibrato"}, +}; + static XmlLabel xml_whammy_amount_labels[] = { {WHAMMY_TYPE_OCT_UP, "OctUp"}, {WHAMMY_TYPE_2OCT_UP, "2OctUp"}, @@ -4029,78 +4034,122 @@ XmlSettings xml_settings[] = { {NOISEGATE_RELEASE, NOISEGATE_POSITION, "Gate Release", &values_0_to_99,}, {NOISEGATE_ATTN, NOISEGATE_POSITION, "Gate Attenuation", &values_0_to_99,}, - {MOD_PRE_POST, CHORUSFX_POSITION, "Mod Pre/Post", &values_pre_post, xml_chorus_pre_post_labels, G_N_ELEMENTS(xml_chorus_pre_post_labels)}, {CHORUSFX_ON_OFF, CHORUSFX_POSITION, "Chorus/FX Enable", &values_on_off, xml_on_off_labels, G_N_ELEMENTS(xml_on_off_labels)}, {CHORUSFX_PRE_POST, CHORUSFX_POSITION, "Mod Pre/Post", &values_pre_post, xml_chorus_pre_post_labels, G_N_ELEMENTS(xml_chorus_pre_post_labels)}, {CHORUSFX_TYPE, CHORUSFX_POSITION, "Mod Type", &values_mod_type, xml_chorusfx_labels, G_N_ELEMENTS(xml_chorusfx_labels)}, + {PHASER_SPEED, CHORUSFX_POSITION, "Phaser Speed", &values_0_to_99,}, {PHASER_DEPTH, CHORUSFX_POSITION, "Phaser Depth", &values_0_to_99,}, {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,}, + {EH_PHASER_RATE, CHORUSFX_POSITION, "Phaser Rate", &values_0_to_99,}, {EH_PHASER_COLOR, CHORUSFX_POSITION, "Phaser xml Color", &values_on_off, xml_on_off_labels,G_N_ELEMENTS(xml_on_off_labels)}, + {MX_PHASER_INTENSITY, CHORUSFX_POSITION, "Intensity", &values_1_to_4,}, + + {TRIG_PHASER_SPEED, CHORUSFX_POSITION, "Trig Phaser Speed", &values_0_to_99,}, + {TRIG_PHASER_SENS, CHORUSFX_POSITION, "Trig Phaser Sens", &values_0_to_99,}, + {TRIG_PHASER_LFO_START, CHORUSFX_POSITION, "Trig Phaser LFO", &values_0_to_99,}, + {TRIG_PHASER_LEVEL, CHORUSFX_POSITION, "Trig Phaser Level", &values_0_to_99,}, + {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,}, + {CHORUS_WIDTH, CHORUSFX_POSITION, "Chorus Width", &values_0_to_99,}, + {CHORUS_INTENSITY, CHORUSFX_POSITION, "Chorus Intensity", &values_0_to_99,}, {CHORUS_WAVE, CHORUSFX_POSITION, "Chorus Waveform", &values_waveform, xml_waveform_labels, G_N_ELEMENTS(xml_waveform_labels)}, + {FLANGER_SPEED, CHORUSFX_POSITION, "Flanger Speed", &values_0_to_99,}, {FLANGER_DEPTH, CHORUSFX_POSITION, "Flanger Depth", &values_0_to_99,}, {FLANGER_REGEN, CHORUSFX_POSITION, "Flanger Regen", &values_0_to_99,}, {FLANGER_WAVE, CHORUSFX_POSITION, "Flanger Waveform", &values_waveform, xml_waveform_labels, G_N_ELEMENTS(xml_waveform_labels)}, {FLANGER_LEVEL, CHORUSFX_POSITION, "Flanger Level", &values_0_to_99,}, + + {TRIG_FLANGER_SPEED, CHORUSFX_POSITION, "Trig Flanger Speed", &values_0_to_99,}, + {TRIG_FLANGER_SENS, CHORUSFX_POSITION, "Trig Flanger Sens", &values_0_to_99,}, + {TRIG_FLANGER_LFO_START, CHORUSFX_POSITION, "Trig Flanger LFO Start", &values_0_to_99,}, + {TRIG_FLANGER_LEVEL, CHORUSFX_POSITION, "Trig Flanger Level", &values_0_to_99,}, + + {EH_FLANGER_RATE, CHORUSFX_POSITION, "EH Flanger Rate", &values_0_to_99,}, + {EH_FLANGER_RANGE, CHORUSFX_POSITION, "EH Flanger Range", &values_0_to_99,}, + {EH_FLANGER_COLOR, CHORUSFX_POSITION, "EH Flanger Color", &values_0_to_99,}, + {MXR_FLANGER_WIDTH, CHORUSFX_POSITION, "Flanger Width", &values_0_to_99,}, {MXR_FLANGER_MANUAL, CHORUSFX_POSITION, "Flanger Manual", &values_0_to_99,}, + {VIBRATO_SPEED, CHORUSFX_POSITION, "Vibrato Speed", &values_0_to_99,}, {VIBRATO_DEPTH, CHORUSFX_POSITION, "Vibrato Depth", &values_0_to_99,}, + {ROTARY_SPEED, CHORUSFX_POSITION, "Rotary Speed", &values_0_to_99,}, {ROTARY_INTENSITY, CHORUSFX_POSITION, "Rotary Intensity", &values_0_to_99,}, {ROTARY_DOPPLER, CHORUSFX_POSITION, "Rotary Doppler", &values_0_to_99,}, {ROTARY_CROSSOVER, CHORUSFX_POSITION, "Rotary Crossover", &values_0_to_99,}, + {VIBROPAN_SPEED, CHORUSFX_POSITION, "VibroPan Speed", &values_0_to_99,}, {VIBROPAN_DEPTH, CHORUSFX_POSITION, "VibroPan Depth", &values_0_to_99,}, {VIBROPAN_VIBRA, CHORUSFX_POSITION, "VibroPan VibratoPan", &values_0_to_99,}, {VIBROPAN_WAVE, CHORUSFX_POSITION, "VibroPan Waveform", &values_waveform, xml_waveform_labels, G_N_ELEMENTS(xml_waveform_labels)}, + + {UNOVIBE_PEDAL_SPEED, CHORUSFX_POSITION, "Unovibe Speed", &values_0_to_99,}, + {UNOVIBE_INTENSITY, CHORUSFX_POSITION, "Unovibe Intensity", &values_0_to_99,}, + {UNOVIBE_VOLUME, CHORUSFX_POSITION, "Unovibe Volume", &values_0_to_99,}, + {UNOVIBE_CHORUS_VIBRATO, CHORUSFX_POSITION, "Unovibe Chorus/Vibrato", &values_chorus_vibrato, &xml_chorus_vibrato_labels, G_N_ELEMENTS(xml_chorus_vibrato_labels)}, + {TREMOLO_SPEED, CHORUSFX_POSITION, "Tremolo Speed", &values_0_to_99,}, {TREMOLO_DEPTH, CHORUSFX_POSITION, "Tremolo Depth", &values_0_to_99,}, {TREMOLO_WAVE, CHORUSFX_POSITION, "Tremolo Waveform", &values_waveform, xml_waveform_labels, G_N_ELEMENTS(xml_waveform_labels)}, + {PANNER_SPEED, CHORUSFX_POSITION, "Panner Speed", &values_0_to_99,}, {PANNER_DEPTH, CHORUSFX_POSITION, "Panner Depth", &values_0_to_99,}, {PANNER_WAVE, CHORUSFX_POSITION, "Panner Waveform", &values_waveform, xml_waveform_labels, G_N_ELEMENTS(xml_waveform_labels)}, + {ENVELOPE_SENSITIVITY, CHORUSFX_POSITION, "Envelope Sens.", &values_0_to_99,}, {ENVELOPE_RANGE, CHORUSFX_POSITION, "Envelope Range", &values_0_to_99,}, + {ENVELOPE_BLEND, CHORUSFX_POSITION, "Envelope Blend", &values_0_to_99,}, + {AUTOYA_SPEED, CHORUSFX_POSITION, "AutoYa Speed", &values_0_to_99,}, {AUTOYA_INTENSITY, CHORUSFX_POSITION, "AutoYa Intensity", &values_0_to_99,}, {AUTOYA_RANGE, CHORUSFX_POSITION, "AutoYa Range", &values_0_to_49,}, + {YAYA_PEDAL, CHORUSFX_POSITION, "YaYa Pedal", &values_0_to_99,}, {YAYA_INTENSITY, CHORUSFX_POSITION, "YaYa Intensity", &values_0_to_99,}, {YAYA_RANGE, CHORUSFX_POSITION, "YaYa Range", &values_0_to_49,}, + {STEP_FILTER_SPEED, CHORUSFX_POSITION, "Step Filter Speed", &values_0_to_99,}, {STEP_FILTER_INTENSITY, CHORUSFX_POSITION, "Step Filter Intensity", &values_0_to_99,}, + {WHAMMY_AMOUNT, CHORUSFX_POSITION, "Whammy Amount", &values_whammy_amount, xml_whammy_amount_labels, G_N_ELEMENTS(xml_whammy_amount_labels)}, {WHAMMY_PEDAL, CHORUSFX_POSITION, "Whammy Pedal", &values_0_to_99,}, {WHAMMY_MIX, CHORUSFX_POSITION, "Whammy Mix", &values_0_to_99,}, - {CHORUSFX_PRE_POST, CHORUSFX_POSITION, "Mod Pre/Post", &values_pre_post, xml_chorus_pre_post_labels, G_N_ELEMENTS(xml_chorus_pre_post_labels)}, {PITCH_AMOUNT, CHORUSFX_POSITION, "Pitch Shift Amount", &values_m24_to_24,}, {PITCH_MIX, CHORUSFX_POSITION, "Pitch Shift Mix", &values_0_to_99,}, + {DETUNE_AMOUNT, CHORUSFX_POSITION, "Detune Amount", &values_m24_to_24,}, {DETUNE_LEVEL, CHORUSFX_POSITION, "Detune Level", &values_0_to_99,}, + {IPS_SHIFT_AMOUNT, CHORUSFX_POSITION, "IPS Amount", &values_ips_shift, xml_ips_shift_labels, G_N_ELEMENTS(xml_ips_shift_labels)}, {IPS_KEY, CHORUSFX_POSITION, "IPS Key", &values_ips_key, xml_ips_key_labels, G_N_ELEMENTS(xml_ips_key_labels)}, {IPS_SCALE, CHORUSFX_POSITION, "IPS Scale", &values_ips_scale, xml_ips_scale_labels, G_N_ELEMENTS(xml_ips_scale_labels)}, {IPS_LEVEL, CHORUSFX_POSITION, "IPS Level", &values_0_to_99,}, + {SYNTH_TALK_ATTACK, CHORUSFX_POSITION, "Synth Talk Attack", &values_0_to_99,}, - {GNX3K_SYNTH_TALK_RELEASE, CHORUSFX_POSITION, "Synth Talk Release", &values_0_to_99,}, {SYNTH_TALK_RELEASE, CHORUSFX_POSITION, "Synth Talk Release", &values_0_to_99,}, {SYNTH_TALK_SENS, CHORUSFX_POSITION, "Synth Talk Sens", &values_0_to_99,}, {SYNTH_TALK_VOX, CHORUSFX_POSITION, "Synth Talk Vox", &values_0_to_99,}, {SYNTH_TALK_BALANCE, CHORUSFX_POSITION, "Synth Talk Balance", &values_0_to_99,}, + {GNX3K_SYNTH_TALK_RELEASE, CHORUSFX_POSITION, "Synth Talk Release", &values_0_to_99,}, + + {OCTAVER_OCTAVE1 , CHORUSFX_POSITION, "Octaver Octave 1", &values_0_to_99}, + {OCTAVER_OCTAVE2 , CHORUSFX_POSITION, "Octaver Octave 2", &values_0_to_99}, + {OCTAVER_DRY_LEVEL, CHORUSFX_POSITION, "Octaver Dry Level", &values_0_to_99}, + {DELAY_TYPE, DELAY_POSITION, "Delay Type", &values_delay_type, xml_delay_labels, G_N_ELEMENTS(xml_delay_labels)}, {DELAY_ON_OFF, DELAY_POSITION, "Delay Enable", &values_on_off, xml_on_off_labels, G_N_ELEMENTS(xml_on_off_labels)}, {DELAY_TIME, DELAY_POSITION, "Delay Time", &values_delay_time,}, @@ -4337,6 +4386,8 @@ static void modifier_group_free(ModifierGroup *modifier_group) int x; for (x=0; xgroup_amt; x++) { if (modifier_group->group[x].settings) + /* The settings for the EXP_POSITION are dynamically allocated. */ + modifier_settings_exp_free(modifier_group->group[x].settings); effect_settings_free(modifier_group->group[x].settings); } g_slice_free1(modifier_group->group_amt * sizeof(EffectGroup), diff --git a/gui.c b/gui.c index 309ad5d..3ee1205 100644 --- a/gui.c +++ b/gui.c @@ -443,6 +443,56 @@ gboolean apply_current_preset_to_gui(gpointer data) return FALSE; } +/** + * Free the data associated with the dynamically allocated settings + * for the EXP_POSITION. + */ +void modifier_settings_exp_free(EffectSettings *settings) +{ + guint i; + guint id = settings->id; + guint pos = settings->position; + gpointer key; + GList *link, *next, *orig_list; + WidgetTreeElem *el; + GObject *widget; + + for (i = 0; i < 2; i++) { + + id = settings[i].id; + pos = settings[i].position; + key = GINT_TO_POINTER(pos <<16| id); + orig_list = g_tree_lookup(widget_tree, key); + if (!orig_list) { + continue; + } + + link = g_list_first(orig_list); + while (link != NULL) { + next = link->next; + + el = link->data; + if (el) { + + widget = el->widget; + if (g_object_get_data(G_OBJECT(widget), "exp")) { + g_slice_free(WidgetTreeElem, el); + link->data = NULL; + } + } + link = next; + } + + /* Remove all the list elements from which we freed data. */ + orig_list = g_list_remove_all(orig_list, NULL); + + /* The list should be empty at this point. */ + g_assert(!orig_list); + + /* Removed them all, so remove the key from the tree.*/ + g_tree_steal(widget_tree, key); + } +} /** * \param settings effect parameters * \param amt amount of effect parameters @@ -492,6 +542,12 @@ GtkWidget *create_grid(EffectSettings *settings, gint amt, GHashTable *widget_ta widget_tree_add(G_OBJECT(adj), settings[x].id, settings[x].position, -1, -1); + + if (settings[x].position == EXP_POSITION) { + /* Tag the adj so we can free it when we free the modifier group. */ + g_object_set_data(G_OBJECT(adj), "exp", GINT_TO_POINTER(1)); + } + gtk_grid_attach(GTK_GRID(grid), label, 0, x, 1, 1); gtk_grid_attach(GTK_GRID(grid), knob, 1, x, 1, 1); gtk_grid_attach(GTK_GRID(grid), widget, 2, x, 1, 1); @@ -696,7 +752,6 @@ static void update_modifier_vbox(GtkWidget *vbox, GObject *combo_box, gint id, g guint amt = get_modifier_amt(); GtkWidget *child = NULL; GHashTable *widget_table; - guint needs_settings = (position == EXP_POSITION); widget_table = g_hash_table_new(g_direct_hash, g_direct_equal); @@ -709,8 +764,8 @@ static void update_modifier_vbox(GtkWidget *vbox, GObject *combo_box, gint id, g settings->type = group[x].type; settings->position = position; - if (needs_settings) { - /* EXP_ASSIGN has unique settings per combo box entry. */ + if (position == EXP_POSITION) { + child = g_object_steal_data(G_OBJECT(combo_box), "active_child"); child = create_grid(group[x].settings, group[x].settings_amt, widget_table); g_object_ref_sink(child); @@ -733,33 +788,41 @@ static void update_modifier_vbox(GtkWidget *vbox, GObject *combo_box, gint id, g return; } -static void widget_tree_elem_free(GList *); - static void clean_modifier_combo_box(GObject *combo_box, GList *list) { EffectSettingsGroup *settings = NULL; WidgetTreeElem *el; gchar *name; - GList *link, *next; + GList *link, *next, *stale_link; link = g_list_first(list); while (link != NULL) { next = link->next; el = link->data; + stale_link = NULL; + + /* We need to clean the data associated with a combo box. + * This may include the per-entry settings widgets. + */ if (el->value != -1) { + /* This is a combo box entry. Remove the associated data. */ + stale_link = link; link = g_list_remove_link(list, link); - g_assert(combo_box == el->widget); name = g_strdup_printf("SettingsGroup%d", el->x); settings = g_object_steal_data(G_OBJECT(combo_box), name); - - if (settings) { - effect_settings_group_free(settings); + if (settings && settings->child) { + gtk_widget_destroy(settings->child); } + + g_slice_free(EffectSettingsGroup, settings); g_free(name); g_slice_free(WidgetTreeElem, el); - g_list_free_1(link); + } + + if (stale_link) { + g_list_free_1(stale_link); } link = next; diff --git a/gui.h b/gui.h index 1c9297d..838a265 100644 --- a/gui.h +++ b/gui.h @@ -31,5 +31,6 @@ gboolean unsupported_device_dialog(Device **device); gint select_device_dialog (GList *devices); const gchar* get_message_name(MessageID msgid); void create_modifier_group (guint pos, guint id); +void modifier_settings_exp_free(EffectSettings *settings); #endif /* GDIGI_GUI_H */