[SCM] calf/master: + Rotary Speaker: temporarily half broken, work in progress (use Organ's vibrato in the meantime), committed to get it out of the way + GUI: added the ability for plugins to define parameterless/GUIless commands + Organ: added panic command (resets all controllers and releases all sounds)
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:37:12 UTC 2013
The following commit has been merged in the master branch:
commit e657f9b90edb8148e409fec71bfb2662fb260126
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date: Mon May 5 21:41:57 2008 +0000
+ Rotary Speaker: temporarily half broken, work in progress (use Organ's vibrato in the meantime), committed to get it out of the way
+ GUI: added the ability for plugins to define parameterless/GUIless commands
+ Organ: added panic command (resets all controllers and releases all sounds)
git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@170 78b06b96-2940-0410-b7fc-879d825d01d8
diff --git a/src/calf/giface.h b/src/calf/giface.h
index 5598af8..6d95d09 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -92,6 +92,15 @@ enum parameter_flags
PF_UNIT_NOTE = 0x0A000000,
};
+class null_audio_module;
+
+struct plugin_command_info
+{
+ const char *label;
+ const char *name;
+ const char *description;
+};
+
struct parameter_properties
{
float def_value, min, max, step;
@@ -111,6 +120,8 @@ struct line_graph_iface
virtual ~line_graph_iface() {}
};
+struct plugin_command_info;
+
struct plugin_ctl_iface
{
virtual parameter_properties *get_param_props(int param_no) = 0;
@@ -129,6 +140,8 @@ struct plugin_ctl_iface
virtual bool get_midi()=0;
virtual float get_level(int port)=0;
virtual ~plugin_ctl_iface() {}
+ virtual plugin_command_info *get_commands() { return NULL; }
+ virtual void execute(int cmd_no)=0;
};
struct midi_event {
@@ -222,6 +235,9 @@ struct ladspa_instance: public Module, public plugin_ctl_iface
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; }
+ virtual void execute(int cmd_no) {
+ Module::execute(cmd_no);
+ }
};
template<class Module>
@@ -454,9 +470,14 @@ struct ladspa_wrapper
const char *Key,
const char *Value)
{
- // XXXKF some day...
- // Module *const mod = (Module *)Instance;
- // return mod->configure(Key, Value);
+ instance *const mod = (instance *)Instance;
+ if (!strcmp(Key, "ExecCommand"))
+ {
+ if (*Value)
+ {
+ mod->execute(atoi(Value));
+ }
+ }
return NULL;
}
diff --git a/src/calf/gui.h b/src/calf/gui.h
index d0dbd44..021bc25 100644
--- a/src/calf/gui.h
+++ b/src/calf/gui.h
@@ -274,12 +274,13 @@ public:
plugin_gui *gui;
GtkWindow *toplevel;
GtkUIManager *ui_mgr;
- GtkActionGroup *std_actions, *preset_actions;
+ GtkActionGroup *std_actions, *preset_actions, *command_actions;
main_window_iface *main;
int source_id;
plugin_gui_window(main_window_iface *_main);
std::string make_gui_preset_list(GtkActionGroup *grp);
+ std::string make_gui_command_list(GtkActionGroup *grp);
void fill_gui_presets();
void create(plugin_ctl_iface *_plugin, const char *title, const char *effect);
void close();
@@ -293,6 +294,22 @@ inline parameter_properties ¶m_control::get_props()
return *gui->plugin->get_param_props(param_no);
}
+class null_audio_module;
+
+struct activate_command_params
+{
+ typedef void (*CommandFunc)(null_audio_module *);
+ plugin_gui *gui;
+ int function_idx;
+
+ activate_command_params(plugin_gui *_gui, int _idx)
+ : gui(_gui), function_idx(_idx)
+ {
+ }
+};
+
+void activate_command(GtkAction *action, activate_command_params *params);
+
};
#endif
diff --git a/src/calf/jackhost.h b/src/calf/jackhost.h
index 7bd765c..b9b022c 100644
--- a/src/calf/jackhost.h
+++ b/src/calf/jackhost.h
@@ -408,6 +408,12 @@ public:
{
return Module::get_label();
}
+ virtual plugin_command_info *get_commands() {
+ return Module::get_commands();
+ }
+ virtual void execute(int cmd_no) {
+ module.execute(cmd_no);
+ }
};
extern jack_host_base *create_jack_host(const char *name);
diff --git a/src/calf/lv2wrap.h b/src/calf/lv2wrap.h
index d324f0d..d78dd23 100644
--- a/src/calf/lv2wrap.h
+++ b/src/calf/lv2wrap.h
@@ -80,6 +80,9 @@ struct lv2_instance: public Module, public plugin_ctl_iface
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; }
+ virtual void execute(int cmd_no) {
+ Module::execute(cmd_no);
+ }
};
template<class Module>
diff --git a/src/calf/modules.h b/src/calf/modules.h
index 524cbaa..593bd52 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -25,11 +25,14 @@
#include "biquad.h"
#include "inertia.h"
#include "audio_fx.h"
+#include "giface.h"
namespace synth {
using namespace dsp;
+class null_audio_module;
+
class null_audio_module: public line_graph_iface
{
public:
@@ -46,6 +49,8 @@ public:
inline bool get_graph(int index, int subindex, float *data, int points, cairo_t *context) { return false; }
inline static const char *get_gui_xml() { return NULL; }
inline static bool get_static_graph(int index, int subindex, float value, float *data, int points, cairo_t *context) { return false; }
+ inline static plugin_command_info *get_commands() { return NULL; }
+ inline void execute(int cmd_no) {}
};
class amp_audio_module: public null_audio_module
@@ -538,7 +543,7 @@ public:
class rotary_speaker_audio_module: public null_audio_module
{
public:
- enum { par_speed, param_count };
+ enum { par_speed, par_spacing, par_shift, param_count };
enum { in_count = 2, out_count = 2, support_midi = true, rt_capable = true };
static const char *port_names[];
float *ins[in_count];
@@ -635,6 +640,8 @@ public:
long long int yl0 = (int)(10000*16384*sin(phase_l * 2 * PI));
long long int xh0 = (int)(10000*16384*cos(phase_h * 2 * PI));
long long int yh0 = (int)(10000*16384*sin(phase_h * 2 * PI));
+// int shift = 500000, pdelta = 150000;
+ int shift = (int)(300000 * (*params[par_shift])), pdelta = (int)(300000 * (*params[par_spacing]));
// printf("xl=%d yl=%d dx=%d dy=%d\n", (int)(xl0>>14), (int)(yl0 >> 14), cos_l, sin_l);
for (unsigned int i = 0; i < nsamples; i++) {
float in_l = ins[0][i + offset], in_r = ins[1][i + offset];
@@ -648,11 +655,11 @@ public:
// printf("xl=%d yl=%d xl'=%f yl'=%f\n", xl, yl, 16384*cos((phase_l + dphase_l * i) * 2 * PI), 16384*sin((phase_l + dphase_l * i) * 2 * PI));
update_euler(xh0, yh0, cos_h, sin_h);
- float out_hi_l = delay.get_interp_1616(500000 + 40 * xh) + 0.0001 * xh * delay.get_interp_1616(650000 - 40 * yh) - delay.get_interp_1616(800000 - 60 * xh);
- float out_hi_r = delay.get_interp_1616(550000 - 48 * yh) - 0.0001 * yh * delay.get_interp_1616(700000 + 46 * xh) + delay.get_interp_1616(1000000 + 76 * yh);
+ float out_hi_l = 0.5f * in_mono - delay.get_interp_1616(shift + 20 * xh) + 0.0001 * xh * delay.get_interp_1616(shift + pdelta - 20 * yh) - delay.get_interp_1616(shift + pdelta + pdelta - 20 * xh);
+ float out_hi_r = 0.5f * in_mono + delay.get_interp_1616(shift - 20 * yh) - 0.0001 * yh * delay.get_interp_1616(shift + pdelta + 20 * xh) + delay.get_interp_1616(shift + pdelta + pdelta + 20 * yh);
- float out_lo_l = 0.5f * in_mono - delay.get_interp_1616(400000 + 34 * xl) + delay.get_interp_1616(650000 - 18 * yl);
- float out_lo_r = 0.5f * in_mono + delay.get_interp_1616(600000 - 50 * xl) - delay.get_interp_1616(900000 + 15 * yl);
+ float out_lo_l = 0.5f * in_mono - delay.get_interp_1616(shift + 20 * xl) + delay.get_interp_1616(shift + pdelta - 20 * yl);
+ float out_lo_r = 0.5f * in_mono + delay.get_interp_1616(shift - 20 * xl) - delay.get_interp_1616(shift + pdelta + 20 * yl);
out_hi_l = crossover2l.process_d2(out_hi_l); // sanitize(out_hi_l);
out_hi_r = crossover2r.process_d2(out_hi_r); // sanitize(out_hi_r);
diff --git a/src/calf/modules_synths.h b/src/calf/modules_synths.h
index c2a8b87..912e445 100644
--- a/src/calf/modules_synths.h
+++ b/src/calf/modules_synths.h
@@ -203,6 +203,7 @@ public:
float *params[param_count];
organ_parameters par_values;
uint32_t srate;
+ bool panic_flag;
organ_audio_module()
: drawbar_organ(&par_values)
@@ -221,17 +222,26 @@ public:
}
void activate() {
setup(srate);
+ panic_flag = false;
}
void deactivate() {
}
uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
float *o[2] = { outs[0] + offset, outs[1] + offset };
+ if (panic_flag)
+ {
+ control_change(120, 0); // stop all sounds
+ control_change(121, 0); // reset all controllers
+ panic_flag = false;
+ }
render_separate(o, nsamples);
return 3;
}
+ void execute(int cmd_no);
static const char *get_name() { return "organ"; }
static const char *get_id() { return "organ"; }
static const char *get_label() { return "Organ"; }
+ static plugin_command_info *get_commands();
};
};
diff --git a/src/dssigui.cpp b/src/dssigui.cpp
index 2ca7f7f..ad378c9 100644
--- a/src/dssigui.cpp
+++ b/src/dssigui.cpp
@@ -155,6 +155,25 @@ struct plugin_proxy: public plugin_proxy_base, public line_graph_iface
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; }
+ virtual plugin_command_info *get_commands() {
+ return Module::get_commands();
+ }
+ virtual void execute(int command_no) {
+ if (send_osc) {
+ vector<osc_data> data;
+ stringstream ss;
+ ss << command_no;
+
+ data.push_back(osc_data("ExecCommand"));
+ data.push_back(osc_data(ss.str()));
+ client->send("/configure", data);
+ data.clear();
+
+ data.push_back(osc_data("ExecCommand"));
+ data.push_back(osc_data(""));
+ client->send("/configure", data);
+ }
+ }
};
plugin_proxy_base *create_plugin_proxy(const char *effect_name)
diff --git a/src/gui.cpp b/src/gui.cpp
index cbf0d23..2eea954 100644
--- a/src/gui.cpp
+++ b/src/gui.cpp
@@ -799,6 +799,7 @@ static void store_preset_action(GtkAction *action, plugin_gui_window *gui_win)
static const GtkActionEntry actions[] = {
{ "PresetMenuAction", "", "_Preset", NULL, "Preset operations", NULL },
+ { "CommandMenuAction", "", "_Command", NULL, "Plugin-related commands", NULL },
{ "store-preset", "", "_Store preset", NULL, "Store a current setting as preset", (GCallback)store_preset_action },
};
@@ -812,6 +813,7 @@ static const char *ui_xml =
" <separator/>\n"
" <placeholder name=\"presets\"/>\n"
" </menu>\n"
+" <placeholder name=\"commands\"/>\n"
" </menubar>\n"
"</ui>\n"
;
@@ -829,12 +831,26 @@ static const char *preset_post_xml =
"</ui>\n"
;
+static const char *command_pre_xml =
+"<ui>\n"
+" <menubar>\n"
+" <placeholder name=\"commands\">\n"
+" <menu action=\"CommandMenuAction\">\n";
+
+static const char *command_post_xml =
+" </menu>\n"
+" </placeholder>\n"
+" </menubar>\n"
+"</ui>\n"
+;
+
plugin_gui_window::plugin_gui_window(main_window_iface *_main)
{
toplevel = NULL;
ui_mgr = NULL;
std_actions = NULL;
preset_actions = NULL;
+ command_actions = NULL;
main = _main;
assert(main);
}
@@ -858,6 +874,25 @@ string plugin_gui_window::make_gui_preset_list(GtkActionGroup *grp)
return preset_xml;
}
+string plugin_gui_window::make_gui_command_list(GtkActionGroup *grp)
+{
+ string command_xml = command_pre_xml;
+ plugin_command_info *ci = gui->plugin->get_commands();
+ if (!ci)
+ return "";
+ for(int i = 0; ci->name; i++, ci++)
+ {
+ stringstream ss;
+ ss << " <menuitem name=\"" << ci->name << "\" action=\"" << ci->label << "\"/>\n";
+
+ GtkActionEntry ae = { ci->label, NULL, ci->name, NULL, ci->description, (GCallback)activate_command };
+ gtk_action_group_add_actions_full(command_actions, &ae, 1, (gpointer)new activate_command_params(gui, i), action_destroy_notify);
+ command_xml += ss.str();
+ }
+ command_xml += command_post_xml;
+ return command_xml;
+}
+
void plugin_gui_window::fill_gui_presets()
{
if(preset_actions) {
@@ -898,6 +933,9 @@ void plugin_gui_window::create(plugin_ctl_iface *_jh, const char *title, const c
GError *error = NULL;
gtk_ui_manager_insert_action_group(ui_mgr, std_actions, 0);
gtk_ui_manager_add_ui_from_string(ui_mgr, ui_xml, -1, &error);
+
+ command_actions = gtk_action_group_new("commands");
+
fill_gui_presets();
gtk_box_pack_start(GTK_BOX(vbox), gtk_ui_manager_get_widget(ui_mgr, "/ui/menubar"), false, false, 0);
@@ -913,6 +951,11 @@ void plugin_gui_window::create(plugin_ctl_iface *_jh, const char *title, const c
container = gui->create_from_xml(_jh, xml);
else
container = gui->create(_jh);
+
+ string command_xml = make_gui_command_list(command_actions);
+ gtk_ui_manager_insert_action_group(ui_mgr, command_actions, 0);
+ gtk_ui_manager_add_ui_from_string(ui_mgr, command_xml.c_str(), -1, &error);
+
GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_NONE);
@@ -933,6 +976,7 @@ void plugin_gui_window::create(plugin_ctl_iface *_jh, const char *title, const c
// gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(sw), GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, req.height, 20, 100, 100)));
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
}
@@ -952,4 +996,11 @@ plugin_gui_window::~plugin_gui_window()
delete gui;
}
+void synth::activate_command(GtkAction *action, activate_command_params *params)
+{
+ plugin_gui *gui = params->gui;
+ gui->plugin->execute(params->function_idx);
+ gui->refresh();
+}
+
diff --git a/src/lv2gui.cpp b/src/lv2gui.cpp
index daa1ec6..0c92412 100644
--- a/src/lv2gui.cpp
+++ b/src/lv2gui.cpp
@@ -125,6 +125,10 @@ struct plugin_proxy: public plugin_proxy_base, public line_graph_iface
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; }
+ virtual void execute(int command_no) { assert(0); }
+ virtual plugin_command_info *get_commands() {
+ return Module::get_commands();
+ }
};
plugin_proxy_base *create_plugin_proxy(const char *effect_name)
diff --git a/src/modules.cpp b/src/modules.cpp
index eec35a7..eb28664 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -164,6 +164,8 @@ const char *rotary_speaker_speed_names[] = { "Off", "Chorale", "Tremolo", "HoldP
parameter_properties rotary_speaker_audio_module::param_props[] = {
{ 2, 0, 4, 1.01, PF_ENUM | PF_CTL_COMBO, rotary_speaker_speed_names, "vib_speed", "Speed Mode" },
+ { 0.5, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "spacing", "Tap Spacing" },
+ { 0.5, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "shift", "Tap Offset" },
};
static synth::ladspa_info rotary_speaker_info = { 0x8483, "RotarySpeaker", "Calf Rotary Speaker", "Krzysztof Foltman", copyright, "SimulationPlugin" };
diff --git a/src/organ.cpp b/src/organ.cpp
index 16daba7..a578c16 100644
--- a/src/organ.cpp
+++ b/src/organ.cpp
@@ -804,3 +804,22 @@ void drawbar_organ::update_params()
double dphase = synth::midi_note_to_phase((int)parameters->foldover, 0, sample_rate);
parameters->foldvalue = (int)(dphase);
}
+
+void organ_audio_module::execute(int cmd_no)
+{
+ switch(cmd_no)
+ {
+ case 0:
+ panic_flag = true;
+ break;
+ }
+}
+
+plugin_command_info *organ_audio_module::get_commands()
+{
+ static plugin_command_info cmds[] = {
+ { "cmd_panic", "Panic!", "Stop all sounds and reset all controllers" },
+ { NULL }
+ };
+ return cmds;
+}
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list