[SCM] calf/master: + GUI, JACK host: implemented primitive main window + VU Meter: added, used in JACK host + at least some LV2 and DSSI GUI support is temporarily broken
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:37:04 UTC 2013
The following commit has been merged in the master branch:
commit 486dd24340ba56270287b9609fb2d8f16fd37131
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date: Tue Feb 12 00:04:52 2008 +0000
+ GUI, JACK host: implemented primitive main window
+ VU Meter: added, used in JACK host
+ at least some LV2 and DSSI GUI support is temporarily broken
git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@127 78b06b96-2940-0410-b7fc-879d825d01d8
diff --git a/src/Makefile.am b/src/Makefile.am
index e7b7c8c..5999aca 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -48,7 +48,7 @@ calf_la_SOURCES = modules.cpp giface.cpp monosynth.cpp organ.cpp preset.cpp synt
calf_la_LDFLAGS = -rpath $(ladspadir) -avoid-version -module -lexpat -export-symbols-regex "(ladspa_|lv2_|dssi_)descriptor"
if USE_LV2_GUI
-calflv2gui_la_SOURCES = gui.cpp custom_ctl.cpp modules.cpp giface.cpp monosynth.cpp organ.cpp preset.cpp synth.cpp lv2gui.cpp
+calflv2gui_la_SOURCES = gui.cpp custom_ctl.cpp modules.cpp giface.cpp monosynth.cpp organ.cpp preset.cpp synth.cpp lv2gui.cpp main_win.cpp
calflv2gui_la_LDFLAGS = -rpath $(lv2dir) -avoid-version -module -lexpat -export-symbols-regex "lv2_gui_descriptor" $(GUI_DEPS_LIBS)
endif
@@ -56,7 +56,7 @@ libcalfstatic_la_SOURCES = modules.cpp giface.cpp monosynth.cpp organ.cpp preset
libcalfstatic_la_LDFLAGS = -static -lexpat
if USE_GUI
-libcalfgui_la_SOURCES = gui.cpp preset_gui.cpp custom_ctl.cpp osctl.cpp
+libcalfgui_la_SOURCES = gui.cpp preset_gui.cpp custom_ctl.cpp osctl.cpp main_win.cpp
libcalfgui_la_LDFLAGS = -static
endif
diff --git a/src/calf/custom_ctl.h b/src/calf/custom_ctl.h
index de9ab1d..372a9be 100644
--- a/src/calf/custom_ctl.h
+++ b/src/calf/custom_ctl.h
@@ -28,6 +28,28 @@ extern GtkWidget *calf_line_graph_new();
extern GType calf_line_graph_get_type();
+#define CALF_TYPE_VUMETER (calf_vumeter_get_type())
+#define CALF_VUMETER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALF_TYPE_VUMETER, CalfVUMeter))
+#define CALF_IS_VUMETER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALF_TYPE_VUMETER))
+#define CALF_VUMETER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALF_TYPE_VUMETER, CalfVUMeterClass))
+#define CALF_IS_VUMETER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALF_TYPE_VUMETER))
+
+struct CalfVUMeter
+{
+ GtkWidget parent;
+ float value;
+};
+
+struct CalfVUMeterClass
+{
+ GtkWidgetClass parent_class;
+};
+
+extern GtkWidget *calf_vumeter_new();
+extern GType calf_vumeter_get_type();
+extern void calf_vumeter_set_value(CalfVUMeter *meter, float value);
+extern float calf_vumeter_get_value(CalfVUMeter *meter);
+
#define CALF_TYPE_KNOB (calf_knob_get_type())
#define CALF_KNOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALF_TYPE_KNOB, CalfKnob))
#define CALF_IS_KNOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALF_TYPE_KNOB))
diff --git a/src/calf/giface.h b/src/calf/giface.h
index bf89dd3..941c4a2 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -118,6 +118,12 @@ struct plugin_ctl_iface
virtual line_graph_iface *get_line_graph_iface() = 0;
virtual int get_param_port_offset() = 0;
virtual bool activate_preset(int bank, int program) = 0;
+ virtual const char *get_name() = 0;
+ virtual const char *get_id() = 0;
+ virtual int get_input_count()=0;
+ virtual int get_output_count()=0;
+ virtual bool get_midi()=0;
+ virtual float get_level(int port)=0;
virtual ~plugin_ctl_iface() {}
};
@@ -194,6 +200,18 @@ struct ladspa_instance: public Module, public plugin_ctl_iface
virtual bool activate_preset(int bank, int program) {
return false;
}
+ virtual const char *get_name()
+ {
+ return Module::get_name();
+ }
+ virtual const char *get_id()
+ {
+ return Module::get_id();
+ }
+ virtual int get_input_count() { return Module::in_count; }
+ virtual int get_output_count() { return Module::out_count; }
+ virtual bool get_midi() { return Module::support_midi; }
+ virtual float get_level(int port) { return 0.f; }
};
template<class Module>
diff --git a/src/calf/gui.h b/src/calf/gui.h
index b598fa8..fc0016e 100644
--- a/src/calf/gui.h
+++ b/src/calf/gui.h
@@ -69,7 +69,8 @@ struct param_control: public control_base
/// called to transfer the value from parameter(s) to control
virtual void set()=0;
virtual void hook_params();
- virtual ~param_control() {}
+ virtual void on_idle() {}
+ virtual ~param_control();
};
struct control_container: public control_base
@@ -172,13 +173,12 @@ struct combo_box_param_control: public param_control
struct line_graph_param_control: public param_control
{
CalfLineGraph *graph;
- int source_id;
virtual GtkWidget *create(plugin_gui *_gui, int _param_no);
virtual void get() {}
virtual void set();
+ virtual void on_idle();
virtual ~line_graph_param_control();
- static gboolean update(void *data);
};
struct knob_param_control: public param_control
@@ -222,10 +222,24 @@ public:
void refresh(int param_no, param_control *originator = NULL);
void xml_element_start(const char *element, const char *attributes[]);
void set_param_value(int param_no, float value, param_control *originator = NULL);
+ void on_idle();
+ ~plugin_gui();
static void xml_element_start(void *data, const char *element, const char *attributes[]);
static void xml_element_end(void *data, const char *element);
};
+class main_window_iface
+{
+public:
+ virtual void add_plugin(plugin_ctl_iface *plugin)=0;
+ virtual void del_plugin(plugin_ctl_iface *plugin)=0;
+
+ virtual void set_window(plugin_ctl_iface *plugin, plugin_gui_window *window)=0;
+ virtual void refresh_all_presets()=0;
+ virtual bool check_condition(const char *name)=0;
+ virtual ~main_window_iface() {}
+};
+
class plugin_gui_window
{
public:
@@ -233,14 +247,15 @@ public:
GtkWindow *toplevel;
GtkUIManager *ui_mgr;
GtkActionGroup *std_actions, *preset_actions;
- std::set<std::string> conditions;
- static std::set<plugin_gui_window *> all_windows;
+ main_window_iface *main;
+ int source_id;
- plugin_gui_window();
+ plugin_gui_window(main_window_iface *_main);
std::string make_gui_preset_list(GtkActionGroup *grp);
void fill_gui_presets();
void create(plugin_ctl_iface *_plugin, const char *title, const char *effect);
- static void refresh_all_presets();
+ void close();
+ static gboolean on_idle(void *data);
~plugin_gui_window();
};
diff --git a/src/calf/jackhost.h b/src/calf/jackhost.h
index f0d44fb..2b56bd9 100644
--- a/src/calf/jackhost.h
+++ b/src/calf/jackhost.h
@@ -1,10 +1,6 @@
/* Calf DSP Library Utility Application - calfjackhost
* API wrapper for JACK Audio Connection Kit
*
- * Note: while this header file is licensed under LGPL license,
- * the application as a whole is GPLed because of partial dependency
- * on phat graphics library.
- *
* Copyright (C) 2007 Krzysztof Foltman
*
* This program is free software; you can redistribute it and/or
@@ -111,15 +107,12 @@ public:
bool changed;
port midi_port;
std::string name;
- virtual int get_input_count()=0;
- virtual int get_output_count()=0;
virtual port *get_inputs()=0;
virtual port *get_outputs()=0;
virtual port *get_midi_port() { return get_midi() ? &midi_port : NULL; }
virtual float *get_params()=0;
virtual void init_module()=0;
virtual void cache_ports()=0;
- virtual bool get_midi()=0;
virtual int process(jack_nframes_t nframes)=0;
jack_host_base() {
@@ -194,12 +187,38 @@ public:
}
};
+struct vumeter
+{
+ float level, falloff;
+
+ vumeter()
+ {
+ falloff = 0.999f;
+ }
+
+ inline void update(float *src, unsigned int len)
+ {
+ double tmp = level;
+ for (unsigned int i = 0; i < len; i++)
+ tmp = std::max(tmp * falloff, (double)fabs(src[i]));
+ level = tmp;
+ dsp::sanitize(level);
+ }
+ inline void update_zeros(unsigned int len)
+ {
+ level *= pow((double)falloff, (double)len);
+ dsp::sanitize(level);
+ }
+};
+
template<class Module>
class jack_host: public jack_host_base {
public:
Module module;
port inputs[Module::in_count], outputs[Module::out_count];
+ vumeter input_vus[Module::in_count], output_vus[Module::out_count];
float params[Module::param_count];
+ float midi_meter;
jack_host()
{
@@ -207,6 +226,7 @@ public:
module.params[i] = ¶ms[i];
params[i] = Module::param_props[i].def_value;
}
+ midi_meter = 0;
}
virtual void init_module() {
@@ -240,6 +260,38 @@ public:
break;
}
}
+ void process_part(unsigned int time, unsigned int len)
+ {
+ if (!len)
+ return;
+ for (int i = 0; i < Module::in_count; i++)
+ input_vus[i].update(module.ins[i] + time, len);
+ unsigned int mask = module.process(time, len, -1, -1);
+ for (int i = 0; i < Module::out_count; i++)
+ {
+ if (!(mask & (1 << i))) {
+ dsp::zero(module.outs[i] + time, len);
+ output_vus[i].update_zeros(len);
+ } else
+ output_vus[i].update(module.outs[i] + time, len);
+ }
+ // decay linearly for 0.1s
+ float new_meter = midi_meter - len / (0.1 * client->sample_rate);
+ if (new_meter < 0)
+ new_meter = 0;
+ midi_meter = new_meter;
+ }
+ virtual float get_level(int port) {
+ if (port < Module::in_count)
+ return input_vus[port].level;
+ port -= Module::in_count;
+ if (port < Module::out_count)
+ return output_vus[port].level;
+ port -= Module::out_count;
+ if (port == 0 && Module::support_midi)
+ return midi_meter;
+ return 0.f;
+ }
int process(jack_nframes_t nframes)
{
for (int i=0; i<Module::in_count; i++) {
@@ -253,7 +305,6 @@ public:
}
unsigned int time = 0;
- unsigned int mask = 0;
if (Module::support_midi)
{
jack_midi_event_t event;
@@ -269,23 +320,16 @@ public:
#else
jack_midi_event_get(&event, midi_port.data, i);
#endif
- mask = module.process(time, event.time - time, -1, -1);
- for (int i = 0; i < Module::out_count; i++) {
- if (!(mask & (1 << i)))
- dsp::zero(module.outs[i] + time, event.time - time);
- }
+ unsigned int len = event.time - time;
+ process_part(time, len);
+ midi_meter = 1.f;
handle_event(event.buffer, event.size);
time = event.time;
}
}
- mask = module.process(time, nframes - time, -1, -1);
- for (int i = 0; i < Module::out_count; i++) {
- // zero unfilled outputs
- if (!(mask & (1 << i)))
- dsp::zero(module.outs[i] + time, nframes - time);
- }
+ process_part(time, nframes - time);
return 0;
}
@@ -327,6 +371,14 @@ public:
{
return &module;
}
+ virtual const char *get_name()
+ {
+ return Module::get_name();
+ }
+ virtual const char *get_id()
+ {
+ return Module::get_id();
+ }
};
extern jack_host_base *create_jack_host(const char *name);
diff --git a/src/calf/lv2wrap.h b/src/calf/lv2wrap.h
index de9948f..d0552d8 100644
--- a/src/calf/lv2wrap.h
+++ b/src/calf/lv2wrap.h
@@ -64,6 +64,18 @@ struct lv2_instance: public Module, public plugin_ctl_iface
virtual bool activate_preset(int bank, int program) {
return false;
}
+ virtual const char *get_name()
+ {
+ return Module::get_name();
+ }
+ virtual const char *get_id()
+ {
+ return Module::get_id();
+ }
+ virtual int get_input_count() { return Module::in_count; }
+ virtual int get_output_count() { return Module::out_count; }
+ virtual bool get_midi() { return Module::support_midi; }
+ virtual float get_level(int port) { return 0.f; }
};
template<class Module>
diff --git a/src/calf/main_win.h b/src/calf/main_win.h
new file mode 100644
index 0000000..a6303fa
--- /dev/null
+++ b/src/calf/main_win.h
@@ -0,0 +1,81 @@
+/* Calf DSP Library Utility Application - calfjackhost
+ * GUI - main window
+ *
+ * Copyright (C) 2007 Krzysztof Foltman
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __CALF_MAIN_WIN_H
+#define __CALF_MAIN_WIN_H
+
+#include <expat.h>
+#include <map>
+#include <set>
+#include <vector>
+#include <gtk/gtk.h>
+#include <calf/gui.h>
+#include <calf/jackhost.h>
+#include "custom_ctl.h"
+
+namespace synth {
+
+ class main_window: public main_window_iface
+ {
+ public:
+ struct plugin_strip
+ {
+ main_window *main_win;
+ plugin_ctl_iface *plugin;
+ plugin_gui_window *gui_win;
+ GtkWidget *name, *midi_in, *audio_in[2], *audio_out[2];
+ };
+
+ public:
+ GtkWindow *toplevel;
+ GtkWidget *all_vbox;
+ GtkWidget *strips_table;
+ jack_client *client;
+ std::map<plugin_ctl_iface *, plugin_strip *> plugins;
+ std::set<std::string> conditions;
+ std::vector<plugin_ctl_iface *> plugin_queue;
+ std::string prefix;
+ bool is_closed;
+ int source_id;
+
+ protected:
+ plugin_strip *create_strip(plugin_ctl_iface *plugin);
+ void update_strip(plugin_ctl_iface *plugin);
+ static gboolean on_idle(void *data);
+
+ public:
+ main_window();
+ void add_plugin(plugin_ctl_iface *plugin);
+ void del_plugin(plugin_ctl_iface *plugin);
+ void set_window(plugin_ctl_iface *iface, plugin_gui_window *window);
+ void refresh_all_presets();
+ void refresh_plugin(plugin_ctl_iface *plugin);
+ void on_closed();
+ void close_guis();
+ void open_gui(plugin_ctl_iface *plugin);
+ bool check_condition(const char *cond) {
+ return conditions.count(cond) != 0;
+ }
+
+ void create();
+ };
+};
+
+#endif
diff --git a/src/calf/modules.h b/src/calf/modules.h
index 4b3b7fb..a9287cc 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -68,6 +68,8 @@ public:
}
return inputs_mask;
}
+ static const char *get_name() { return "amp"; }
+ static const char *get_id() { return "amp"; }
};
class flanger_audio_module: public null_audio_module
@@ -112,6 +114,8 @@ public:
right.process(outs[1] + offset, ins[1] + offset, nsamples);
return outputs_mask; // XXXKF allow some delay after input going blank
}
+ static const char *get_name() { return "flanger"; }
+ static const char *get_id() { return "flanger"; }
};
class reverb_audio_module: public null_audio_module
@@ -159,6 +163,8 @@ public:
reverb.extra_sanitize();
return outputs_mask;
}
+ static const char *get_name() { return "reverb"; }
+ static const char *get_id() { return "reverb"; }
};
class filter_audio_module: public null_audio_module
@@ -308,6 +314,8 @@ public:
}
return ostate;
}
+ static const char *get_id() { return "filter"; }
+ static const char *get_name() { return "filter"; }
};
class vintage_delay_audio_module: public null_audio_module
@@ -418,6 +426,8 @@ public:
}
return ostate;
}
+ static const char *get_name() { return "vintage_delay"; }
+ static const char *get_id() { return "vintagedelay"; }
};
extern std::string get_builtin_modules_rdf();
diff --git a/src/calf/modules_dev.h b/src/calf/modules_dev.h
index a9a8bb8..b3fc394 100644
--- a/src/calf/modules_dev.h
+++ b/src/calf/modules_dev.h
@@ -73,7 +73,8 @@ public:
render_to(o, nsamples);
return 3;
}
-
+ static const char *get_name() { return "organ"; }
+ static const char *get_id() { return "organ"; }
};
class rotary_speaker_audio_module: public null_audio_module
@@ -238,6 +239,8 @@ public:
return;
}
}
+ static const char *get_name() { return "rotary_speaker"; }
+ static const char *get_id() { return "rotaryspeaker"; }
};
};
diff --git a/src/calf/modules_synths.h b/src/calf/modules_synths.h
index c5cce96..2f67bec 100644
--- a/src/calf/modules_synths.h
+++ b/src/calf/modules_synths.h
@@ -182,6 +182,8 @@ public:
return 3;
}
+ static const char *get_name() { return "monosynth"; }
+ static const char *get_id() { return "monosynth"; }
};
};
diff --git a/src/custom_ctl.cpp b/src/custom_ctl.cpp
index f95d7ae..ebaa80d 100644
--- a/src/custom_ctl.cpp
+++ b/src/custom_ctl.cpp
@@ -155,7 +155,7 @@ calf_line_graph_get_type (void)
GTypeInfo *type_info_copy = new GTypeInfo(type_info);
for (int i = 0; ; i++) {
- char *name = g_strdup_printf("CalfLineGraph%d", i);
+ char *name = g_strdup_printf("CalfLineGraph%u%d", ((unsigned int)calf_line_graph_class_init) >> 16, i);
if (g_type_from_name(name)) {
free(name);
continue;
@@ -171,6 +171,147 @@ calf_line_graph_get_type (void)
return type;
}
+///////////////////////////////////////// vu meter ///////////////////////////////////////////////
+
+static gboolean
+calf_vumeter_expose (GtkWidget *widget, GdkEventExpose *event)
+{
+ g_assert(CALF_IS_VUMETER(widget));
+
+ CalfVUMeter *vu = CALF_VUMETER(widget);
+ int ox = widget->allocation.x + 1, oy = widget->allocation.y + 1;
+ int sx = widget->allocation.width - 2, sy = widget->allocation.height - 2;
+
+ cairo_t *c = gdk_cairo_create(GDK_DRAWABLE(widget->window));
+
+ GdkColor sc = { 0, 0, 0, 0 };
+ gdk_cairo_set_source_color(c, &sc);
+ cairo_rectangle(c, ox, oy, sx, sy);
+ cairo_fill(c);
+ cairo_set_line_width(c, 1);
+
+ for (int x = ox; x <= ox + sx; x += 3)
+ {
+ float ts = (x - ox) * 1.0 / sx;
+ int is = vu->value > ts ? 2 : 1;
+ float r, g, b;
+ if (ts < 0.75)
+ r = ts / 0.75, g = 1, b = 0;
+ else
+ r = 1, g = 1 - (ts - 0.75) / 0.25, b = 0;
+ if (vu->value < ts || vu->value <= 0)
+ r *= 0.5, g *= 0.5, b *= 0.5;
+ GdkColor sc2 = { 0, 65535 * r, 65535 * g, 65535 * b };
+ gdk_cairo_set_source_color(c, &sc2);
+ cairo_move_to(c, x, oy);
+ cairo_line_to(c, x, oy + sy + 1);
+ cairo_move_to(c, x, oy + sy);
+ cairo_line_to(c, x, oy );
+ cairo_stroke(c);
+ }
+
+ cairo_destroy(c);
+
+ gtk_paint_shadow(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, widget, NULL, ox - 1, oy - 1, sx + 2, sy + 2);
+ // printf("exposed %p %d+%d\n", widget->window, widget->allocation.x, widget->allocation.y);
+
+ return TRUE;
+}
+
+static void
+calf_vumeter_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ g_assert(CALF_IS_VUMETER(widget));
+
+ requisition->width = 50;
+ requisition->height = 14;
+}
+
+static void
+calf_vumeter_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ g_assert(CALF_IS_VUMETER(widget));
+
+ widget->allocation = *allocation;
+}
+
+static void
+calf_vumeter_class_init (CalfVUMeterClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ widget_class->expose_event = calf_vumeter_expose;
+ widget_class->size_request = calf_vumeter_size_request;
+ widget_class->size_allocate = calf_vumeter_size_allocate;
+}
+
+static void
+calf_vumeter_init (CalfVUMeter *self)
+{
+ GtkWidget *widget = GTK_WIDGET(self);
+ GTK_WIDGET_SET_FLAGS (widget, GTK_NO_WINDOW);
+ widget->requisition.width = 40;
+ widget->requisition.height = 40;
+ self->value = 0.5;
+}
+
+GtkWidget *
+calf_vumeter_new()
+{
+ return GTK_WIDGET( g_object_new (CALF_TYPE_VUMETER, NULL ));
+}
+
+GType
+calf_vumeter_get_type (void)
+{
+ static GType type = 0;
+ if (!type) {
+ static const GTypeInfo type_info = {
+ sizeof(CalfVUMeterClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc)calf_vumeter_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(CalfVUMeter),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc)calf_vumeter_init
+ };
+
+ GTypeInfo *type_info_copy = new GTypeInfo(type_info);
+
+ for (int i = 0; ; i++) {
+ char *name = g_strdup_printf("CalfVUMeter%u%d", ((unsigned int)calf_vumeter_class_init) >> 16, i);
+ if (g_type_from_name(name)) {
+ free(name);
+ continue;
+ }
+ type = g_type_register_static( GTK_TYPE_WIDGET,
+ name,
+ type_info_copy,
+ (GTypeFlags)0);
+ free(name);
+ break;
+ }
+ }
+ return type;
+}
+
+extern void calf_vumeter_set_value(CalfVUMeter *meter, float value)
+{
+ if (value != meter->value)
+ {
+ meter->value = value;
+ gtk_widget_queue_draw(GTK_WIDGET(meter));
+ }
+}
+
+extern float calf_vumeter_get_value(CalfVUMeter *meter)
+{
+ return meter->value;
+}
+
///////////////////////////////////////// knob ///////////////////////////////////////////////
static gboolean
@@ -386,7 +527,8 @@ calf_knob_get_type (void)
};
for (int i = 0; ; i++) {
- char *name = g_strdup_printf("CalfKnob%d", i);
+ char *name = g_strdup_printf("CalfKnob%u%d",
+ ((unsigned int)calf_knob_class_init) >> 16, i);
if (g_type_from_name(name)) {
free(name);
continue;
diff --git a/src/dssigui.cpp b/src/dssigui.cpp
index 70f2113..d249015 100644
--- a/src/dssigui.cpp
+++ b/src/dssigui.cpp
@@ -26,6 +26,7 @@
#include <calf/modules.h>
#include <calf/modules_dev.h>
#include <calf/benchmark.h>
+#include <calf/main_win.h>
using namespace std;
using namespace dsp;
@@ -132,6 +133,18 @@ struct plugin_proxy: public plugin_proxy_base, public line_graph_iface
virtual bool get_graph(int index, int subindex, float *data, int points, cairo_t *context) {
return Module::get_static_graph(index, subindex, params[index], data, points, context);
}
+ virtual const char *get_name()
+ {
+ return Module::get_name();
+ }
+ virtual const char *get_id()
+ {
+ return Module::get_id();
+ }
+ virtual int get_input_count() { return Module::in_count; }
+ virtual int get_output_count() { return Module::out_count; }
+ virtual bool get_midi() { return Module::support_midi; }
+ virtual float get_level(int port) { return 0.f; }
};
plugin_proxy_base *create_plugin_proxy(const char *effect_name)
@@ -175,7 +188,8 @@ static bool osc_debug = false;
struct dssi_osc_server: public osc_server, public osc_message_sink
{
plugin_proxy_base *plugin;
- plugin_gui_window window;
+ main_window *main_win;
+ plugin_gui_window *window;
string effect_name, title;
osc_client cli;
bool in_program, enable_dump;
@@ -183,6 +197,8 @@ struct dssi_osc_server: public osc_server, public osc_message_sink
dssi_osc_server()
: plugin(NULL)
+ , main_win(new main_window)
+ , window(new plugin_gui_window(main_win))
{
sink = this;
}
@@ -202,10 +218,10 @@ struct dssi_osc_server: public osc_server, public osc_message_sink
plugin = create_plugin_proxy(effect_name.c_str());
plugin->client = &cli;
plugin->send_osc = true;
- window.conditions.insert("dssi");
- window.create(plugin, title.c_str(), effect_name.c_str());
- plugin->gui = window.gui;
- gtk_signal_connect(GTK_OBJECT(window.toplevel), "destroy", G_CALLBACK(on_destroy), this);
+ ((main_window *)window->main)->conditions.insert("dssi");
+ window->create(plugin, title.c_str(), effect_name.c_str());
+ plugin->gui = window->gui;
+ gtk_signal_connect(GTK_OBJECT(window->toplevel), "destroy", G_CALLBACK(on_destroy), this);
global_presets.get_for_plugin(presets, effect_name.c_str());
}
@@ -236,7 +252,7 @@ struct dssi_osc_server: public osc_server, public osc_message_sink
for (int i =0 ; i < count; i++)
plugin->set_param_value(i, plugin->get_param_props(i)->def_value);
plugin->send_osc = sosc;
- window.gui->refresh();
+ window->gui->refresh();
// special handling for default preset
return;
}
@@ -247,7 +263,7 @@ struct dssi_osc_server: public osc_server, public osc_message_sink
plugin->send_osc = false;
presets[nr].activate(plugin);
plugin->send_osc = sosc;
- window.gui->refresh();
+ window->gui->refresh();
// cli.send("/update", data);
return;
@@ -259,18 +275,18 @@ struct dssi_osc_server: public osc_server, public osc_message_sink
debug_printf("CONTROL %d %f\n", idx, val);
bool sosc = plugin->send_osc;
plugin->send_osc = false;
- window.gui->set_param_value(idx, val);
+ window->gui->set_param_value(idx, val);
plugin->send_osc = sosc;
return;
}
if (address == prefix + "/show")
{
- gtk_widget_show_all(GTK_WIDGET(window.toplevel));
+ gtk_widget_show_all(GTK_WIDGET(window->toplevel));
return;
}
if (address == prefix + "/hide")
{
- gtk_widget_hide(GTK_WIDGET(window.toplevel));
+ gtk_widget_hide(GTK_WIDGET(window->toplevel));
return;
}
}
diff --git a/src/gui.cpp b/src/gui.cpp
index 232a9b7..cbf13d1 100644
--- a/src/gui.cpp
+++ b/src/gui.cpp
@@ -19,10 +19,12 @@
*/
#include <config.h>
+#include <assert.h>
#include <calf/giface.h>
#include <calf/gui.h>
#include <calf/preset.h>
#include <calf/preset_gui.h>
+#include <calf/main_win.h>
using namespace synth;
using namespace std;
@@ -49,6 +51,14 @@ void param_control::hook_params()
gui->add_param_ctl(param_no, this);
}
+param_control::~param_control()
+{
+ if (label)
+ gtk_widget_destroy(label);
+ if (widget)
+ gtk_widget_destroy(widget);
+}
+
// combo box
GtkWidget *combo_box_param_control::create(plugin_gui *_gui, int _param_no)
@@ -290,11 +300,10 @@ void knob_param_control::knob_value_changed(GtkWidget *widget, gpointer value)
// line graph
-gboolean line_graph_param_control::update(void *data)
+void line_graph_param_control::on_idle()
{
- line_graph_param_control *self = (line_graph_param_control *)data;
- self->set();
- return TRUE;
+ if (get_int("refresh", 0))
+ set();
}
GtkWidget *line_graph_param_control::create(plugin_gui *_gui, int _param_no)
@@ -309,10 +318,7 @@ GtkWidget *line_graph_param_control::create(plugin_gui *_gui, int _param_no)
widget->requisition.height = get_int("height", 40);
clg->source = gui->plugin->get_line_graph_iface();
clg->source_id = param_no;
-
- if (get_int("refresh", 0))
- source_id = g_timeout_add_full(G_PRIORITY_LOW, 1000/30, update, this, NULL); // 30 fps should be enough for everybody
-
+
return widget;
}
@@ -330,8 +336,6 @@ void line_graph_param_control::set()
line_graph_param_control::~line_graph_param_control()
{
- if (get_int("refresh", 0))
- g_source_remove(source_id);
}
/******************************** GUI proper ********************************/
@@ -342,6 +346,11 @@ plugin_gui::plugin_gui(plugin_gui_window *_window)
}
+static void window_destroyed(GtkWidget *window, gpointer data)
+{
+ delete (plugin_gui_window *)data;
+}
+
static void action_destroy_notify(gpointer data)
{
delete (activate_preset_params *)data;
@@ -571,12 +580,12 @@ void plugin_gui::xml_element_start(const char *element, const char *attributes[]
if (!xam.count("cond") || xam["cond"].empty())
g_error("Incorrect <if cond=\"[!]symbol\"> element");
string cond = xam["cond"];
- unsigned int exp_count = 1;
+ bool state = true;
if (cond.substr(0, 1) == "!") {
- exp_count = 0;
+ state = false;
cond.erase(0, 1);
}
- if (window->conditions.count(cond) == exp_count)
+ if (window->main->check_condition(cond.c_str()) == state)
return;
ignore_stack = 1;
return;
@@ -667,6 +676,15 @@ GtkWidget *plugin_gui::create_from_xml(plugin_ctl_iface *_plugin, const char *xm
return GTK_WIDGET(top_container->container);
}
+void plugin_gui::on_idle()
+{
+ for (unsigned int i = 0; i < params.size(); i++)
+ {
+ if (params[i] != NULL)
+ params[i]->on_idle();
+ }
+}
+
void plugin_gui::refresh()
{
for (unsigned int i = 0; i < params.size(); i++)
@@ -693,6 +711,14 @@ void plugin_gui::set_param_value(int param_no, float value, param_control *origi
refresh(param_no);
}
+plugin_gui::~plugin_gui()
+{
+ for (std::vector<param_control *>::iterator i = params.begin(); i != params.end(); i++)
+ {
+ delete *i;
+ }
+}
+
/******************************* Actions **************************************************/
@@ -701,14 +727,7 @@ static void store_preset_action(GtkAction *action, plugin_gui_window *gui_win)
store_preset(GTK_WINDOW(gui_win->toplevel), gui_win->gui);
}
-static void exit_gui(GtkAction *action, plugin_gui_window *gui_win)
-{
- gtk_widget_destroy(GTK_WIDGET(gui_win->toplevel));
-}
-
static const GtkActionEntry actions[] = {
- { "HostMenuAction", "", "_Host", NULL, "Application-wide actions", NULL },
- { "exit", "", "E_xit", NULL, "Exit the application", (GCallback)exit_gui },
{ "PresetMenuAction", "", "_Preset", NULL, "Preset operations", NULL },
{ "store-preset", "", "_Store preset", NULL, "Store a current setting as preset", (GCallback)store_preset_action },
};
@@ -718,9 +737,6 @@ static const GtkActionEntry actions[] = {
static const char *ui_xml =
"<ui>\n"
" <menubar>\n"
-" <menu action=\"HostMenuAction\">\n"
-" <menuitem action=\"exit\"/>\n"
-" </menu>\n"
" <menu action=\"PresetMenuAction\">\n"
" <menuitem action=\"store-preset\"/>\n"
" <separator/>\n"
@@ -743,12 +759,14 @@ static const char *preset_post_xml =
"</ui>\n"
;
-plugin_gui_window::plugin_gui_window()
+plugin_gui_window::plugin_gui_window(main_window_iface *_main)
{
toplevel = NULL;
ui_mgr = NULL;
std_actions = NULL;
preset_actions = NULL;
+ main = _main;
+ assert(main);
}
string plugin_gui_window::make_gui_preset_list(GtkActionGroup *grp)
@@ -784,6 +802,13 @@ void plugin_gui_window::fill_gui_presets()
gtk_ui_manager_add_ui_from_string(ui_mgr, preset_xml.c_str(), -1, &error);
}
+gboolean plugin_gui_window::on_idle(void *data)
+{
+ plugin_gui_window *self = (plugin_gui_window *)data;
+ self->gui->on_idle();
+ return TRUE;
+}
+
void plugin_gui_window::create(plugin_ctl_iface *_jh, const char *title, const char *effect)
{
toplevel = GTK_WINDOW(gtk_window_new (GTK_WINDOW_TOPLEVEL));
@@ -836,20 +861,25 @@ void plugin_gui_window::create(plugin_ctl_iface *_jh, const char *title, const c
//gtk_widget_set_size_request(GTK_WIDGET(toplevel), max(req.width + 10, req2.width), req.height + req2.height + 10);
// printf("size set %dx%d\n", wx, wy);
// gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(sw), GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, req.height, 20, 100, 100)));
- all_windows.insert(this);
+ gtk_signal_connect (GTK_OBJECT (toplevel), "destroy", G_CALLBACK (window_destroyed), (plugin_gui_window *)this);
+ main->set_window(gui->plugin, this);
+ source_id = g_timeout_add_full(G_PRIORITY_LOW, 1000/30, on_idle, this, NULL); // 30 fps should be enough for everybody
}
-plugin_gui_window::~plugin_gui_window()
+void plugin_gui_window::close()
{
- all_windows.erase(this);
- delete gui;
+ if (source_id)
+ g_source_remove(source_id);
+ source_id = 0;
+ gtk_widget_destroy(GTK_WIDGET(toplevel));
}
-std::set<plugin_gui_window *> plugin_gui_window::all_windows;
-
-void plugin_gui_window::refresh_all_presets()
+plugin_gui_window::~plugin_gui_window()
{
- for (std::set<plugin_gui_window *>::iterator i = all_windows.begin(); i != all_windows.end(); i++)
- (*i)->fill_gui_presets();
+ if (source_id)
+ g_source_remove(source_id);
+ main->set_window(gui->plugin, NULL);
+ delete gui;
}
+
diff --git a/src/jackhost.cpp b/src/jackhost.cpp
index b697541..69d0d8a 100644
--- a/src/jackhost.cpp
+++ b/src/jackhost.cpp
@@ -34,6 +34,7 @@
#include <calf/gui.h>
#include <calf/preset.h>
#include <calf/preset_gui.h>
+#include <calf/main_win.h>
using namespace synth;
using namespace std;
@@ -70,6 +71,10 @@ void destroy(GtkWindow *window, gpointer data)
gtk_main_quit();
}
+void gui_win_destroy(GtkWindow *window, gpointer data)
+{
+}
+
static struct option long_options[] = {
{"help", 0, 0, 'h'},
{"version", 0, 0, 'v'},
@@ -121,7 +126,7 @@ struct host_session
string autoconnect_midi;
set<int> chains;
vector<jack_host_base *> plugins;
- vector<plugin_gui_window *> guis;
+ main_window *main_win;
int lash_source_id;
bool restoring_session;
@@ -131,6 +136,7 @@ struct host_session
void close();
static gboolean update_lash(void *self) { ((host_session *)self)->update_lash(); return TRUE; }
void update_lash();
+ void activate_preset(int plugin, const std::string &preset);
#if USE_LASH
void send_lash(LASH_Event_Type type, const std::string &data) {
lash_send_event(lash_client, lash_event_new_with_all(type, data.c_str()));
@@ -152,6 +158,7 @@ host_session::host_session()
lash_args = NULL;
lash_source_id = 0;
restoring_session = false;
+ main_win = new main_window;
}
void host_session::open()
@@ -160,6 +167,9 @@ void host_session::open()
if (!output_name.empty()) client.output_name = output_name;
if (!midi_name.empty()) client.midi_name = midi_name;
client.open(client_name.c_str());
+ main_win->prefix = client_name + " - ";
+ main_win->conditions.insert("jackhost");
+ main_win->conditions.insert("directlink");
for (unsigned int i = 0; i < plugin_names.size(); i++) {
// if (presets.count(i))
// printf("%s : %s\n", names[i].c_str(), presets[i].c_str());
@@ -172,34 +182,33 @@ void host_session::open()
#endif
}
jh->open(&client);
- gui_win = new plugin_gui_window;
- gui_win->conditions.insert("jackhost");
- gui_win->conditions.insert("directlink");
- gui_win->create(jh, (string(client_name)+" - "+plugin_names[i]).c_str(), plugin_names[i].c_str());
- gtk_signal_connect(GTK_OBJECT(gui_win->toplevel), "destroy", G_CALLBACK(destroy), NULL);
- gtk_widget_show_all(GTK_WIDGET(gui_win->toplevel));
- guis.push_back(gui_win);
plugins.push_back(jh);
client.add(jh);
- if (presets.count(i)) {
- string cur_plugin = plugin_names[i];
- string preset = presets[i];
- preset_vector &pvec = global_presets.presets;
- bool found = false;
- for (unsigned int i = 0; i < pvec.size(); i++) {
- if (pvec[i].name == preset && pvec[i].plugin == cur_plugin)
- {
- pvec[i].activate(jh);
- gui_win->gui->refresh();
- found = true;
- break;
- }
- }
- if (!found) {
- fprintf(stderr, "Warning: unknown preset %s %s\n", preset.c_str(), cur_plugin.c_str());
- }
+ main_win->add_plugin(jh);
+ if (presets.count(i))
+ activate_preset(i, presets[i]);
+ }
+ main_win->create();
+ gtk_signal_connect(GTK_OBJECT(main_win->toplevel), "destroy", G_CALLBACK(destroy), NULL);
+}
+
+void host_session::activate_preset(int i, const std::string &preset)
+{
+ string cur_plugin = plugin_names[i];
+ preset_vector &pvec = global_presets.presets;
+ bool found = false;
+ for (unsigned int i = 0; i < pvec.size(); i++) {
+ if (pvec[i].name == preset && pvec[i].plugin == cur_plugin)
+ {
+ pvec[i].activate(plugins[i]);
+ gui_win->gui->refresh();
+ found = true;
+ break;
}
}
+ if (!found) {
+ fprintf(stderr, "Warning: unknown preset %s %s\n", preset.c_str(), cur_plugin.c_str());
+ }
}
void host_session::connect()
@@ -268,8 +277,9 @@ void host_session::close()
g_source_remove(lash_source_id);
client.deactivate();
client.close();
+ main_win->on_closed();
+ main_win->close_guis();
for (unsigned int i = 0; i < plugin_names.size(); i++) {
- delete guis[i];
plugins[i]->close();
delete plugins[i];
}
@@ -320,7 +330,7 @@ void host_session::update_lash()
if (tmp.presets.size())
{
tmp.presets[0].activate(plugins[nplugin]);
- guis[nplugin]->gui->refresh();
+ main_win->refresh_plugin(plugins[nplugin]);
}
}
}
diff --git a/src/lv2gui.cpp b/src/lv2gui.cpp
index e0c315c..6304fcd 100644
--- a/src/lv2gui.cpp
+++ b/src/lv2gui.cpp
@@ -23,6 +23,7 @@
#include <config.h>
#include <calf/giface.h>
#include <calf/gui.h>
+#include <calf/main_win.h>
#include <calf/modules.h>
#include <calf/modules_dev.h>
#include <calf/benchmark.h>
@@ -84,24 +85,42 @@ struct plugin_proxy: public plugin_proxy_base, public line_graph_iface
send = true;
}
}
- virtual int get_param_count() {
+ virtual int get_param_count()
+ {
return Module::param_count;
}
- virtual int get_param_port_offset() {
+ virtual int get_param_port_offset()
+ {
return Module::in_count + Module::out_count;
}
- virtual const char *get_gui_xml() {
+ virtual const char *get_gui_xml()
+ {
return Module::get_gui_xml();
}
- virtual line_graph_iface *get_line_graph_iface() {
+ virtual line_graph_iface *get_line_graph_iface()
+ {
return this;
}
- virtual bool activate_preset(int bank, int program) {
+ virtual bool activate_preset(int bank, int program)
+ {
return false;
}
- virtual bool get_graph(int index, int subindex, float *data, int points, cairo_t *context) {
+ virtual bool get_graph(int index, int subindex, float *data, int points, cairo_t *context)
+ {
return Module::get_static_graph(index, subindex, params[index], data, points, context);
}
+ virtual const char *get_name()
+ {
+ return Module::get_name();
+ }
+ virtual const char *get_id()
+ {
+ return Module::get_id();
+ }
+ virtual int get_input_count() { return Module::in_count; }
+ virtual int get_output_count() { return Module::out_count; }
+ virtual bool get_midi() { return Module::support_midi; }
+ virtual float get_level(int port) { return 0.f; }
};
plugin_proxy_base *create_plugin_proxy(const char *effect_name)
@@ -140,8 +159,9 @@ LV2UI_Handle gui_instantiate(const struct _LV2UI_Descriptor* descriptor,
plugin_proxy_base *proxy = create_plugin_proxy(plugin_uri + sizeof("http://calf.sourceforge.net/plugins/") - 1);
proxy->setup(write_function, controller);
// dummy window
- plugin_gui_window *window = new plugin_gui_window;
- window->conditions.insert("lv2gui");
+ main_window *main = new main_window;
+ main->conditions.insert("lv2gui");
+ plugin_gui_window *window = new plugin_gui_window(main);
plugin_gui *gui = new plugin_gui(window);
const char *xml = proxy->get_gui_xml();
if (xml)
diff --git a/src/main_win.cpp b/src/main_win.cpp
new file mode 100644
index 0000000..70a6cf1
--- /dev/null
+++ b/src/main_win.cpp
@@ -0,0 +1,233 @@
+/* Calf DSP Library
+ * GUI main window.
+ * Copyright (C) 2007 Krzysztof Foltman
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <config.h>
+#include <calf/giface.h>
+#include <calf/gui.h>
+#include <calf/preset.h>
+#include <calf/preset_gui.h>
+#include <calf/main_win.h>
+
+using namespace synth;
+using namespace std;
+
+main_window::main_window()
+{
+ toplevel = NULL;
+ is_closed = true;
+}
+
+void main_window::add_plugin(plugin_ctl_iface *plugin)
+{
+ if (toplevel)
+ {
+ plugins[plugin] = create_strip(plugin);
+ }
+ else {
+ plugin_queue.push_back(plugin);
+ plugins[plugin] = NULL;
+ }
+}
+
+void main_window::del_plugin(plugin_ctl_iface *plugin)
+{
+ plugins.erase(plugin);
+}
+
+void main_window::set_window(plugin_ctl_iface *plugin, plugin_gui_window *gui_win)
+{
+ if (!plugins.count(plugin))
+ return;
+ plugin_strip *strip = plugins[plugin];
+ if (!strip)
+ return;
+ strip->gui_win = gui_win;
+ if (!is_closed)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(strip->name), gui_win != NULL);
+}
+
+void main_window::refresh_all_presets()
+{
+ for (std::map<plugin_ctl_iface *, plugin_strip *>::iterator i = plugins.begin(); i != plugins.end(); i++)
+ {
+ if (i->second && i->second->gui_win)
+ i->second->gui_win->fill_gui_presets();
+ }
+}
+
+static gboolean
+gui_button_pressed(GtkWidget *button, main_window::plugin_strip *strip)
+{
+ GtkToggleButton *tb = GTK_TOGGLE_BUTTON(button);
+ if ((gtk_toggle_button_get_active(tb) != 0) == (strip->gui_win != NULL))
+ return FALSE;
+ if (strip->gui_win) {
+ strip->gui_win->close();
+ strip->gui_win = NULL;
+ } else {
+ strip->main_win->open_gui(strip->plugin);
+ }
+ return TRUE;
+}
+
+main_window::plugin_strip *main_window::create_strip(plugin_ctl_iface *plugin)
+{
+ plugin_strip *strip = new plugin_strip;
+ strip->main_win = this;
+ strip->plugin = plugin;
+ strip->gui_win = NULL;
+
+ int row = 0, cols = 0;
+ g_object_get(G_OBJECT(strips_table), "n-rows", &row, "n-columns", &cols, NULL);
+ gtk_table_resize(GTK_TABLE(strips_table), row + 3, cols);
+
+ gtk_table_attach_defaults(GTK_TABLE(strips_table), gtk_hseparator_new(), 0, 4, row, row + 1);
+ row++;
+
+ GtkWidget *label = gtk_toggle_button_new_with_label(plugin->get_name());
+ gtk_table_attach_defaults(GTK_TABLE(strips_table), label, 0, 1, row, row + 2);
+ strip->name = label;
+ gtk_signal_connect(GTK_OBJECT(label), "toggled", G_CALLBACK(gui_button_pressed),
+ (plugin_ctl_iface *)strip);
+
+ label = gtk_label_new(plugin->get_midi() ? "MIDI" : "");
+ gtk_table_attach_defaults(GTK_TABLE(strips_table), label, 1, 2, row, row + 2);
+ strip->midi_in = label;
+
+ for (int i = 0; i < 2; i++)
+ strip->audio_in[i] = strip->audio_out[i] = NULL;
+
+ if (plugin->get_input_count() == 2) {
+ label = calf_vumeter_new();
+ gtk_table_attach_defaults(GTK_TABLE(strips_table), label, 2, 3, row, row + 1);
+ strip->audio_in[0] = label;
+ label = calf_vumeter_new();
+ gtk_table_attach_defaults(GTK_TABLE(strips_table), label, 2, 3, row + 1, row + 2);
+ strip->audio_in[1] = label;
+ }
+
+ if (plugin->get_output_count() == 2) {
+ label = calf_vumeter_new();
+ gtk_table_attach_defaults(GTK_TABLE(strips_table), label, 3, 4, row, row + 1);
+ strip->audio_out[0] = label;
+ label = calf_vumeter_new();
+ gtk_table_attach_defaults(GTK_TABLE(strips_table), label, 3, 4, row + 1, row + 2);
+ strip->audio_out[1] = label;
+ }
+ return strip;
+}
+
+void main_window::update_strip(plugin_ctl_iface *plugin)
+{
+ // plugin_strip *strip = plugins[plugin];
+ // assert(strip);
+
+}
+
+void main_window::open_gui(plugin_ctl_iface *plugin)
+{
+ plugin_gui_window *gui_win = new plugin_gui_window(this);
+ gui_win->create(plugin, (prefix + plugin->get_name()).c_str(), plugin->get_id());
+ gtk_widget_show_all(GTK_WIDGET(gui_win->toplevel));
+ plugins[plugin]->gui_win = gui_win;
+}
+
+void main_window::create()
+{
+ toplevel = GTK_WINDOW(gtk_window_new (GTK_WINDOW_TOPLEVEL));
+ is_closed = false;
+
+ all_vbox = gtk_vbox_new(0, FALSE);
+ strips_table = gtk_table_new(1, 5, FALSE);
+ gtk_table_set_col_spacings(GTK_TABLE(strips_table), 10);
+ gtk_table_set_row_spacings(GTK_TABLE(strips_table), 5);
+
+ gtk_table_attach_defaults(GTK_TABLE(strips_table), gtk_label_new("Module"), 0, 1, 0, 1);
+ gtk_table_attach_defaults(GTK_TABLE(strips_table), gtk_label_new("MIDI In"), 1, 2, 0, 1);
+ gtk_table_attach_defaults(GTK_TABLE(strips_table), gtk_label_new("Audio In"), 2, 3, 0, 1);
+ gtk_table_attach_defaults(GTK_TABLE(strips_table), gtk_label_new("Audio Out"), 3, 4, 0, 1);
+ for (std::vector<plugin_ctl_iface *>::iterator i = plugin_queue.begin(); i != plugin_queue.end(); i++)
+ {
+ plugins[*i] = create_strip(*i);
+ update_strip(*i);
+ }
+
+ gtk_container_add(GTK_CONTAINER(all_vbox), strips_table);
+ gtk_container_add(GTK_CONTAINER(toplevel), all_vbox);
+
+ gtk_widget_show_all(GTK_WIDGET(toplevel));
+ source_id = g_timeout_add_full(G_PRIORITY_LOW, 1000/30, on_idle, this, NULL); // 30 fps should be enough for everybody
+}
+
+void main_window::refresh_plugin(plugin_ctl_iface *plugin)
+{
+ plugins[plugin]->gui_win->gui->refresh();
+}
+
+void main_window::close_guis()
+{
+ for (std::map<plugin_ctl_iface *, plugin_strip *>::iterator i = plugins.begin(); i != plugins.end(); i++)
+ {
+ if (i->second && i->second->gui_win) {
+ i->second->gui_win->close();
+ }
+ }
+ plugins.clear();
+}
+
+void main_window::on_closed()
+{
+ if (source_id)
+ g_source_remove(source_id);
+ is_closed = true;
+ toplevel = NULL;
+}
+
+static inline float LVL(float value)
+{
+ return sqrt(value) * 0.75;
+}
+
+gboolean main_window::on_idle(void *data)
+{
+ main_window *self = (main_window *)data;
+ for (std::map<plugin_ctl_iface *, plugin_strip *>::iterator i = self->plugins.begin(); i != self->plugins.end(); i++)
+ {
+ if (i->second)
+ {
+ plugin_ctl_iface *plugin = i->first;
+ plugin_strip *strip = i->second;
+ int idx = 0;
+ if (plugin->get_input_count() == 2) {
+ calf_vumeter_set_value(CALF_VUMETER(strip->audio_in[0]), LVL(plugin->get_level(idx++)));
+ calf_vumeter_set_value(CALF_VUMETER(strip->audio_in[1]), LVL(plugin->get_level(idx++)));
+ }
+ if (plugin->get_output_count() == 2) {
+ calf_vumeter_set_value(CALF_VUMETER(strip->audio_out[0]), LVL(plugin->get_level(idx++)));
+ calf_vumeter_set_value(CALF_VUMETER(strip->audio_out[1]), LVL(plugin->get_level(idx++)));
+ }
+ if (plugin->get_midi()) {
+ gtk_label_set_text(GTK_LABEL(strip->midi_in), (plugin->get_level(idx++) > 0.f) ? "*" : "");
+ }
+ }
+ }
+ return TRUE;
+}
diff --git a/src/preset_gui.cpp b/src/preset_gui.cpp
index 62a23bc..d63a727 100644
--- a/src/preset_gui.cpp
+++ b/src/preset_gui.cpp
@@ -24,6 +24,7 @@
#include <calf/gui.h>
#include <calf/preset.h>
#include <calf/preset_gui.h>
+#include <calf/main_win.h>
using namespace synth;
using namespace std;
@@ -58,7 +59,7 @@ void store_preset_ok(GtkAction *action, plugin_gui *gui)
global_presets = tmp;
global_presets.save(tmp.get_preset_filename().c_str());
gtk_widget_destroy(store_preset_dlg);
- plugin_gui_window::refresh_all_presets();
+ gui->window->main->refresh_all_presets();
}
void store_preset_cancel(GtkAction *action, plugin_gui *gui)
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list