summaryrefslogtreecommitdiff
path: root/snd-genv.c
diff options
context:
space:
mode:
authorAlessio Treglia <quadrispro@ubuntu.com>2009-10-19 09:55:11 +0200
committerAlessio Treglia <quadrispro@ubuntu.com>2009-10-19 09:55:11 +0200
commit5cd66eecc95be11cacc5aaf4db8c67a499bb2d4d (patch)
treef9fe35437c9a69b886676bbdeff692ebc728bec2 /snd-genv.c
Imported Upstream version 11
Diffstat (limited to 'snd-genv.c')
-rw-r--r--snd-genv.c1396
1 files changed, 1396 insertions, 0 deletions
diff --git a/snd-genv.c b/snd-genv.c
new file mode 100644
index 0000000..37bd835
--- /dev/null
+++ b/snd-genv.c
@@ -0,0 +1,1396 @@
+#include "snd.h"
+
+/* envelope editor and viewer */
+
+
+static GtkWidget *enved_dialog = NULL;
+static GtkWidget *applyB, *apply2B, *cancelB, *drawer, *showB, *saveB, *resetB, *firB = NULL;
+static GtkWidget *revertB, *undoB, *redoB, *printB, *brktxtL, *brkpixL, *graphB, *fltB, *ampB, *srcB, *rbrow, *clipB, *deleteB;
+static GtkWidget *nameL, *textL, *dBB, *orderL;
+static GtkWidget *expB, *linB, *lerow, *baseScale, *baseLabel, *baseValue, *selectionB, *selrow, *revrow, *unrow, *saverow;
+static GtkObject *baseAdj, *orderAdj;
+static gc_t *gc, *rgc, *ggc, *hgc;
+static slist *env_list = NULL;
+
+static const char *env_names[3] = {N_("amp env:"), N_("flt env:"), N_("src env:")};
+
+static bool showing_all_envs = false; /* edit one env (0), or view all currently defined envs (1) */
+static bool apply_to_selection = false, we_turned_selection_off = false;
+
+static int env_window_width = 0;
+static int env_window_height = 0;
+
+static chan_info *active_channel = NULL, *last_active_channel = NULL;
+
+static env* selected_env = NULL; /* if during view, one env is clicked, it is "selected" and can be pasted elsewhere */
+static env* active_env = NULL; /* env currently being edited */
+
+static axis_info *axis = NULL;
+static axis_info *gray_ap = NULL;
+static bool FIR_p = true;
+static bool old_clip_p = false;
+static bool ignore_button_release = false;
+
+static axis_context *pix_ax = NULL;
+
+
+static void fixup_axis_context(axis_context *ax, GtkWidget *w, gc_t *gc)
+{
+ ax->wn = WIDGET_TO_WINDOW(w);
+ ax->w = w;
+ if (gc) ax->gc = gc;
+ ax->current_font = AXIS_NUMBERS_FONT(ss);
+}
+
+
+axis_info *enved_make_axis(const char *name, axis_context *ax,
+ int ex0, int ey0, int width, int height,
+ mus_float_t xmin, mus_float_t xmax, mus_float_t ymin, mus_float_t ymax,
+ printing_t printing)
+{
+ /* conjure up minimal context for axis drawer in snd-axis.c */
+ if (!axis)
+ {
+ axis = (axis_info *)calloc(1, sizeof(axis_info));
+ axis->ax = (axis_context *)calloc(1, sizeof(axis_context));
+ fixup_axis_context(axis->ax, drawer, ax->gc);
+ }
+ if (!gray_ap)
+ {
+ gray_ap = (axis_info *)calloc(1, sizeof(axis_info));
+ gray_ap->ax = (axis_context *)calloc(1, sizeof(axis_context));
+ gray_ap->graph_active = true;
+ fixup_axis_context(gray_ap->ax, drawer, ggc);
+ }
+#if USE_CAIRO
+ axis->ax->cr = gdk_cairo_create(WIDGET_TO_WINDOW(drawer));
+#endif
+ init_env_axes(axis, name, ex0, ey0, width, height, xmin, xmax, ymin, ymax, printing);
+#if USE_CAIRO
+ cairo_destroy(axis->ax->cr);
+#endif
+ return(axis);
+}
+
+
+static void display_env(env *e, const char *name, gc_t *cur_gc, int x0, int y0, int width, int height, bool dots, printing_t printing)
+{
+ axis_context *ax = NULL;
+ ax = (axis_context *)calloc(1, sizeof(axis_context));
+ ax->wn = WIDGET_TO_WINDOW(drawer);
+ ax->w = drawer;
+ ax->gc = cur_gc;
+#if USE_CAIRO
+ ax->cr = gdk_cairo_create(WIDGET_TO_WINDOW(drawer));
+#endif
+ ss->enved->with_dots = dots;
+ env_editor_display_env(ss->enved, e, ax, name, x0, y0, width, height, printing);
+#if USE_CAIRO
+ cairo_destroy(ax->cr);
+#endif
+ free(ax);
+}
+
+
+void display_enved_env_with_selection(env *e, const char *name, int x0, int y0, int width, int height, bool dots, printing_t printing)
+{
+ display_env(e, name, (selected_env == e) ? rgc : gc, x0, y0, width, height, dots, printing);
+}
+
+
+static void reflect_segment_state(void);
+
+static void prepare_env_edit(env *new_env)
+{
+ prepare_enved_edit(new_env);
+ if (new_env->base == 1.0)
+ set_enved_style(ENVELOPE_LINEAR);
+ else
+ {
+ set_enved_style(ENVELOPE_EXPONENTIAL);
+ set_enved_base(new_env->base);
+ }
+ reflect_segment_state();
+}
+
+
+void set_enved_redo_sensitive(bool val) {set_sensitive(redoB, val);}
+void set_enved_revert_sensitive(bool val) {set_sensitive(revertB, val);}
+void set_enved_undo_sensitive(bool val) {set_sensitive(undoB, val);}
+void set_enved_save_sensitive(bool val) {set_sensitive(saveB, val);}
+void set_enved_show_sensitive(bool val) {set_sensitive(showB, val);}
+
+
+void make_scrolled_env_list(void)
+{
+ int n, size;
+ size = enved_all_envs_top();
+ slist_clear(env_list);
+ for (n = 0; n < size; n++)
+ slist_append(env_list, enved_all_names(n));
+ gtk_widget_show(env_list->scroller);
+}
+
+
+void enved_reflect_peak_env_completion(snd_info *sp)
+{
+ if ((enved_dialog) && (active_channel) && (enved_wave_p(ss)))
+ {
+ if (active_channel->sound == sp)
+ env_redisplay();
+ }
+}
+
+
+void new_active_channel_alert(void)
+{
+ if (enved_dialog)
+ {
+ /* if showing current active channel in gray, update */
+ active_channel = current_channel();
+ env_redisplay();
+ }
+}
+
+
+static void dismiss_enved_callback(GtkWidget *w, gpointer context)
+{
+ gtk_widget_hide(enved_dialog);
+}
+
+
+static gint delete_enved_dialog(GtkWidget *w, GdkEvent *event, gpointer context)
+{
+ gtk_widget_hide(enved_dialog);
+ return(true);
+}
+
+
+static void help_enved_callback(GtkWidget *w, gpointer context)
+{
+ envelope_editor_dialog_help();
+}
+
+
+static void force_update(GtkWidget *wid)
+{
+ if ((wid) && (WIDGET_TO_WINDOW(wid)))
+ {
+ gdk_window_invalidate_rect(GDK_WINDOW(WIDGET_TO_WINDOW(wid)), NULL, true);
+ gdk_window_process_updates(GDK_WINDOW(WIDGET_TO_WINDOW(wid)), true);
+ }
+}
+
+
+static bool within_selection_src = false;
+
+static void apply_enved(void)
+{
+ char *origin = NULL, *estr = NULL;
+ if (active_env)
+ {
+ active_channel = current_channel();
+ if (active_channel)
+ {
+ set_sensitive(applyB, false);
+ set_sensitive(apply2B, false);
+ set_stock_button_label(cancelB, _("Stop"));
+ force_update(cancelB);
+ switch (enved_target(ss))
+ {
+ case ENVED_AMPLITUDE:
+#if HAVE_FORTH
+ origin = mus_format("%s%s %s drop",
+ estr = env_to_string(active_env),
+ (apply_to_selection) ? "" : " 0 " PROC_FALSE,
+ (apply_to_selection) ? S_env_selection : S_env_channel);
+#else
+ origin = mus_format("%s" PROC_OPEN "%s%s",
+ TO_PROC_NAME((apply_to_selection) ? S_env_selection : S_env_channel),
+ estr = env_to_string(active_env),
+ (apply_to_selection) ? "" : PROC_SEP "0" PROC_SEP PROC_FALSE);
+#endif
+ apply_env(active_channel, active_env, 0,
+ CURRENT_SAMPLES(active_channel),
+ apply_to_selection,
+ origin, NULL,
+ C_TO_XEN_INT(AT_CURRENT_EDIT_POSITION), 0);
+ /* calls update_graph, I think, but in short files that doesn't update the amp-env */
+ if (enved_wave_p(ss)) env_redisplay();
+ if (estr) free(estr);
+ if (origin) free(origin);
+ break;
+ case ENVED_SPECTRUM:
+#if HAVE_FORTH
+ origin = mus_format("%s %d%s %s drop",
+ estr = env_to_string(active_env),
+ enved_filter_order(ss),
+ (apply_to_selection) ? "" : " 0 " PROC_FALSE,
+ (apply_to_selection) ? S_filter_selection : S_filter_channel);
+#else
+ origin = mus_format("%s" PROC_OPEN "%s" PROC_SEP "%d%s",
+ TO_PROC_NAME((apply_to_selection) ? S_filter_selection : S_filter_channel),
+ estr = env_to_string(active_env),
+ enved_filter_order(ss),
+ (apply_to_selection) ? "" : PROC_SEP "0" PROC_SEP PROC_FALSE);
+#endif
+ apply_filter(active_channel,
+ (FIR_p) ? enved_filter_order(ss) : 0,
+ active_env,
+ origin, NULL,
+ apply_to_selection, NULL, NULL,
+ C_TO_XEN_INT(AT_CURRENT_EDIT_POSITION), 0, false);
+ if (estr) free(estr);
+ if (origin) free(origin);
+ break;
+ case ENVED_SRATE:
+ {
+ int i, j;
+ env *max_env = NULL;
+ max_env = copy_env(active_env);
+ for (i = 0, j = 1; i < max_env->pts; i++, j += 2)
+ if (max_env->data[j] < .01) max_env->data[j] = .01;
+ within_selection_src = true;
+ src_env_or_num(active_channel, max_env, 0.0,
+ false, "Enved: src", apply_to_selection, NULL,
+ C_TO_XEN_INT(AT_CURRENT_EDIT_POSITION), 0);
+ within_selection_src = false;
+ max_env = free_env(max_env);
+ if (enved_wave_p(ss)) env_redisplay();
+ }
+ break;
+ }
+ set_sensitive(applyB, true);
+ set_sensitive(apply2B, true);
+ set_stock_button_label(cancelB, _("Go Away"));
+ }
+ }
+}
+
+
+static void env_redisplay_1(printing_t printing)
+{
+ if (enved_dialog_is_active())
+ {
+ gdk_window_clear(WIDGET_TO_WINDOW(drawer));
+ if (showing_all_envs)
+ view_envs(env_window_width, env_window_height, printing);
+ else
+ {
+ char *name = NULL;
+ name = (char *)gtk_entry_get_text(GTK_ENTRY(textL));
+ if (!name) name = _("noname");
+ if (enved_wave_p(ss))
+ {
+#if USE_CAIRO
+ gray_ap->ax->cr = gdk_cairo_create(WIDGET_TO_WINDOW(drawer));
+#endif
+ if ((enved_target(ss) == ENVED_SPECTRUM) && (active_env) && (FIR_p) && (printing == NOT_PRINTING))
+ display_frequency_response(active_env, axis, gray_ap->ax, enved_filter_order(ss), enved_in_dB(ss));
+ enved_show_background_waveform(axis, gray_ap, apply_to_selection, (enved_target(ss) == ENVED_SPECTRUM), printing);
+#if USE_CAIRO
+ cairo_destroy(gray_ap->ax->cr);
+#endif
+ }
+ display_env(active_env, name, gc, 0, 0, env_window_width, env_window_height, true, printing);
+ name = NULL;
+ }
+ }
+}
+
+
+void env_redisplay(void) {env_redisplay_1(NOT_PRINTING);}
+
+void env_redisplay_with_print(void) {env_redisplay_1(PRINTING);}
+
+
+void update_enved_background_waveform(chan_info *cp)
+{
+ if ((enved_dialog_is_active()) &&
+ (enved_wave_p(ss)) &&
+ (enved_target(ss) == ENVED_AMPLITUDE) &&
+ (cp == active_channel) &&
+ ((!apply_to_selection) || (selection_is_active_in_channel(cp))))
+ env_redisplay();
+}
+
+
+
+static void enved_filter_order_callback(GtkWidget *w, gpointer data)
+{
+ set_enved_filter_order(gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(orderL)));
+}
+
+
+static void clear_point_label(void);
+
+static void clear_genv_error(void)
+{
+ if (brktxtL)
+ clear_point_label();
+}
+
+
+static gint unpost_genv_error(gpointer data)
+{
+ clear_genv_error();
+ return(0);
+}
+
+
+static void errors_to_genv_text(const char *msg, void *data)
+{
+ set_button_label(brktxtL, msg);
+ g_timeout_add_full(0, (guint32)5000, unpost_genv_error, NULL, NULL);
+}
+
+
+static void text_field_activated(GtkWidget *w, gpointer context)
+{ /* might be breakpoints to load or an envelope name (<cr> in enved text field) */
+ char *str = NULL;
+ str = (char *)gtk_entry_get_text(GTK_ENTRY(w));
+ if ((str) && (*str))
+ {
+ env *e = NULL;
+ while (isspace((int)(*str))) str++;
+ e = name_to_env(str);
+ if (!e)
+ {
+ if (isalpha((int)(str[0])))
+ {
+ alert_envelope_editor(str, copy_env(active_env));
+ add_or_edit_symbol(str, active_env);
+ set_sensitive(saveB, false);
+ env_redisplay(); /* updates label */
+ }
+ else
+ {
+ redirect_errors_to(errors_to_genv_text, NULL);
+ e = string_to_env(str);
+ redirect_errors_to(NULL, NULL);
+ }
+ }
+ if (e)
+ {
+ if (active_env)
+ {
+ #define ENVED_TEMP_NAME "enved-backup"
+ /* save current under a temp name! -- user might have mistakenly reused a name */
+ alert_envelope_editor((char *)ENVED_TEMP_NAME, copy_env(active_env));
+ add_or_edit_symbol(ENVED_TEMP_NAME, active_env);
+ active_env = free_env(active_env);
+ }
+ active_env = copy_env(e);
+ set_enved_env_list_top(0);
+ prepare_env_edit(active_env);
+ set_sensitive(saveB, true);
+ set_sensitive(undoB, false);
+ set_sensitive(revertB, false);
+ env_redisplay();
+ free_env(e);
+ }
+ }
+}
+
+
+static void save_button_pressed(GtkWidget *w, gpointer context)
+{
+ char *name = NULL;
+ if (active_env == NULL) return;
+ name = (char *)gtk_entry_get_text(GTK_ENTRY(textL));
+ if ((!name) || (!(*name)))
+ name = _("unnamed");
+ alert_envelope_editor(name, copy_env(active_env));
+ add_or_edit_symbol(name, active_env);
+ set_sensitive(saveB, false);
+ env_redisplay();
+}
+
+
+static void apply_enved_callback(GtkWidget *w, gpointer context)
+{
+ /* apply current envs to currently sync'd channels */
+ apply_enved();
+ last_active_channel = active_channel;
+}
+
+
+static void undo_and_apply_enved_callback(GtkWidget *w, gpointer context)
+{
+ /* undo upto previous amp env, then apply */
+ /* this blindly undoes the previous edit (assumed to be an envelope) -- if the user made some other change in the meantime, too bad */
+ if ((active_channel) && (active_channel == last_active_channel))
+ {
+ active_channel->squelch_update = true;
+ undo_edit_with_sync(active_channel, 1);
+ active_channel->squelch_update = false;
+ clear_minibuffer(active_channel->sound);
+ }
+ apply_enved();
+ last_active_channel = active_channel;
+}
+
+
+static void reflect_segment_state(void)
+{
+ if (enved_dialog)
+ {
+ widget_modify_bg(expB, GTK_STATE_NORMAL, (enved_style(ss) == ENVELOPE_EXPONENTIAL) ? ss->sgx->yellow : ss->sgx->basic_color);
+ widget_modify_bg(linB, GTK_STATE_NORMAL, (enved_style(ss) == ENVELOPE_LINEAR) ? ss->sgx->yellow : ss->sgx->basic_color);
+ if ((active_env) && (!(showing_all_envs))) env_redisplay();
+ }
+}
+
+
+static void select_or_edit_env(int pos)
+{
+ if (showing_all_envs)
+ {
+ showing_all_envs = false;
+ set_button_label(showB, _("view envs"));
+ }
+ if (active_env) active_env = free_env(active_env);
+ selected_env = position_to_env(pos);
+ if (!selected_env) return;
+ active_env = selected_env;
+ gtk_entry_set_text(GTK_ENTRY(textL), enved_all_names(pos));
+ set_enved_env_list_top(0);
+ prepare_env_edit(active_env);
+ set_sensitive(undoB, false);
+ set_sensitive(revertB, false);
+ set_sensitive(saveB, false);
+ env_redisplay();
+ set_sensitive(deleteB, true);
+}
+
+
+#define BLANK_LABEL " "
+
+static void clear_point_label(void)
+{
+ if (pix_ax)
+ fill_rectangle(pix_ax, 0, 4, 24, 24);
+ set_button_label(brktxtL, BLANK_LABEL);
+}
+
+
+static char brkpt_buf[LABEL_BUFFER_SIZE];
+
+static void enved_display_point_label(mus_float_t x, mus_float_t y)
+{
+ if ((enved_in_dB(ss)) && (min_dB(ss) < -60))
+ mus_snprintf(brkpt_buf, LABEL_BUFFER_SIZE, "%.3f : %.5f", x, y);
+ else mus_snprintf(brkpt_buf, LABEL_BUFFER_SIZE, "%.3f : %.3f", x, y);
+ set_button_label(brktxtL, brkpt_buf);
+}
+
+
+static gboolean brkpixL_expose(GtkWidget *w, GdkEventExpose *ev, gpointer data)
+{
+ if (pix_ax)
+ fill_rectangle(pix_ax, 0, 4, 24, 24);
+ return(false);
+}
+
+
+static gboolean drawer_button_motion(GtkWidget *w, GdkEventMotion *ev, gpointer data)
+{
+ int evx, evy;
+ GdkModifierType state;
+ oclock_t motion_time = 0;
+ ignore_button_release = false;
+ if (BUTTON1_PRESSED(EVENT_STATE(ev)))
+ {
+ if (EVENT_IS_HINT(ev))
+ gdk_window_get_pointer(EVENT_WINDOW(ev), &evx, &evy, &state);
+ else
+ {
+ evx = (int)(EVENT_X(ev));
+ evy = (int)(EVENT_Y(ev));
+ motion_time = EVENT_TIME(ev);
+ if ((motion_time - ss->enved->down_time) < 100) return(false);
+ }
+ }
+ else return(false);
+ if (!showing_all_envs)
+ {
+ mus_float_t x, y;
+ env_editor_button_motion_with_xy(ss->enved, evx, evy, motion_time, active_env, &x, &y);
+ enved_display_point_label(x, y);
+ env_redisplay();
+ }
+ return(false);
+}
+
+
+static gboolean drawer_button_press(GtkWidget *w, GdkEventButton *ev, gpointer data)
+{
+ ss->enved->down_time = EVENT_TIME(ev);
+ ss->enved->env_dragged = false;
+ if (showing_all_envs)
+ {
+ int pos;
+ pos = hit_env((int)(EVENT_X(ev)), (int)(EVENT_Y(ev)), env_window_width, env_window_height);
+ slist_select(env_list, pos);
+ if ((pos >= 0) &&
+ (pos < enved_all_envs_top()))
+ {
+ select_or_edit_env(pos);
+ ignore_button_release = true;
+ }
+ }
+ else
+ {
+ if (!active_env)
+ {
+ active_env = default_env(1.0, 0.0);
+ env_redisplay(); /* needed to get current_xs set up correctly */
+ }
+ if (env_editor_button_press(ss->enved, (int)(EVENT_X(ev)), (int)(EVENT_Y(ev)), EVENT_TIME(ev), active_env))
+ env_redisplay();
+ enved_display_point_label(ungrf_x(ss->enved->axis, EVENT_X(ev)), env_editor_ungrf_y_dB(ss->enved, (int)(EVENT_Y(ev))));
+ set_sensitive(saveB, true);
+ set_sensitive(undoB, true);
+ set_sensitive(revertB, true);
+ }
+ return(false);
+}
+
+
+static gboolean drawer_button_release(GtkWidget *w, GdkEventButton *ev, gpointer data)
+{
+ if (ignore_button_release)
+ ignore_button_release = false;
+ else
+ {
+ if (!showing_all_envs)
+ {
+ env_editor_button_release(ss->enved, active_env);
+ env_redisplay();
+ clear_point_label();
+ }
+ }
+ return(false);
+}
+
+
+static gboolean drawer_expose(GtkWidget *w, GdkEventExpose *ev, gpointer data)
+{
+ env_window_width = widget_width(w);
+ env_window_height = widget_height(w);
+ env_redisplay();
+ return(false);
+}
+
+
+static gboolean drawer_resize(GtkWidget *w, GdkEventConfigure *ev, gpointer data)
+{
+ /* update display, can be either view of all envs or sequence of current envs */
+ env_window_width = widget_width(w);
+ env_window_height = widget_height(w);
+ env_redisplay();
+ return(false);
+}
+
+
+static void show_button_pressed(GtkWidget *w, gpointer context)
+{
+ /* if show all (as opposed to show current), loop through loaded LV_LISTs */
+ showing_all_envs = (!showing_all_envs);
+ set_button_label(showB, (showing_all_envs) ? _("edit env") : _("view envs"));
+ env_redisplay();
+}
+
+
+static void selection_button_pressed(GtkWidget *w, gpointer context)
+{
+ apply_to_selection = (!apply_to_selection);
+ widget_modify_bg(selectionB, GTK_STATE_NORMAL, (apply_to_selection) ? ss->sgx->yellow : ss->sgx->basic_color);
+ set_sensitive(apply2B, true);
+ if ((enved_wave_p(ss)) &&
+ (!showing_all_envs))
+ env_redisplay();
+}
+
+
+static void delete_button_pressed(GtkWidget *w, gpointer context)
+{
+ if (selected_env)
+ {
+ int i, len;
+ len = enved_all_envs_top();
+ for (i = 0; i < len; i++)
+ if (selected_env == enved_all_envs(i))
+ {
+ delete_envelope(enved_all_names(i));
+ if (enved_all_envs_top() == 0)
+ set_sensitive(deleteB, false);
+ if (active_env) active_env = free_env(active_env);
+ selected_env = NULL;
+ env_redisplay();
+ break;
+ }
+ }
+}
+
+
+static void revert_button_pressed(GtkWidget *w, gpointer context)
+{
+ revert_env_edit();
+ if (active_env) active_env = free_env(active_env);
+ active_env = enved_next_env();
+ if (active_env == NULL)
+ text_field_activated(textL, NULL);
+ env_redisplay();
+}
+
+
+static void undo_button_pressed(GtkWidget *w, gpointer context)
+{
+ undo_env_edit();
+ if (active_env) active_env = free_env(active_env);
+ active_env = enved_next_env();
+ env_redisplay();
+}
+
+
+static void redo_button_pressed(GtkWidget *w, gpointer context)
+{
+ redo_env_edit();
+ if (active_env) active_env = free_env(active_env);
+ active_env = enved_next_env();
+ env_redisplay();
+}
+
+
+static void reflect_apply_state(void)
+{
+ gtk_label_set_text(GTK_LABEL(nameL), _(env_names[enved_target(ss)]));
+ widget_modify_bg(ampB, GTK_STATE_NORMAL, (enved_target(ss) == ENVED_AMPLITUDE) ? ss->sgx->yellow : ss->sgx->basic_color);
+ widget_modify_bg(fltB, GTK_STATE_NORMAL, (enved_target(ss) == ENVED_SPECTRUM) ? ss->sgx->yellow : ss->sgx->basic_color);
+ widget_modify_bg(srcB, GTK_STATE_NORMAL, (enved_target(ss) == ENVED_SRATE) ? ss->sgx->yellow : ss->sgx->basic_color);
+ if ((!showing_all_envs) && (enved_wave_p(ss))) env_redisplay();
+}
+
+
+static void flt_button_pressed(GtkWidget *w, gpointer context)
+{
+ in_set_enved_target(ENVED_SPECTRUM);
+ old_clip_p = enved_clip_p(ss);
+ set_enved_clip_p(true);
+ reflect_apply_state();
+}
+
+
+static void amp_button_pressed(GtkWidget *w, gpointer context)
+{
+ if (enved_target(ss) == ENVED_SPECTRUM)
+ set_enved_clip_p(old_clip_p);
+ in_set_enved_target(ENVED_AMPLITUDE);
+ reflect_apply_state();
+}
+
+
+static void src_button_pressed(GtkWidget *w, gpointer context)
+{
+ if (enved_target(ss) == ENVED_SPECTRUM)
+ set_enved_clip_p(old_clip_p);
+ in_set_enved_target(ENVED_SRATE);
+ reflect_apply_state();
+}
+
+
+static void enved_reset(void)
+{
+ set_enved_clip_p(DEFAULT_ENVED_CLIP_P);
+ set_enved_style(ENVELOPE_LINEAR);
+ set_enved_power(DEFAULT_ENVED_POWER);
+ set_enved_base(DEFAULT_ENVED_BASE);
+ set_enved_target(DEFAULT_ENVED_TARGET);
+ set_enved_wave_p(DEFAULT_ENVED_WAVE_P);
+ set_enved_in_dB(DEFAULT_ENVED_IN_DB);
+ set_enved_filter_order(DEFAULT_ENVED_FILTER_ORDER);
+ if (active_env) active_env = free_env(active_env);
+#if HAVE_SCHEME
+ active_env = string_to_env("'(0 0 1 0)");
+#endif
+#if HAVE_FORTH
+ active_env = string_to_env("'( 0 0 1 0 )");
+#endif
+#if HAVE_RUBY
+ active_env = string_to_env("[0, 0, 1, 0]");
+#endif
+ set_enved_env_list_top(0);
+ prepare_env_edit(active_env);
+ set_sensitive(saveB, true);
+ reflect_enved_style();
+ env_redisplay();
+}
+
+
+static void reset_button_pressed(GtkWidget *w, gpointer context)
+{
+ enved_reset();
+}
+
+
+void enved_print(char *name)
+{
+ print_enved(name, env_window_height);
+}
+
+
+static void print_button_pressed(GtkWidget *w, gpointer context)
+{
+ ss->print_choice = PRINT_ENV;
+ file_print_callback(w, context);
+}
+
+
+static void env_browse_callback(const char *name, int row, void *data)
+{
+ select_or_edit_env(row);
+}
+
+
+static void graph_button_callback(GtkWidget *w, gpointer context)
+{
+ in_set_enved_wave_p(TOGGLE_BUTTON_ACTIVE(w));
+ env_redisplay();
+}
+
+
+static void dB_button_callback(GtkWidget *w, gpointer context)
+{
+ in_set_enved_in_dB(TOGGLE_BUTTON_ACTIVE(w));
+ env_redisplay();
+}
+
+
+static void clip_button_callback(GtkWidget *w, gpointer context)
+{
+ in_set_enved_clip_p(TOGGLE_BUTTON_ACTIVE(w));
+}
+
+
+static void exp_button_pressed(GtkWidget *w, gpointer context)
+{
+ set_enved_style(ENVELOPE_EXPONENTIAL);
+ if ((active_env) && (!(showing_all_envs)))
+ {
+ active_env->base = enved_base(ss);
+ set_sensitive(saveB, true);
+ }
+ reflect_segment_state();
+}
+
+
+static void lin_button_pressed(GtkWidget *w, gpointer context)
+{
+ set_enved_style(ENVELOPE_LINEAR);
+ if ((active_env) && (!(showing_all_envs)))
+ {
+ active_env->base = 1.0;
+ set_sensitive(saveB, true);
+ }
+ reflect_segment_state();
+}
+
+
+static void make_base_label(mus_float_t bval)
+{
+ char *sfs, *buf;
+ int i, len, scale_len;
+ len = (int)(enved_power(ss) * 4);
+ if (len < 32) len = 32;
+ sfs = (char *)calloc(len, sizeof(char));
+ mus_snprintf(sfs, len, "%.3f", bval);
+ scale_len = (int)(enved_power(ss) + 3);
+ if (scale_len < 32) scale_len = 32;
+ buf = (char *)calloc(scale_len, sizeof(char));
+ for (i = 0; i < scale_len - 1; i++) buf[i] = sfs[i];
+ gtk_label_set_text(GTK_LABEL(baseValue), buf);
+ free(sfs);
+ free(buf);
+ in_set_enved_base(bval);
+ if ((active_env) && (!(showing_all_envs)))
+ {
+ active_env->base = enved_base(ss);
+ if (enved_style(ss) == ENVELOPE_EXPONENTIAL) env_redisplay();
+ }
+}
+
+
+static void base_changed(mus_float_t val)
+{
+ mus_float_t bval;
+ if (val == 0)
+ bval = 0.0;
+ else
+ {
+ if (val == 0.5)
+ bval = 1.0;
+ else
+ {
+ if (val > 0.5)
+ bval = pow(1.0 + (10.0 * ((val - 0.5) * 2)), enved_power(ss));
+ else
+ bval = pow((val * 2), enved_power(ss) - 1.0);
+ }
+ }
+ make_base_label(bval);
+ if ((active_env) && (enved_style(ss) == ENVELOPE_EXPONENTIAL)) set_sensitive(saveB, true); /* what about undo/redo here? */
+}
+
+
+static void reflect_changed_base(mus_float_t val)
+{
+ mus_float_t ival;
+ if (val <= 0.0)
+ ival = 0.0;
+ else
+ {
+ if (val == 1.0)
+ ival = 0.5;
+ else
+ {
+ if (val <= 1.0)
+ ival = pow(val, 1.0 / (enved_power(ss) - 1.0)) * 0.5;
+ else ival = (0.5 + ((0.5 * (pow(val, (1.0 / (enved_power(ss)))) - 1)) / 10.0));
+ }
+ }
+ ADJUSTMENT_SET_VALUE(baseAdj, ival);
+ /* gtk_adjustment_value_changed(GTK_ADJUSTMENT(baseAdj)); */
+ make_base_label(val);
+}
+
+
+static void base_changed_callback(GtkAdjustment *adj, gpointer context)
+{
+ base_changed(ADJUSTMENT_VALUE(adj));
+}
+
+
+static void fir_button_pressed(GtkWidget *w, gpointer context)
+{
+ FIR_p = (!FIR_p);
+ set_button_label(firB, (FIR_p) ? "fir" : "fft");
+ if (enved_wave_p(ss)) env_redisplay();
+}
+
+
+static void reflect_sound_state(void)
+{
+ bool file_p;
+ file_p = (bool)(any_selected_sound());
+ set_sensitive(applyB, file_p);
+ set_sensitive(apply2B, file_p);
+}
+
+
+static void reflect_file_in_enved(ss_watcher_reason_t reason, void *ignore)
+{
+ if (enved_dialog) reflect_sound_state();
+}
+
+
+static void enved_selection_watcher(selection_watcher_reason_t reason, void *data);
+#define BB_MARGIN 3
+
+GtkWidget *create_envelope_editor(void)
+{
+ if (!enved_dialog)
+ {
+ GtkWidget *mainform, *helpB, *leftbox, *bottombox, *leftframe, *toprow, *bottomrow;
+
+ enved_dialog = gtk_dialog_new();
+ SG_SIGNAL_CONNECT(enved_dialog, "delete_event", delete_enved_dialog, NULL);
+ gtk_window_set_title(GTK_WINDOW(enved_dialog), _("Edit Envelope"));
+ sg_make_resizable(enved_dialog);
+ gtk_container_set_border_width(GTK_CONTAINER(enved_dialog), 4);
+ gtk_widget_realize(enved_dialog);
+ gtk_window_resize(GTK_WINDOW(enved_dialog), 500, 500);
+ widget_modify_bg(enved_dialog, GTK_STATE_NORMAL, ss->sgx->basic_color);
+
+ gc = gc_new(MAIN_WINDOW(ss));
+ gc_set_background(gc, ss->sgx->white);
+ gc_set_foreground(gc, ss->sgx->black);
+
+ rgc = gc_new(MAIN_WINDOW(ss));
+ gc_set_background(rgc, ss->sgx->white);
+ gc_set_foreground(rgc, ss->sgx->red);
+
+ ggc = gc_new(MAIN_WINDOW(ss));
+ gc_set_background(ggc, ss->sgx->white);
+ gc_set_foreground(ggc, ss->sgx->enved_waveform_color);
+
+ hgc = gc_new(MAIN_WINDOW(ss)); /* progress pix next to break point label */
+ gc_set_background(hgc, ss->sgx->basic_color);
+ gc_set_foreground(hgc, ss->sgx->basic_color);
+
+ helpB = gtk_button_new_from_stock(GTK_STOCK_HELP);
+ gtk_widget_set_name(helpB, "help_button");
+
+ cancelB = sg_button_new_from_stock_with_label("Go Away", GTK_STOCK_QUIT);
+ gtk_widget_set_name(cancelB, "quit_button");
+
+ applyB = gtk_button_new_from_stock(GTK_STOCK_APPLY);
+ gtk_widget_set_name(applyB, "doit_button");
+
+ apply2B = sg_button_new_from_stock_with_label(_("Undo&Apply"), GTK_STOCK_UNDO);
+ gtk_widget_set_name(apply2B, "doit_again_button");
+
+ resetB = sg_button_new_from_stock_with_label(_("Reset"), GTK_STOCK_REFRESH);
+ gtk_widget_set_name(resetB, "reset_button");
+
+ gtk_box_pack_start(GTK_BOX(DIALOG_ACTION_AREA(enved_dialog)), applyB, false, true, 10);
+ gtk_box_pack_start(GTK_BOX(DIALOG_ACTION_AREA(enved_dialog)), apply2B, false, true, 10);
+ gtk_box_pack_start(GTK_BOX(DIALOG_ACTION_AREA(enved_dialog)), cancelB, false, true, 10);
+ gtk_box_pack_start(GTK_BOX(DIALOG_ACTION_AREA(enved_dialog)), resetB, false, true, 10);
+ gtk_box_pack_end(GTK_BOX(DIALOG_ACTION_AREA(enved_dialog)), helpB, false, true, 10);
+
+ SG_SIGNAL_CONNECT(cancelB, "clicked", dismiss_enved_callback, NULL);
+ SG_SIGNAL_CONNECT(applyB, "clicked", apply_enved_callback, NULL);
+ SG_SIGNAL_CONNECT(apply2B, "clicked", undo_and_apply_enved_callback, NULL);
+ SG_SIGNAL_CONNECT(resetB, "clicked", reset_button_pressed, NULL);
+ SG_SIGNAL_CONNECT(helpB, "clicked", help_enved_callback, NULL);
+
+ gtk_widget_show(cancelB);
+ gtk_widget_show(applyB);
+ gtk_widget_show(apply2B);
+ gtk_widget_show(resetB);
+ gtk_widget_show(helpB);
+
+ mainform = gtk_hbox_new(false, 0); /* buttons + graph */
+ gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(enved_dialog)), mainform, true, true, 0);
+
+ leftframe = gtk_frame_new(NULL);
+ gtk_box_pack_start(GTK_BOX(mainform), leftframe, false, false, 0);
+ gtk_frame_set_shadow_type(GTK_FRAME(leftframe), GTK_SHADOW_ETCHED_IN);
+ gtk_widget_show(leftframe);
+ widget_modify_bg(leftframe, GTK_STATE_NORMAL, ss->sgx->black);
+
+ leftbox = gtk_vbox_new(false, 0);
+ gtk_container_add(GTK_CONTAINER(leftframe), leftbox);
+ gtk_widget_show(leftbox);
+
+ bottombox = gtk_vbox_new(false, 0);
+ gtk_box_pack_start(GTK_BOX(DIALOG_CONTENT_AREA(enved_dialog)), bottombox, false, false, 0);
+ gtk_widget_show(bottombox);
+
+ drawer = gtk_drawing_area_new();
+ gtk_box_pack_start(GTK_BOX(mainform), drawer, true, true, 0);
+ gtk_widget_set_events(drawer, GDK_ALL_EVENTS_MASK);
+ widget_modify_bg(drawer, GTK_STATE_NORMAL, ss->sgx->white);
+ widget_modify_fg(drawer, GTK_STATE_NORMAL, ss->sgx->black);
+ gtk_widget_show(drawer);
+
+ showB = gtk_button_new_with_label(_("view envs"));
+ gtk_button_set_relief(GTK_BUTTON(showB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(leftbox), showB, false, false, BB_MARGIN);
+ SG_SIGNAL_CONNECT(showB, "clicked", show_button_pressed, NULL);
+ gtk_widget_show(showB);
+
+ saverow = gtk_hbox_new(false, BB_MARGIN);
+ gtk_box_pack_start(GTK_BOX(leftbox), saverow, false, false, BB_MARGIN);
+ gtk_widget_show(saverow);
+
+ saveB = gtk_button_new_with_label(_(" save "));
+ gtk_button_set_relief(GTK_BUTTON(saveB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(saverow), saveB, true, true, BB_MARGIN);
+ SG_SIGNAL_CONNECT(saveB, "clicked", save_button_pressed, NULL);
+ gtk_widget_show(saveB);
+
+ printB = gtk_button_new_with_label(_(" print "));
+ gtk_button_set_relief(GTK_BUTTON(printB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(saverow), printB, true, true, BB_MARGIN);
+ SG_SIGNAL_CONNECT(printB, "clicked", print_button_pressed, NULL);
+ gtk_widget_show(printB);
+
+ revrow = gtk_hbox_new(false, 0);
+ gtk_box_pack_start(GTK_BOX(leftbox), revrow, false, false, BB_MARGIN);
+ gtk_widget_show(revrow);
+
+ revertB = gtk_button_new_with_label(_("revert "));
+ gtk_button_set_relief(GTK_BUTTON(revertB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(revrow), revertB, true, true, BB_MARGIN);
+ SG_SIGNAL_CONNECT(revertB, "clicked", revert_button_pressed, NULL);
+ gtk_widget_show(revertB);
+
+ deleteB = gtk_button_new_with_label(_("delete"));
+ gtk_button_set_relief(GTK_BUTTON(deleteB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(revrow), deleteB, true, true, BB_MARGIN);
+ SG_SIGNAL_CONNECT(deleteB, "clicked", delete_button_pressed, NULL);
+ gtk_widget_show(deleteB);
+
+ unrow = gtk_hbox_new(false, 0);
+ gtk_box_pack_start(GTK_BOX(leftbox), unrow, false, false, BB_MARGIN);
+ gtk_widget_show(unrow);
+
+ undoB = gtk_button_new_with_label(_(" undo "));
+ gtk_button_set_relief(GTK_BUTTON(undoB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(unrow), undoB, true, true, BB_MARGIN);
+ SG_SIGNAL_CONNECT(undoB, "clicked", undo_button_pressed, NULL);
+ gtk_widget_show(undoB);
+
+ redoB = gtk_button_new_with_label(_(" redo "));
+ gtk_button_set_relief(GTK_BUTTON(redoB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(unrow), redoB, true, true, BB_MARGIN);
+ SG_SIGNAL_CONNECT(redoB, "clicked", redo_button_pressed, NULL);
+ gtk_widget_show(redoB);
+
+ rbrow = gtk_hbox_new(false, 0);
+ gtk_box_pack_start(GTK_BOX(leftbox), rbrow, false, false, BB_MARGIN);
+ gtk_widget_show(rbrow);
+
+ ampB = gtk_button_new_with_label(_("amp"));
+ gtk_button_set_relief(GTK_BUTTON(ampB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(rbrow), ampB, true, true, BB_MARGIN);
+ SG_SIGNAL_CONNECT(ampB, "clicked", amp_button_pressed, NULL);
+ gtk_widget_show(ampB);
+
+ fltB = gtk_button_new_with_label(_("flt"));
+ gtk_button_set_relief(GTK_BUTTON(fltB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(rbrow), fltB, true, true, BB_MARGIN);
+ SG_SIGNAL_CONNECT(fltB, "clicked", flt_button_pressed, NULL);
+ gtk_widget_show(fltB);
+
+ srcB = gtk_button_new_with_label(_("src"));
+ gtk_button_set_relief(GTK_BUTTON(srcB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(rbrow), srcB, true, true, BB_MARGIN);
+ SG_SIGNAL_CONNECT(srcB, "clicked", src_button_pressed, NULL);
+ gtk_widget_show(srcB);
+
+ lerow = gtk_hbox_new(false, 0);
+ gtk_box_pack_start(GTK_BOX(leftbox), lerow, false, false, BB_MARGIN);
+ gtk_widget_show(lerow);
+
+ linB = gtk_button_new_with_label(_("lin"));
+ gtk_button_set_relief(GTK_BUTTON(linB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(lerow), linB, true, true, BB_MARGIN);
+ SG_SIGNAL_CONNECT(linB, "clicked", lin_button_pressed, NULL);
+ gtk_widget_show(linB);
+
+ expB = gtk_button_new_with_label(_("exp"));
+ gtk_button_set_relief(GTK_BUTTON(expB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(lerow), expB, true, true, BB_MARGIN);
+ SG_SIGNAL_CONNECT(expB, "clicked", exp_button_pressed, NULL);
+ gtk_widget_show(expB);
+
+ selrow = gtk_hbox_new(false, 0);
+ gtk_box_pack_start(GTK_BOX(leftbox), selrow, false, false, BB_MARGIN);
+ gtk_widget_show(selrow);
+
+ selectionB = gtk_button_new_with_label(_("selection"));
+ gtk_button_set_relief(GTK_BUTTON(selectionB), GTK_RELIEF_HALF);
+ gtk_box_pack_start(GTK_BOX(selrow), selectionB, true, true, BB_MARGIN);
+ SG_SIGNAL_CONNECT(selectionB, "clicked", selection_button_pressed, NULL);
+ gtk_widget_show(selectionB);
+
+ env_list = slist_new_with_title(_("envs:"), leftbox, NULL, 0, BOX_PACK);
+ env_list->select_callback = env_browse_callback;
+ if (enved_all_envs_top() > 0) make_scrolled_env_list();
+
+ toprow = gtk_hbox_new(false, 0);
+ gtk_box_pack_start(GTK_BOX(bottombox), toprow, false, false, 6);
+ gtk_widget_show(toprow);
+
+ bottomrow = gtk_hbox_new(false, 0);
+ gtk_box_pack_start(GTK_BOX(bottombox), bottomrow, false, false, 4);
+ gtk_widget_show(bottomrow);
+
+ nameL = gtk_label_new(_("amp env:"));
+ gtk_box_pack_start(GTK_BOX(toprow), nameL, false, false, 0);
+ gtk_widget_show(nameL);
+
+ textL = snd_entry_new(toprow, WITH_WHITE_BACKGROUND);
+ SG_SIGNAL_CONNECT(textL, "activate", text_field_activated, NULL);
+
+ brkpixL = gtk_drawing_area_new();
+ widget_modify_bg(brkpixL, GTK_STATE_NORMAL, ss->sgx->basic_color);
+ gtk_widget_set_events(brkpixL, GDK_EXPOSURE_MASK);
+ gtk_widget_set_size_request(brkpixL, 16, 16);
+ gtk_box_pack_start(GTK_BOX(toprow), brkpixL, false, false, 0);
+ gtk_widget_show(brkpixL);
+ SG_SIGNAL_CONNECT(brkpixL, "expose_event", brkpixL_expose, NULL);
+
+#if 0
+ brktxtL = snd_gtk_highlight_label_new(BLANK_LABEL); /* not NULL! gtk only creates the label child if not null */
+#else
+ brktxtL = gtk_button_new_with_label(BLANK_LABEL);
+ gtk_button_set_relief(GTK_BUTTON(brktxtL), GTK_RELIEF_NONE);
+#endif
+ gtk_box_pack_start(GTK_BOX(toprow), brktxtL, false, false, 6);
+ gtk_widget_show(brktxtL);
+
+ clipB = gtk_check_button_new_with_label(_("clip"));
+ SG_SIGNAL_CONNECT(clipB, "toggled", clip_button_callback, NULL);
+ gtk_box_pack_start(GTK_BOX(toprow), clipB, false, false, 4);
+ gtk_widget_show(clipB);
+
+ graphB = gtk_check_button_new_with_label(_("wave"));
+ SG_SIGNAL_CONNECT(graphB, "toggled", graph_button_callback, NULL);
+ gtk_box_pack_start(GTK_BOX(toprow), graphB, false, false, 4);
+ gtk_widget_show(graphB);
+
+ dBB = gtk_check_button_new_with_label(_("dB"));
+ SG_SIGNAL_CONNECT(dBB, "toggled", dB_button_callback, NULL);
+ gtk_box_pack_start(GTK_BOX(toprow), dBB, false, false, 4);
+ gtk_widget_show(dBB);
+
+ baseLabel = gtk_label_new(_("exp:"));
+ gtk_box_pack_start(GTK_BOX(bottomrow), baseLabel, false, false, 2);
+ gtk_widget_show(baseLabel);
+
+ baseValue = gtk_label_new("1.000");
+ gtk_box_pack_start(GTK_BOX(bottomrow), baseValue, false, false, 2);
+ gtk_widget_show(baseValue);
+
+
+ baseAdj = gtk_adjustment_new(0.5, 0.0, 1.0, 0.001, 0.01, .1);
+ baseScale = gtk_hscrollbar_new(GTK_ADJUSTMENT(baseAdj));
+ widget_modify_bg(baseScale, GTK_STATE_NORMAL, ss->sgx->position_color);
+ SG_SIGNAL_CONNECT(baseAdj, "value_changed", base_changed_callback, NULL);
+ gtk_box_pack_start(GTK_BOX(bottomrow), baseScale, true, true, 4);
+ gtk_widget_show(baseScale);
+
+ orderAdj = gtk_adjustment_new(20, 2, 100000, 2, 10, 0);
+ orderL = gtk_spin_button_new(GTK_ADJUSTMENT(orderAdj), 0.0, 0);
+ gtk_box_pack_end(GTK_BOX(bottomrow), orderL, false, false, 4);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(orderL), true);
+ SG_SIGNAL_CONNECT(orderAdj, "value_changed", enved_filter_order_callback, NULL);
+ SG_SIGNAL_CONNECT(orderL, "enter_notify_event", spin_button_focus_callback, NULL);
+ SG_SIGNAL_CONNECT(orderL, "leave_notify_event", spin_button_unfocus_callback, NULL);
+ gtk_widget_show(orderL);
+
+ firB = gtk_button_new_with_label((FIR_p) ? "fir" : "fft");
+ SG_SIGNAL_CONNECT(firB, "clicked", fir_button_pressed, NULL);
+ gtk_box_pack_end(GTK_BOX(bottomrow), firB, false, false, 4);
+ gtk_widget_show(firB);
+
+ gtk_widget_show(mainform);
+ gtk_widget_show(enved_dialog);
+
+ pix_ax = (axis_context *)calloc(1, sizeof(axis_context));
+ pix_ax->wn = GDK_DRAWABLE(WIDGET_TO_WINDOW(brkpixL));
+ pix_ax->gc = hgc;
+#if USE_CAIRO
+ pix_ax->cr = gdk_cairo_create(WIDGET_TO_WINDOW(brkpixL));
+#endif
+
+ SG_SIGNAL_CONNECT(drawer, "expose_event", drawer_expose, NULL);
+ SG_SIGNAL_CONNECT(drawer, "configure_event", drawer_resize, NULL);
+ SG_SIGNAL_CONNECT(drawer, "button_press_event", drawer_button_press, NULL);
+ SG_SIGNAL_CONNECT(drawer, "button_release_event", drawer_button_release, NULL);
+ SG_SIGNAL_CONNECT(drawer, "motion_notify_event", drawer_button_motion, NULL);
+
+ if (enved_all_envs_top() == 0)
+ {
+ set_sensitive(showB, false);
+ }
+ set_sensitive(revertB, false);
+ set_sensitive(deleteB, false);
+ set_sensitive(undoB, false);
+ set_sensitive(redoB, false);
+ set_sensitive(saveB, false);
+ if (!(selection_is_active())) set_sensitive(selectionB, false);
+
+ set_toggle_button(clipB, enved_clip_p(ss), false, NULL);
+ set_toggle_button(graphB, enved_wave_p(ss), false, NULL);
+ set_toggle_button(dBB, enved_in_dB(ss), false, NULL);
+
+ reflect_apply_state();
+ reflect_segment_state();
+ reflect_sound_state();
+
+ set_dialog_widget(ENVED_DIALOG, enved_dialog);
+ add_ss_watcher(SS_FILE_OPEN_WATCHER, reflect_file_in_enved, NULL);
+ add_selection_watcher(enved_selection_watcher, NULL);
+ }
+ else raise_dialog(enved_dialog);
+ active_channel = current_channel();
+ return(enved_dialog);
+}
+
+
+#if USE_CAIRO
+GdkDrawable *enved_pix_wn(void);
+GdkDrawable *enved_pix_wn(void)
+{
+ return(GDK_DRAWABLE(WIDGET_TO_WINDOW(brkpixL)));
+}
+#endif
+
+
+void set_enved_clip_p(bool val)
+{
+ in_set_enved_clip_p(val);
+ if (enved_dialog) set_toggle_button(clipB, val, false, NULL);
+}
+
+
+void reflect_enved_style(void)
+{
+ reflect_segment_state();
+}
+
+
+void set_enved_target(enved_target_t val)
+{
+ in_set_enved_target(val);
+ if (enved_dialog) reflect_apply_state();
+}
+
+
+void set_enved_wave_p(bool val)
+{
+ in_set_enved_wave_p(val);
+ if (enved_dialog) set_toggle_button(graphB, val, false, NULL);
+}
+
+
+void set_enved_in_dB(bool val)
+{
+ in_set_enved_in_dB(val);
+ if (enved_dialog) set_toggle_button(dBB, val, false, NULL);
+}
+
+
+void set_enved_base(mus_float_t val)
+{
+ in_set_enved_base(val);
+ if (enved_dialog) reflect_changed_base(val);
+}
+
+
+bool enved_dialog_is_active(void)
+{
+ return((enved_dialog) && (GTK_WIDGET_VISIBLE(enved_dialog)));
+}
+
+
+void set_enved_filter_order(int order)
+{
+ if ((order > 0) && (order < 2000))
+ {
+ if (order & 1)
+ in_set_enved_filter_order(order + 1);
+ else in_set_enved_filter_order(order);
+ if (enved_dialog)
+ {
+ widget_int_to_text(orderL, enved_filter_order(ss));
+ if ((enved_target(ss) == ENVED_SPECTRUM) &&
+ (enved_wave_p(ss)) &&
+ (!showing_all_envs))
+ env_redisplay();
+ }
+ }
+}
+
+
+static void enved_reflect_selection(bool on)
+{
+ if ((enved_dialog) && (!within_selection_src))
+ {
+ set_sensitive(selectionB, on);
+ if ((apply_to_selection) && (!on))
+ {
+ apply_to_selection = false;
+ we_turned_selection_off = true;
+ }
+ if ((on) && (we_turned_selection_off))
+ {
+ apply_to_selection = true;
+ }
+ widget_modify_bg(selectionB, GTK_STATE_NORMAL, (apply_to_selection) ? ss->sgx->yellow : ss->sgx->basic_color);
+ if ((enved_target(ss) != ENVED_SPECTRUM) &&
+ (enved_wave_p(ss)) &&
+ (!showing_all_envs))
+ env_redisplay();
+ }
+}
+
+
+static void enved_selection_watcher(selection_watcher_reason_t reason, void *data)
+{
+ switch (reason)
+ {
+ case SELECTION_INACTIVE: enved_reflect_selection(false); break;
+ case SELECTION_ACTIVE: enved_reflect_selection(true); break;
+ default: enved_reflect_selection(selection_is_active()); break;
+ }
+}
+
+
+void color_enved_waveform(color_info *pix)
+{
+ ss->sgx->enved_waveform_color = pix;
+ if (enved_dialog)
+ {
+ gc_set_foreground(ggc, pix);
+ if ((enved_wave_p(ss)) && (enved_dialog)) env_redisplay();
+ }
+}
+
+
+static XEN g_enved_envelope(void)
+{
+ #define H_enved_envelope "(" S_enved_envelope "): current envelope editor displayed (active) envelope"
+ return(env_to_xen(active_env));
+}
+
+
+static XEN g_set_enved_envelope(XEN e)
+{
+ XEN_ASSERT_TYPE(XEN_LIST_P(e) || XEN_STRING_P(e) || XEN_SYMBOL_P(e), e, XEN_ONLY_ARG, S_setB S_enved_envelope, "a list, symbol, or string");
+ if (active_env) active_env = free_env(active_env);
+ if ((XEN_STRING_P(e)) || (XEN_SYMBOL_P(e)))
+ active_env = name_to_env((XEN_STRING_P(e)) ? XEN_TO_C_STRING(e) : XEN_SYMBOL_TO_C_STRING(e));
+ else active_env = xen_to_env(e);
+ if ((!active_env) && (!(XEN_LIST_P(e))))
+ XEN_ERROR(NO_SUCH_ENVELOPE,
+ XEN_LIST_2(C_TO_XEN_STRING(S_setB S_enved_envelope),
+ e));
+ if (enved_dialog)
+ env_redisplay();
+ return(e);
+}
+
+
+static XEN g_enved_filter(void)
+{
+ #define H_enved_filter "(" S_enved_filter "): envelope editor FIR/FFT filter choice (#t: FIR)"
+ return(C_TO_XEN_BOOLEAN(FIR_p));
+}
+
+
+static XEN g_set_enved_filter(XEN type)
+{
+ XEN_ASSERT_TYPE(XEN_BOOLEAN_P(type), type, XEN_ONLY_ARG, S_setB S_enved_filter, "boolean");
+ FIR_p = XEN_TO_C_BOOLEAN(type);
+ if (firB)
+ set_button_label(firB, (FIR_p) ? "fir" : "fft");
+ return(type);
+}
+
+
+#ifdef XEN_ARGIFY_1
+XEN_NARGIFY_0(g_enved_filter_w, g_enved_filter)
+XEN_NARGIFY_1(g_set_enved_filter_w, g_set_enved_filter)
+XEN_NARGIFY_0(g_enved_envelope_w, g_enved_envelope)
+XEN_NARGIFY_1(g_set_enved_envelope_w, g_set_enved_envelope)
+#else
+#define g_enved_filter_w g_enved_filter
+#define g_set_enved_filter_w g_set_enved_filter
+#define g_enved_envelope_w g_enved_envelope
+#define g_set_enved_envelope_w g_set_enved_envelope
+#endif
+
+void g_init_gxenv(void)
+{
+ XEN_DEFINE_PROCEDURE_WITH_SETTER(S_enved_filter, g_enved_filter_w, H_enved_filter,
+ S_setB S_enved_filter, g_set_enved_filter_w, 0, 0, 1, 0);
+ XEN_DEFINE_PROCEDURE_WITH_SETTER(S_enved_envelope, g_enved_envelope_w, H_enved_envelope,
+ S_setB S_enved_envelope, g_set_enved_envelope_w, 0, 0, 1, 0);
+}
+