[SCM] calf/master: + GUI, Fluidsynth: provide a way for combo box to work through configure/update API, use for preset selection
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:39:31 UTC 2013
The following commit has been merged in the master branch:
commit 734949614328ad86aaa04bba91589849c2345bca
Author: Krzysztof Foltman <wdev at foltman.com>
Date: Wed Apr 22 22:54:22 2009 +0100
+ GUI, Fluidsynth: provide a way for combo box to work through configure/update API, use for preset selection
diff --git a/gui/gui-fluidsynth.xml b/gui/gui-fluidsynth.xml
index 670e493..c5a17f1 100644
--- a/gui/gui-fluidsynth.xml
+++ b/gui/gui-fluidsynth.xml
@@ -5,8 +5,8 @@
<align attach-x="0" attach-y="1" align-x="1"><label param="soundfont" /></align>
<filechooser attach-x="1" attach-w="2" attach-y="1" key="soundfont" title="Select a soundfont" width_chars="30"/>
- <align attach-x="0" attach-y="2" align-x="1"><label text="SF Name" /></align>
- <combo attach-x="1" attach-w="2" attach-y="2" key="preset_list" width="30"/>
+ <align attach-x="0" attach-y="2" align-x="1"><label text="Current preset" /></align>
+ <combo attach-x="1" attach-w="2" attach-y="2" key="preset_list" current-key="preset_key" setter-key="preset_key_set"/>
<align attach-x="0" attach-y="3" align-x="1"><label param="interpolation" /></align>
<align attach-x="1" attach-y="3" attach-w="2" ><combo param="interpolation" /></align>
diff --git a/src/calf/gui.h b/src/calf/gui.h
index b3c4811..0dd4d19 100644
--- a/src/calf/gui.h
+++ b/src/calf/gui.h
@@ -223,11 +223,14 @@ struct button_param_control: public param_control
struct combo_box_param_control: public param_control, public send_updates_iface
{
GtkListStore *lstore;
+ std::map<std::string, GtkTreeIter> key2pos;
+ std::string last_key;
virtual GtkWidget *create(plugin_gui *_gui, int _param_no);
virtual void get();
virtual void set();
virtual void send_status(const char *key, const char *value);
+ void set_to_last_key();
static void combo_value_changed(GtkComboBox *widget, gpointer value);
};
diff --git a/src/calf/modules_dev.h b/src/calf/modules_dev.h
index 8f3134e..9e2d99f 100644
--- a/src/calf/modules_dev.h
+++ b/src/calf/modules_dev.h
@@ -61,6 +61,8 @@ protected:
uint32_t last_selected_preset;
/// Serial number of status data
int status_serial;
+ /// Preset number to set on next process() call
+ volatile int set_preset;
/// Update last_selected_preset based on synth object state
void update_preset_num();
diff --git a/src/fluidsynth.cpp b/src/fluidsynth.cpp
index 26cb7da..57b34cb 100644
--- a/src/fluidsynth.cpp
+++ b/src/fluidsynth.cpp
@@ -1,5 +1,5 @@
/* Calf DSP Library
- * Example audio modules - monosynth
+ * Fluidsynth wrapper
*
* Copyright (C) 2001-2007 Krzysztof Foltman
*
@@ -40,6 +40,7 @@ fluidsynth_audio_module::fluidsynth_audio_module()
settings = NULL;
synth = NULL;
status_serial = 1;
+ set_preset = -1;
}
void fluidsynth_audio_module::post_instantiate()
@@ -58,6 +59,7 @@ void fluidsynth_audio_module::deactivate()
fluid_synth_t *fluidsynth_audio_module::create_synth(int &new_sfid)
{
+ set_preset = -1;
fluid_settings_t *new_settings = new_fluid_settings();
fluid_synth_t *s = new_fluid_synth(new_settings);
if (!soundfont.empty())
@@ -71,8 +73,6 @@ fluid_synth_t *fluidsynth_audio_module::create_synth(int &new_sfid)
assert(sid >= 0);
printf("sid=%d\n", sid);
fluid_synth_sfont_select(s, 0, sid);
- fluid_synth_bank_select(s, 0, 0);
- fluid_synth_program_change(s, 0, 0);
new_sfid = sid;
fluid_sfont_t* sfont = fluid_synth_get_sfont(s, 0);
@@ -82,13 +82,22 @@ fluid_synth_t *fluidsynth_audio_module::create_synth(int &new_sfid)
string preset_list;
fluid_preset_t tmp;
+ int first_preset = -1;
while(sfont->iteration_next(sfont, &tmp))
{
string pname = tmp.get_name(&tmp);
int bank = tmp.get_banknum(&tmp);
int num = tmp.get_num(&tmp);
- sf_preset_names[num + 128 * bank] = pname;
- preset_list += calf_utils::i2s(num + 128 * bank) + "\t" + pname + "\n";
+ int id = num + 128 * bank;
+ sf_preset_names[id] = pname;
+ preset_list += calf_utils::i2s(id) + "\t" + pname + "\n";
+ if (first_preset == -1)
+ first_preset = id;
+ }
+ if (first_preset != -1)
+ {
+ fluid_synth_bank_select(s, 0, first_preset >> 7);
+ fluid_synth_program_change(s, 0, first_preset & 127);
}
soundfont_preset_list = preset_list;
}
@@ -129,13 +138,22 @@ void fluidsynth_audio_module::update_preset_num()
if (p)
last_selected_preset = p->get_num(p) + 128 * p->get_banknum(p);
else
- last_selected_preset = 0;
+ last_selected_preset = -1;
status_serial++;
}
uint32_t fluidsynth_audio_module::process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask)
{
static const int interp_lens[] = { 0, 1, 4, 7 };
+ int new_preset = set_preset;
+ if (new_preset != -1)
+ {
+ // XXXKF yeah there's a tiny chance of race here, have to live with it until I write some utility classes for lock-free data passing
+ set_preset = -1;
+ fluid_synth_bank_select(synth, 0, new_preset >> 7);
+ fluid_synth_program_change(synth, 0, new_preset & 127);
+ last_selected_preset = new_preset;
+ }
fluid_synth_set_interp_method(synth, -1, interp_lens[dsp::clip<int>(fastf2i_drm(*params[par_interpolation]), 0, 3)]);
fluid_synth_set_reverb_on(synth, *params[par_reverb] > 0);
fluid_synth_set_chorus_on(synth, *params[par_chorus] > 0);
@@ -146,6 +164,11 @@ uint32_t fluidsynth_audio_module::process(uint32_t offset, uint32_t nsamples, ui
char *fluidsynth_audio_module::configure(const char *key, const char *value)
{
+ if (!strcmp(key, "preset_key_set"))
+ {
+ set_preset = atoi(value);
+ return NULL;
+ }
if (!strcmp(key, "soundfont"))
{
if (*value)
@@ -180,7 +203,7 @@ int fluidsynth_audio_module::send_status_updates(send_updates_iface *sui, int la
{
sui->send_status("sf_name", soundfont_name.c_str());
sui->send_status("preset_list", soundfont_preset_list.c_str());
-
+ sui->send_status("preset_key", calf_utils::i2s(last_selected_preset).c_str());
map<uint32_t, string>::const_iterator i = sf_preset_names.find(last_selected_preset);
if (i == sf_preset_names.end())
sui->send_status("preset_name", "");
diff --git a/src/gui.cpp b/src/gui.cpp
index 126d28d..2b37ab5 100644
--- a/src/gui.cpp
+++ b/src/gui.cpp
@@ -72,14 +72,14 @@ GtkWidget *combo_box_param_control::create(plugin_gui *_gui, int _param_no)
{
gui = _gui;
param_no = _param_no;
- lstore = gtk_list_store_new(1, G_TYPE_STRING);
+ lstore = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); // value, key
parameter_properties &props = get_props();
widget = gtk_combo_box_new_text ();
if (props.choices)
{
for (int j = (int)props.min; j <= (int)props.max; j++)
- gtk_list_store_insert_with_values (lstore, NULL, j - (int)props.min, 0, props.choices[j - (int)props.min], -1);
+ gtk_list_store_insert_with_values (lstore, NULL, j - (int)props.min, 0, props.choices[j - (int)props.min], 1, calf_utils::i2s(j).c_str(), -1);
}
gtk_combo_box_set_model (GTK_COMBO_BOX(widget), GTK_TREE_MODEL(lstore));
gtk_signal_connect (GTK_OBJECT (widget), "changed", G_CALLBACK (combo_value_changed), (gpointer)this);
@@ -102,15 +102,30 @@ void combo_box_param_control::get()
void combo_box_param_control::combo_value_changed(GtkComboBox *widget, gpointer value)
{
- param_control *jhp = (param_control *)value;
- jhp->get();
+ combo_box_param_control *jhp = (combo_box_param_control *)value;
+ if (jhp->attribs.count("setter-key"))
+ {
+ GtkTreeIter iter;
+ gchar *key = NULL;
+ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (jhp->widget), &iter))
+ {
+ gtk_tree_model_get (GTK_TREE_MODEL (jhp->lstore), &iter, 1, &key, -1);
+ if (key) {
+ jhp->gui->plugin->configure(jhp->attribs["setter-key"].c_str(), key);
+ free(key);
+ }
+ }
+ }
+ else
+ jhp->get();
}
void combo_box_param_control::send_status(const char *key, const char *value)
{
- if (key == attribs["key"])
+ if (attribs.count("key") && key == attribs["key"])
{
gtk_list_store_clear (lstore);
+ key2pos.clear();
std::string v = value;
int i = 0;
size_t pos = 0;
@@ -118,11 +133,40 @@ void combo_box_param_control::send_status(const char *key, const char *value)
size_t endpos = v.find("\n", pos);
if (endpos == string::npos)
break;
- gtk_list_store_insert_with_values (lstore, NULL, i, 0, v.substr(pos, endpos - pos).c_str(), -1);
+ string line = v.substr(pos, endpos - pos);
+ string key, label;
+ size_t tabpos = line.find('\t');
+ if (tabpos == string::npos)
+ key = label = line;
+ else {
+ key = line.substr(0, tabpos);
+ label = line.substr(tabpos + 1);
+ }
+ GtkTreeIter gti;
+ gtk_list_store_insert_with_values (lstore, >i, i, 0, label.c_str(), 1, key.c_str(), -1);
+ key2pos[key] = gti;
pos = endpos + 1;
i++;
}
+ set_to_last_key();
}
+ if (attribs.count("current-key") && key == attribs["current-key"])
+ {
+ last_key = value;
+ set_to_last_key();
+ }
+}
+
+void combo_box_param_control::set_to_last_key()
+{
+ map<string, GtkTreeIter>::iterator i = key2pos.find(last_key);
+ if (i != key2pos.end())
+ {
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &i->second);
+
+ }
+ else
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), -1);
}
// horizontal fader
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list