summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/generic_pluginui.cc12
-rw-r--r--gtk2_ardour/lv2_plugin_ui.cc5
-rw-r--r--gtk2_ardour/lv2_plugin_ui.h6
-rw-r--r--gtk2_ardour/plugin_ui.cc115
-rw-r--r--gtk2_ardour/plugin_ui.h19
-rw-r--r--gtk2_ardour/vst_pluginui.cc20
-rw-r--r--gtk2_ardour/vst_pluginui.h2
-rw-r--r--libs/ardour/ardour/audio_unit.h5
-rw-r--r--libs/ardour/ardour/ladspa_plugin.h7
-rw-r--r--libs/ardour/ardour/lv2_plugin.h9
-rw-r--r--libs/ardour/ardour/plugin.h60
-rw-r--r--libs/ardour/ardour/vst_plugin.h10
-rw-r--r--libs/ardour/audio_unit.cc84
-rw-r--r--libs/ardour/ladspa_plugin.cc35
-rw-r--r--libs/ardour/lv2_plugin.cc31
-rw-r--r--libs/ardour/plugin.cc85
-rw-r--r--libs/ardour/session_vst.cc4
-rw-r--r--libs/ardour/vst_plugin.cc109
18 files changed, 389 insertions, 229 deletions
diff --git a/gtk2_ardour/generic_pluginui.cc b/gtk2_ardour/generic_pluginui.cc
index f672af112e..9204912a36 100644
--- a/gtk2_ardour/generic_pluginui.cc
+++ b/gtk2_ardour/generic_pluginui.cc
@@ -92,7 +92,7 @@ GenericPluginUI::GenericPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrol
set_latency_label ();
smaller_hbox->pack_start (latency_button, false, false, 10);
- smaller_hbox->pack_start (preset_combo, false, false);
+ smaller_hbox->pack_start (_preset_box, false, false);
smaller_hbox->pack_start (add_button, false, false);
smaller_hbox->pack_start (save_button, false, false);
smaller_hbox->pack_start (delete_button, false, false);
@@ -425,7 +425,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
//control_ui->combo->set_value_in_list(true, false);
set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui));
control_ui->combo->signal_changed().connect (sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::control_combo_changed), control_ui));
- mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::parameter_changed, this, control_ui), gui_context());
+ mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::ui_parameter_changed, this, control_ui), gui_context());
control_ui->pack_start(control_ui->label, true, true);
control_ui->pack_start(*control_ui->combo, false, true);
@@ -446,7 +446,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
//control_ui->combo->set_value_in_list(true, false);
set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui));
control_ui->combo->signal_changed().connect (sigc::bind (sigc::mem_fun(*this, &GenericPluginUI::control_combo_changed), control_ui));
- mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::parameter_changed, this, control_ui), gui_context());
+ mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::ui_parameter_changed, this, control_ui), gui_context());
control_ui->pack_start(control_ui->label, true, true);
control_ui->pack_start(*control_ui->combo, false, true);
@@ -557,7 +557,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
automation_state_changed (control_ui);
- mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::parameter_changed, this, control_ui), gui_context());
+ mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::ui_parameter_changed, this, control_ui), gui_context());
mcontrol->alist()->automation_state_changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::automation_state_changed, this, control_ui), gui_context());
input_controls.push_back (control_ui);
@@ -609,7 +609,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
output_controls.push_back (control_ui);
}
- mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::parameter_changed, this, control_ui), gui_context());
+ mcontrol->Changed.connect (control_connections, invalidator (*this), boost::bind (&GenericPluginUI::ui_parameter_changed, this, control_ui), gui_context());
return control_ui;
}
@@ -672,7 +672,7 @@ GenericPluginUI::toggle_parameter_changed (ControlUI* cui)
}
void
-GenericPluginUI::parameter_changed (ControlUI* cui)
+GenericPluginUI::ui_parameter_changed (ControlUI* cui)
{
if (!cui->update_pending) {
cui->update_pending = true;
diff --git a/gtk2_ardour/lv2_plugin_ui.cc b/gtk2_ardour/lv2_plugin_ui.cc
index 89d46846eb..f8924e5bec 100644
--- a/gtk2_ardour/lv2_plugin_ui.cc
+++ b/gtk2_ardour/lv2_plugin_ui.cc
@@ -55,7 +55,8 @@ void LV2PluginUI::on_external_ui_closed(LV2UI_Controller controller)
void
LV2PluginUI::parameter_changed (uint32_t port_index, float val)
{
- //cout << "parameter_changed" << endl;
+ PlugUIBase::parameter_changed (port_index, val);
+
if (val != _values[port_index]) {
parameter_update(port_index, val);
}
@@ -199,8 +200,6 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title)
}
}
}
-
- _lv2->ParameterChanged.connect (parameter_connection, invalidator (*this), ui_bind (&LV2PluginUI::parameter_changed, this, _1, _2), gui_context());
}
LV2PluginUI::~LV2PluginUI ()
diff --git a/gtk2_ardour/lv2_plugin_ui.h b/gtk2_ardour/lv2_plugin_ui.h
index 817e1e825d..37234c59eb 100644
--- a/gtk2_ardour/lv2_plugin_ui.h
+++ b/gtk2_ardour/lv2_plugin_ui.h
@@ -59,6 +59,9 @@ class LV2PluginUI : public PlugUIBase, public Gtk::VBox
int package (Gtk::Window&);
private:
+
+ void parameter_changed (uint32_t, float);
+
boost::shared_ptr<ARDOUR::LV2Plugin> _lv2;
std::vector<int> _output_ports;
sigc::connection _screen_update_connection;
@@ -83,7 +86,6 @@ class LV2PluginUI : public PlugUIBase, public Gtk::VBox
void lv2ui_instantiate(const std::string& title);
- void parameter_changed(uint32_t, float);
void parameter_update(uint32_t, float);
bool configure_handler (GdkEventConfigure*);
void save_plugin_setting ();
@@ -92,8 +94,6 @@ class LV2PluginUI : public PlugUIBase, public Gtk::VBox
virtual bool on_window_show(const std::string& title);
virtual void on_window_hide();
-
- PBD::ScopedConnection parameter_connection;
};
#endif // HAVE_SLV2
diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc
index d18f81b2c4..9ad9e38f8e 100644
--- a/gtk2_ardour/plugin_ui.cc
+++ b/gtk2_ardour/plugin_ui.cc
@@ -217,7 +217,8 @@ PluginUIWindow::on_show ()
set_role("plugin_ui");
if (_pluginui) {
- _pluginui->update_presets ();
+ _pluginui->update_preset_list ();
+ _pluginui->update_preset ();
}
if (_pluginui) {
@@ -427,15 +428,17 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
latency_gui (0),
plugin_analysis_expander (_("Plugin analysis"))
{
- //preset_combo.set_use_arrows_always(true);
- update_presets ();
- update_sensitivity ();
-
- preset_combo.set_size_request (100, -1);
- preset_combo.set_active_text ("");
- preset_combo.signal_changed().connect(sigc::mem_fun(*this, &PlugUIBase::setting_selected));
- no_load_preset = false;
+ _preset_combo.set_size_request (100, -1);
+ _preset_modified.set_size_request (16, -1);
+ _preset_combo.signal_changed().connect(sigc::mem_fun(*this, &PlugUIBase::preset_selected));
+ _no_load_preset = 0;
+
+ _preset_box.pack_start (_preset_combo);
+ _preset_box.pack_start (_preset_modified);
+ update_preset_list ();
+ update_preset ();
+
add_button.set_name ("PluginAddButton");
add_button.signal_clicked().connect (sigc::mem_fun (*this, &PlugUIBase::add_plugin_setting));
@@ -471,8 +474,10 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
insert->DropReferences.connect (death_connection, invalidator (*this), boost::bind (&PlugUIBase::plugin_going_away, this), gui_context());
- plugin->PresetAdded.connect (preset_added_connection, invalidator (*this), boost::bind (&PlugUIBase::update_presets, this), gui_context ());
- plugin->PresetRemoved.connect (preset_removed_connection, invalidator (*this), boost::bind (&PlugUIBase::update_presets, this), gui_context ());
+ plugin->PresetAdded.connect (*this, invalidator (*this), boost::bind (&PlugUIBase::preset_added_or_removed, this), gui_context ());
+ plugin->PresetRemoved.connect (*this, invalidator (*this), boost::bind (&PlugUIBase::preset_added_or_removed, this), gui_context ());
+ plugin->PresetLoaded.connect (*this, invalidator (*this), boost::bind (&PlugUIBase::update_preset, this), gui_context ());
+ plugin->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&PlugUIBase::parameter_changed, this, _1, _2), gui_context ());
}
PlugUIBase::~PlugUIBase()
@@ -529,20 +534,19 @@ PlugUIBase::processor_active_changed (boost::weak_ptr<Processor> weak_p)
}
void
-PlugUIBase::setting_selected ()
+PlugUIBase::preset_selected ()
{
- if (no_load_preset) {
+ if (_no_load_preset) {
return;
}
- if (preset_combo.get_active_text().length() > 0) {
- const Plugin::PresetRecord* pr = plugin->preset_by_label(preset_combo.get_active_text());
+ if (_preset_combo.get_active_text().length() > 0) {
+ const Plugin::PresetRecord* pr = plugin->preset_by_label (_preset_combo.get_active_text());
if (pr) {
- plugin->load_preset (pr->uri);
- update_sensitivity ();
+ plugin->load_preset (*pr);
} else {
warning << string_compose(_("Plugin preset %1 not found"),
- preset_combo.get_active_text()) << endmsg;
+ _preset_combo.get_active_text()) << endmsg;
}
}
}
@@ -562,8 +566,9 @@ PlugUIBase::add_plugin_setting ()
plugin->remove_preset (d.name ());
}
- if (plugin->save_preset (d.name())) {
- preset_combo.set_active_text (d.name());
+ Plugin::PresetRecord const r = plugin->save_preset (d.name());
+ if (!r.uri.empty ()) {
+ plugin->load_preset (r);
}
break;
}
@@ -572,23 +577,18 @@ PlugUIBase::add_plugin_setting ()
void
PlugUIBase::save_plugin_setting ()
{
- string const name = preset_combo.get_active_text ();
+ string const name = _preset_combo.get_active_text ();
plugin->remove_preset (name);
- plugin->save_preset (name);
- preset_combo.set_active_text (name);
+ Plugin::PresetRecord const r = plugin->save_preset (name);
+ if (!r.uri.empty ()) {
+ plugin->load_preset (r);
+ }
}
void
PlugUIBase::delete_plugin_setting ()
{
- plugin->remove_preset (preset_combo.get_active_text ());
-
- vector<ARDOUR::Plugin::PresetRecord> presets = plugin->get_presets();
- if (presets.empty ()) {
- preset_combo.set_active_text ("");
- } else {
- preset_combo.set_active_text (presets.front().label);
- }
+ plugin->remove_preset (_preset_combo.get_active_text ());
}
void
@@ -667,30 +667,61 @@ PlugUIBase::toggle_plugin_analysis()
}
void
-PlugUIBase::update_presets ()
+PlugUIBase::update_preset_list ()
{
vector<string> preset_labels;
vector<ARDOUR::Plugin::PresetRecord> presets = plugin->get_presets();
- no_load_preset = true;
+ ++_no_load_preset;
for (vector<ARDOUR::Plugin::PresetRecord>::const_iterator i = presets.begin(); i != presets.end(); ++i) {
- preset_labels.push_back(i->label);
+ preset_labels.push_back (i->label);
}
- set_popdown_strings (preset_combo, preset_labels);
+ set_popdown_strings (_preset_combo, preset_labels);
- no_load_preset = false;
+ --_no_load_preset;
+}
+
+void
+PlugUIBase::update_preset ()
+{
+ Plugin::PresetRecord p = plugin->last_preset();
+
+ ++_no_load_preset;
+ _preset_combo.set_active_text (p.label);
+ --_no_load_preset;
- update_sensitivity ();
+ save_button.set_sensitive (!p.uri.empty() && p.user);
+ delete_button.set_sensitive (!p.uri.empty() && p.user);
+
+ update_preset_modified ();
}
void
-PlugUIBase::update_sensitivity ()
+PlugUIBase::update_preset_modified ()
{
- bool const have_user_preset =
- !preset_combo.get_model()->children().empty() && preset_combo.get_active_row_number() >= plugin->first_user_preset_index();
+ if (plugin->last_preset().uri.empty()) {
+ _preset_modified.set_text ("");
+ return;
+ }
- save_button.set_sensitive (have_user_preset);
- delete_button.set_sensitive (have_user_preset);
+ bool const c = plugin->parameter_changed_since_last_preset ();
+ if (_preset_modified.get_text().empty() == c) {
+ _preset_modified.set_text (c ? "*" : "");
+ }
+}
+
+void
+PlugUIBase::parameter_changed (uint32_t, float)
+{
+ update_preset_modified ();
+}
+
+void
+PlugUIBase::preset_added_or_removed ()
+{
+ /* Update both the list and the currently-displayed preset */
+ update_preset_list ();
+ update_preset ();
}
diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h
index 99a4ce36e8..16ecc4bd15 100644
--- a/gtk2_ardour/plugin_ui.h
+++ b/gtk2_ardour/plugin_ui.h
@@ -72,7 +72,7 @@ namespace Gtkmm2ext {
class LatencyGUI;
class ArdourDialog;
-class PlugUIBase : public virtual sigc::trackable
+class PlugUIBase : public virtual sigc::trackable, public PBD::ScopedConnectionList
{
public:
PlugUIBase (boost::shared_ptr<ARDOUR::PluginInsert>);
@@ -86,7 +86,8 @@ class PlugUIBase : public virtual sigc::trackable
virtual void activate () {}
virtual void deactivate () {}
- virtual void update_presets ();
+ void update_preset_list ();
+ void update_preset ();
void latency_button_clicked ();
@@ -101,7 +102,9 @@ class PlugUIBase : public virtual sigc::trackable
protected:
boost::shared_ptr<ARDOUR::PluginInsert> insert;
boost::shared_ptr<ARDOUR::Plugin> plugin;
- Gtk::ComboBoxText preset_combo;
+ Gtk::HBox _preset_box;
+ Gtk::ComboBoxText _preset_combo;
+ Gtk::Label _preset_modified;
Gtk::Button add_button;
Gtk::Button save_button;
Gtk::Button delete_button;
@@ -119,9 +122,9 @@ class PlugUIBase : public virtual sigc::trackable
Gtk::Image* focus_out_image;
Gtk::Image* focus_in_image;
- bool no_load_preset;
+ int _no_load_preset;
- virtual void setting_selected ();
+ virtual void preset_selected ();
void add_plugin_setting ();
void save_plugin_setting ();
void delete_plugin_setting ();
@@ -130,7 +133,9 @@ class PlugUIBase : public virtual sigc::trackable
void toggle_plugin_analysis ();
void processor_active_changed (boost::weak_ptr<ARDOUR::Processor> p);
void plugin_going_away ();
- void update_sensitivity ();
+ virtual void parameter_changed (uint32_t, float);
+ void preset_added_or_removed ();
+ void update_preset_modified ();
PBD::ScopedConnection death_connection;
PBD::ScopedConnection active_connection;
@@ -234,7 +239,7 @@ class GenericPluginUI : public PlugUIBase, public Gtk::VBox
void build ();
ControlUI* build_control_ui (guint32 port_index, boost::shared_ptr<ARDOUR::AutomationControl>);
std::vector<std::string> setup_scale_values(guint32 port_index, ControlUI* cui);
- void parameter_changed (ControlUI* cui);
+ void ui_parameter_changed (ControlUI* cui);
void toggle_parameter_changed (ControlUI* cui);
void update_control_display (ControlUI* cui);
void control_port_toggled (ControlUI* cui);
diff --git a/gtk2_ardour/vst_pluginui.cc b/gtk2_ardour/vst_pluginui.cc
index be8a619e70..b6902445f3 100644
--- a/gtk2_ardour/vst_pluginui.cc
+++ b/gtk2_ardour/vst_pluginui.cc
@@ -35,8 +35,6 @@ VSTPluginUI::VSTPluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<
: PlugUIBase (pi),
vst (vp)
{
- update_presets ();
-
fst_run_editor (vst->fst());
preset_box.set_spacing (6);
@@ -45,7 +43,7 @@ VSTPluginUI::VSTPluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<
preset_box.pack_end (delete_button, false, false);
preset_box.pack_end (save_button, false, false);
preset_box.pack_end (add_button, false, false);
- preset_box.pack_end (preset_combo, false, false);
+ preset_box.pack_end (_preset_box, false, false);
bypass_button.set_active (!insert->active());
@@ -61,22 +59,10 @@ VSTPluginUI::~VSTPluginUI ()
}
void
-VSTPluginUI::setting_selected ()
+VSTPluginUI::preset_selected ()
{
- int const r = preset_combo.get_active_row_number ();
-
- if (r < vst->first_user_preset_index()) {
- /* This is a plugin-provided preset.
- We can't dispatch directly here; too many plugins expects only one GUI thread.
- */
- vst->fst()->want_program = r;
- } else {
- /* This is a user preset. This method knows about the direct dispatch restriction, too */
- plugin->load_preset (preset_combo.get_active_text());
- }
-
socket.grab_focus ();
- update_sensitivity ();
+ PlugUIBase::preset_selected ();
}
int
diff --git a/gtk2_ardour/vst_pluginui.h b/gtk2_ardour/vst_pluginui.h
index 71452617f8..c8666a4da9 100644
--- a/gtk2_ardour/vst_pluginui.h
+++ b/gtk2_ardour/vst_pluginui.h
@@ -40,5 +40,5 @@ class VSTPluginUI : public PlugUIBase, public Gtk::VBox
bool configure_handler (GdkEventConfigure*, Gtk::Socket*);
void save_plugin_setting ();
- void setting_selected ();
+ void preset_selected ();
};
diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h
index b00c23b1dc..abbfdbea3d 100644
--- a/libs/ardour/ardour/audio_unit.h
+++ b/libs/ardour/ardour/audio_unit.h
@@ -95,12 +95,10 @@ class AUPlugin : public ARDOUR::Plugin
bool parameter_is_input (uint32_t) const;
bool parameter_is_output (uint32_t) const;
- XMLNode& get_state();
int set_state(const XMLNode& node, int);
bool save_preset (std::string name);
bool load_preset (const std::string& preset_label);
- std::vector<PresetRecord> get_presets ();
std::string current_preset() const;
bool has_editor () const;
@@ -143,6 +141,8 @@ class AUPlugin : public ARDOUR::Plugin
static std::string maybe_fix_broken_au_id (const std::string&);
private:
+ void find_presets ();
+
boost::shared_ptr<CAComponent> comp;
boost::shared_ptr<CAAudioUnit> unit;
@@ -178,6 +178,7 @@ class AUPlugin : public ARDOUR::Plugin
int set_input_format (AudioStreamBasicDescription&);
int set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription&);
void discover_parameters ();
+ void add_state (XMLNode *) const;
std::vector<std::pair<uint32_t, uint32_t> > parameter_map;
uint32_t current_maxbuf;
diff --git a/libs/ardour/ardour/ladspa_plugin.h b/libs/ardour/ardour/ladspa_plugin.h
index 7d561dd0a8..457921cf36 100644
--- a/libs/ardour/ardour/ladspa_plugin.h
+++ b/libs/ardour/ardour/ladspa_plugin.h
@@ -97,11 +97,9 @@ class LadspaPlugin : public ARDOUR::Plugin
bool parameter_is_output(uint32_t) const;
bool parameter_is_toggled(uint32_t) const;
- XMLNode& get_state();
int set_state (const XMLNode&, int version);
- std::vector<PresetRecord> get_presets ();
- bool load_preset (const std::string& uri);
+ bool load_preset (PresetRecord);
bool has_editor() const { return false; }
@@ -131,6 +129,8 @@ class LadspaPlugin : public ARDOUR::Plugin
uint32_t _index;
bool _was_activated;
+ void find_presets ();
+
void init (void *mod, uint32_t index, framecnt_t rate);
void run_in_place (pframes_t nsamples);
void latency_compute_run ();
@@ -140,6 +140,7 @@ class LadspaPlugin : public ARDOUR::Plugin
std::string preset_envvar () const;
std::string preset_source (std::string) const;
bool write_preset_file (std::string);
+ void add_state (XMLNode *) const;
};
class LadspaPluginInfo : public PluginInfo {
diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h
index c2b9ebc7bb..0920a01e6d 100644
--- a/libs/ardour/ardour/lv2_plugin.h
+++ b/libs/ardour/ardour/lv2_plugin.h
@@ -66,7 +66,7 @@ class LV2Plugin : public ARDOUR::Plugin
bool is_external_ui() const;
SLV2Port slv2_port(uint32_t i) { return slv2_plugin_get_port_by_index(_plugin, i); }
- const char* port_symbol(uint32_t port);
+ const char* port_symbol (uint32_t port) const;
const LV2_Feature* const* features() { return _features; }
@@ -112,12 +112,11 @@ class LV2Plugin : public ARDOUR::Plugin
static uint32_t midi_event_type() { return _midi_event_type; }
- XMLNode& get_state();
int set_state(const XMLNode& node, int version);
bool save_preset (std::string uri);
void remove_preset (std::string uri);
- bool load_preset (const std::string& uri);
- virtual std::vector<Plugin::PresetRecord> get_presets();
+ bool load_preset (PresetRecord);
+ std::string current_preset () const;
bool has_editor() const;
@@ -167,6 +166,8 @@ class LV2Plugin : public ARDOUR::Plugin
void latency_compute_run ();
std::string do_save_preset (std::string);
void do_remove_preset (std::string);
+ void find_presets ();
+ void add_state (XMLNode *) const;
};
diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h
index ad002a926d..00ed6bdc94 100644
--- a/libs/ardour/ardour/plugin.h
+++ b/libs/ardour/ardour/plugin.h
@@ -99,6 +99,9 @@ class Plugin : public PBD::StatefulDestructible, public Latent
bool max_unbound;
};
+ XMLNode& get_state ();
+ virtual int set_state (const XMLNode &, int version);
+
virtual std::string unique_id() const = 0;
virtual const char * label() const = 0;
virtual const char * name() const = 0;
@@ -131,23 +134,40 @@ class Plugin : public PBD::StatefulDestructible, public Latent
void realtime_handle_transport_stopped ();
- bool save_preset (std::string);
- void remove_preset (std::string);
- virtual bool load_preset (const std::string& uri) = 0;
-
struct PresetRecord {
- PresetRecord (const std::string& u, const std::string& l) : uri(u), label(l) {}
+ PresetRecord () : user (true) {}
+ PresetRecord (const std::string& u, const std::string& l, bool s = true) : uri (u), label (l), user (s) {}
+
+ bool operator!= (PresetRecord const & a) const {
+ return uri != a.uri || label != a.label;
+ }
+
std::string uri;
std::string label;
+ bool user;
};
+ PresetRecord save_preset (std::string);
+ void remove_preset (std::string);
+
+ virtual bool load_preset (PresetRecord);
+
const PresetRecord * preset_by_label (const std::string &);
const PresetRecord * preset_by_uri (const std::string &);
- /** Return this plugin's presets; should add them to _presets */
- virtual std::vector<PresetRecord> get_presets () = 0;
- virtual std::string current_preset () const { return std::string(); }
+ std::vector<PresetRecord> get_presets ();
+ /** @return Last preset to be requested; the settings may have
+ * been changed since; find out with parameter_changed_since_last_preset.
+ */
+ PresetRecord last_preset () const {
+ return _last_preset;
+ }
+
+ bool parameter_changed_since_last_preset () const {
+ return _parameter_changed_since_last_preset;
+ }
+
virtual int first_user_preset_index () const {
return 0;
}
@@ -155,13 +175,14 @@ class Plugin : public PBD::StatefulDestructible, public Latent
/** Emitted when a preset is added or removed, respectively */
PBD::Signal0<void> PresetAdded;
PBD::Signal0<void> PresetRemoved;
-
- /* XXX: no-one listens to this */
- static PBD::Signal0<bool> PresetFileExists;
- virtual bool has_editor() const = 0;
+ /** Emitted when a preset has been loaded */
+ PBD::Signal0<void> PresetLoaded;
+
+ virtual bool has_editor () const = 0;
- PBD::Signal2<void,uint32_t,float> ParameterChanged;
+ /** Emitted when any parameter changes */
+ PBD::Signal2<void, uint32_t, float> ParameterChanged;
/* NOTE: this block of virtual methods looks like the interface
to a Processor, but Plugin does not inherit from Processor.
@@ -199,7 +220,7 @@ protected:
friend class PluginInsert;
friend struct PluginInsert::PluginControl;
- virtual void set_parameter (uint32_t which, float val) = 0;
+ virtual void set_parameter (uint32_t which, float val);
/** Do the actual saving of the current plugin settings to a preset of the provided name.
* Should return a URI on success, or an empty string on failure.
@@ -215,10 +236,19 @@ protected:
std::map<std::string, PresetRecord> _presets;
private:
-
+
+ /** Fill _presets with our presets */
+ virtual void find_presets () = 0;
+
+ /** Add state to an existing XMLNode */
+ virtual void add_state (XMLNode *) const = 0;
+
+ bool _have_presets;
MidiStateTracker _tracker;
BufferSet _pending_stop_events;
bool _have_pending_stop_events;
+ PresetRecord _last_preset;
+ bool _parameter_changed_since_last_preset;
};
PluginPtr find_plugin(ARDOUR::Session&, std::string unique_id, ARDOUR::PluginType);
diff --git a/libs/ardour/ardour/vst_plugin.h b/libs/ardour/ardour/vst_plugin.h
index e9a2c4abdf..83bf58c4ac 100644
--- a/libs/ardour/ardour/vst_plugin.h
+++ b/libs/ardour/ardour/vst_plugin.h
@@ -78,13 +78,11 @@ class VSTPlugin : public ARDOUR::Plugin
bool parameter_is_input(uint32_t i) const { return true; }
bool parameter_is_output(uint32_t i) const { return false; }
- bool load_preset (const std::string& preset_label);
- virtual std::vector<PresetRecord> get_presets ();
+ bool load_preset (PresetRecord);
int first_user_preset_index () const;
bool has_editor () const;
- XMLNode& get_state();
int set_state (XMLNode const &, int);
AEffect * plugin () const { return _plugin; }
@@ -94,10 +92,14 @@ private:
void do_remove_preset (std::string name);
std::string do_save_preset (std::string name);
- gchar* get_chunk (bool);
+ gchar* get_chunk (bool) const;
int set_chunk (gchar const *, bool);
XMLTree * presets_tree () const;
std::string presets_file () const;
+ void find_presets ();
+ bool load_user_preset (PresetRecord);
+ bool load_plugin_preset (PresetRecord);
+ void add_state (XMLNode *) const;
FSTHandle* handle;
FST* _fst;
diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc
index 2e47a0bd48..54342c7f91 100644
--- a/libs/ardour/audio_unit.cc
+++ b/libs/ardour/audio_unit.cc
@@ -162,16 +162,10 @@ save_property_list (CFPropertyListRef propertyList, Glib::ustring path)
fd = open (path.c_str(), O_WRONLY|O_CREAT|O_EXCL, 0664);
while (fd < 0) {
if (errno == EEXIST) {
- /* tell any UI's that this file already exists and ask them what to do */
- bool overwrite = Plugin::PresetFileExists(); // EMIT SIGNAL
- if (overwrite) {
- fd = open (path.c_str(), O_WRONLY, 0664);
- continue;
- } else {
- return 0;
- }
+ error << string_compose (_("Preset file %1 exists; not overwriting"), path);
+ } else {
+ error << string_compose (_("Cannot open preset file %1 (%2)"), path, strerror (errno)) << endmsg;
}
- error << string_compose (_("Cannot open preset file %1 (%2)"), path, strerror (errno)) << endmsg;
CFRelease (xmlData);
return -1;
}
@@ -767,24 +761,28 @@ AUPlugin::signal_latency () const
void
AUPlugin::set_parameter (uint32_t which, float val)
{
- if (which < descriptors.size()) {
- const AUParameterDescriptor& d (descriptors[which]);
- TRACE_API ("set parameter %d in scope %d element %d to %f\n", d.id, d.scope, d.element, val);
- unit->SetParameter (d.id, d.scope, d.element, val);
-
- /* tell the world what we did */
-
- AudioUnitEvent theEvent;
-
- theEvent.mEventType = kAudioUnitEvent_ParameterValueChange;
- theEvent.mArgument.mParameter.mAudioUnit = unit->AU();
- theEvent.mArgument.mParameter.mParameterID = d.id;
- theEvent.mArgument.mParameter.mScope = d.scope;
- theEvent.mArgument.mParameter.mElement = d.element;
-
- TRACE_API ("notify about parameter change\n");
- AUEventListenerNotify (NULL, NULL, &theEvent);
+ if (which >= descriptors.size()) {
+ return;
}
+
+ const AUParameterDescriptor& d (descriptors[which]);
+ TRACE_API ("set parameter %d in scope %d element %d to %f\n", d.id, d.scope, d.element, val);
+ unit->SetParameter (d.id, d.scope, d.element, val);
+
+ /* tell the world what we did */
+
+ AudioUnitEvent theEvent;
+
+ theEvent.mEventType = kAudioUnitEvent_ParameterValueChange;
+ theEvent.mArgument.mParameter.mAudioUnit = unit->AU();
+ theEvent.mArgument.mParameter.mParameterID = d.id;
+ theEvent.mArgument.mParameter.mScope = d.scope;
+ theEvent.mArgument.mParameter.mElement = d.element;
+
+ TRACE_API ("notify about parameter change\n");
+ AUEventListenerNotify (NULL, NULL, &theEvent);
+
+ Plugin::set_parameter (which, val);
}
float
@@ -1551,11 +1549,10 @@ AUPlugin::parameter_is_output (uint32_t) const
return false;
}
-XMLNode&
-AUPlugin::get_state()
+void
+AUPlugin::add_state (XMLNode* root)
{
LocaleGuard lg (X_("POSIX"));
- XMLNode *root = new XMLNode (state_node_name());
#ifdef AU_STATE_SUPPORT
CFDataRef xmlData;
@@ -1563,7 +1560,7 @@ AUPlugin::get_state()
TRACE_API ("get preset state\n");
if (unit->GetAUPreset (propertyList) != noErr) {
- return *root;
+ return;
}
// Convert the property list into XML data.
@@ -1597,12 +1594,10 @@ AUPlugin::get_state()
seen_get_state_message = true;
}
#endif
-
- return *root;
}
int
-AUPlugin::set_state(const XMLNode& node, int /* version*/)
+AUPlugin::set_state(const XMLNode& node, int version)
{
#ifdef AU_STATE_SUPPORT
int ret = -1;
@@ -1650,6 +1645,7 @@ AUPlugin::set_state(const XMLNode& node, int /* version*/)
CFRelease (propertyList);
}
+ Plugin::set_state (node, version);
return ret;
#else
if (!seen_set_state_message) {
@@ -1657,13 +1653,15 @@ AUPlugin::set_state(const XMLNode& node, int /* version*/)
PROGRAM_NAME)
<< endmsg;
}
- return 0;
+ return Plugin::set_state (node, version);
#endif
}
bool
-AUPlugin::load_preset (const string& preset_label)
+AUPlugin::load_preset (PluginRecord r)
{
+ Plugin::load_preset (r);
+
#ifdef AU_STATE_SUPPORT
bool ret = false;
CFPropertyListRef propertyList;
@@ -1962,11 +1960,9 @@ AUPlugin::current_preset() const
return preset_name;
}
-vector<Plugin::PresetRecord>
-AUPlugin::get_presets ()
+void
+AUPlugin::find_presets ()
{
- vector<Plugin::PresetRecord> presets;
-
#ifdef AU_STATE_SUPPORT
vector<string*>* preset_files;
PathScanner scanner;
@@ -1976,7 +1972,7 @@ AUPlugin::get_presets ()
preset_files = scanner (preset_search_path, au_preset_filter, this, true, true, -1, true);
if (!preset_files) {
- return presets;
+ return;
}
for (vector<string*>::iterator x = preset_files->begin(); x != preset_files->end(); ++x) {
@@ -2006,18 +2002,18 @@ AUPlugin::get_presets ()
/* now fill the vector<string> with the names we have */
for (UserPresetMap::iterator i = user_preset_map.begin(); i != user_preset_map.end(); ++i) {
- presets.push_back (Plugin::PresetRecord (i->second, i->first));
+ _presets.insert (i->second, Plugin::PresetRecord (i->second, i->first));
}
/* add factory presets */
for (FactoryPresetMap::iterator i = factory_preset_map.begin(); i != factory_preset_map.end(); ++i) {
- presets.push_back (Plugin::PresetRecord ("", i->first));
+ /* XXX: dubious */
+ string const uri = string_compose ("%1", _presets.size ());
+ _presets.push_back (uri, Plugin::PresetRecord (uri, i->first));
}
#endif
-
- return presets;
}
bool
diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc
index 43fa8e43ee..cab21f46f9 100644
--- a/libs/ardour/ladspa_plugin.cc
+++ b/libs/ardour/ladspa_plugin.cc
@@ -297,9 +297,8 @@ LadspaPlugin::set_parameter (uint32_t which, float val)
{
if (which < _descriptor->PortCount) {
_shadow_data[which] = (LADSPA_Data) val;
-#if 0
- ParameterChanged (Parameter(PluginAutomation, 0, which), val); /* EMIT SIGNAL */
+#if 0
if (which < parameter_count() && controls[which]) {
controls[which]->Changed ();
}
@@ -311,6 +310,8 @@ LadspaPlugin::set_parameter (uint32_t which, float val)
"invalid"), name())
<< endmsg;
}
+
+ Plugin::set_parameter (which, val);
}
float
@@ -341,10 +342,9 @@ LadspaPlugin::nth_parameter (uint32_t n, bool& ok) const
return 0;
}
-XMLNode&
-LadspaPlugin::get_state()
+void
+LadspaPlugin::add_state (XMLNode* root) const
{
- XMLNode *root = new XMLNode(state_node_name());
XMLNode *child;
char buf[16];
LocaleGuard lg (X_("POSIX"));
@@ -362,8 +362,6 @@ LadspaPlugin::get_state()
root->add_child_nocopy (*child);
}
}
-
- return *root;
}
int
@@ -372,7 +370,7 @@ LadspaPlugin::set_state (const XMLNode& node, int version)
if (version < 3000) {
return set_state_2X (node, version);
}
-
+
XMLNodeList nodes;
XMLProperty *prop;
XMLNodeConstIterator iter;
@@ -389,7 +387,7 @@ LadspaPlugin::set_state (const XMLNode& node, int version)
nodes = node.children ("Port");
- for(iter = nodes.begin(); iter != nodes.end(); ++iter){
+ for (iter = nodes.begin(); iter != nodes.end(); ++iter) {
child = *iter;
@@ -412,7 +410,7 @@ LadspaPlugin::set_state (const XMLNode& node, int version)
latency_compute_run ();
- return 0;
+ return Plugin::set_state (node, version);
}
int
@@ -709,15 +707,14 @@ LadspaPluginInfo::LadspaPluginInfo()
}
-vector<Plugin::PresetRecord>
-LadspaPlugin::get_presets ()
+void
+LadspaPlugin::find_presets ()
{
- vector<PresetRecord> result;
uint32_t id;
std::string unique (unique_id());
if (!isdigit (unique[0])) {
- return result;
+ return;
}
id = atol (unique.c_str());
@@ -727,22 +724,19 @@ LadspaPlugin::get_presets ()
if (set_uris) {
for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) {
if (char* label = lrdf_get_label(set_uris->items[i])) {
- PresetRecord rec(set_uris->items[i], label);
- result.push_back(rec);
+ PresetRecord rec (set_uris->items[i], label);
_presets.insert (make_pair (set_uris->items[i], rec));
}
}
lrdf_free_uris(set_uris);
}
-
- return result;
}
bool
-LadspaPlugin::load_preset (const string& preset_uri)
+LadspaPlugin::load_preset (PresetRecord r)
{
- lrdf_defaults* defs = lrdf_get_setting_values(preset_uri.c_str());
+ lrdf_defaults* defs = lrdf_get_setting_values (r.uri.c_str());
if (defs) {
for (uint32_t i = 0; i < (uint32_t) defs->count; ++i) {
@@ -755,6 +749,7 @@ LadspaPlugin::load_preset (const string& preset_uri)
lrdf_free_setting_values(defs);
}
+ Plugin::load_preset (r);
return true;
}
diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc
index d8daca9f64..dd36d134f5 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -219,7 +219,7 @@ LV2Plugin::default_value (uint32_t port)
}
const char*
-LV2Plugin::port_symbol (uint32_t index)
+LV2Plugin::port_symbol (uint32_t index) const
{
SLV2Port port = slv2_plugin_get_port_by_index(_plugin, index);
if (!port) {
@@ -236,7 +236,6 @@ LV2Plugin::set_parameter (uint32_t which, float val)
{
if (which < slv2_plugin_get_num_ports(_plugin)) {
_shadow_data[which] = val;
- ParameterChanged (which, val); /* EMIT SIGNAL */
#if 0
if (which < parameter_count() && controls[which]) {
@@ -249,6 +248,8 @@ LV2Plugin::set_parameter (uint32_t which, float val)
"This is a bug in either %2 or the LV2 plugin (%3)"),
name(), PROGRAM_NAME, unique_id()) << endmsg;
}
+
+ Plugin::set_parameter (which, val);
}
float
@@ -307,10 +308,9 @@ LV2Plugin::lv2_persist_retrieve_callback(void* callback_data,
return NULL;
}
-XMLNode&
-LV2Plugin::get_state()
+void
+LV2Plugin::add_state (XMLNode* root) const
{
- XMLNode *root = new XMLNode(state_node_name());
XMLNode *child;
char buf[16];
LocaleGuard lg (X_("POSIX"));
@@ -347,7 +347,7 @@ LV2Plugin::get_state()
warning << string_compose(
_("Plugin \"%1\% failed to return LV2 persist data"),
unique_id());
- return *root; // FIXME: Possibly inconsistent state
+ return;
}
LV2PFile file = lv2_pfile_open(state_path.c_str(), true);
@@ -356,36 +356,35 @@ LV2Plugin::get_state()
root->add_property("state-file", state_filename);
}
-
- return *root;
}
-vector<Plugin::PresetRecord>
-LV2Plugin::get_presets()
+void
+LV2Plugin::find_presets ()
{
- vector<PresetRecord> result;
SLV2Results presets = slv2_plugin_query_sparql(_plugin,
"PREFIX lv2p: <http://lv2plug.in/ns/dev/presets#>\n"
"PREFIX dc: <http://dublincore.org/documents/dcmi-namespace/>\n"
"SELECT ?p ?name WHERE { <> lv2p:hasPreset ?p . ?p dc:title ?name }\n");
+
for (; !slv2_results_finished(presets); slv2_results_next(presets)) {
SLV2Value uri = slv2_results_get_binding_value(presets, 0);
SLV2Value name = slv2_results_get_binding_value(presets, 1);
PresetRecord rec(slv2_value_as_string(uri), slv2_value_as_string(name));
- result.push_back(rec);
_presets.insert(std::make_pair(slv2_value_as_string(uri), rec));
}
+
slv2_results_free(presets);
- return result;
}
bool
-LV2Plugin::load_preset(const string& uri)
+LV2Plugin::load_preset (PresetRecord r)
{
+ Plugin::load_preset (r);
+
const string query = string(
"PREFIX lv2p: <http://lv2plug.in/ns/dev/presets#>\n"
"PREFIX dc: <http://dublincore.org/documents/dcmi-namespace/>\n"
- "SELECT ?sym ?val WHERE { <") + uri + "> lv2:port ?port . "
+ "SELECT ?sym ?val WHERE { <") + r.uri + "> lv2:port ?port . "
" ?port lv2:symbol ?sym ; lv2p:value ?val . }";
SLV2Results values = slv2_plugin_query_sparql(_plugin, query.c_str());
for (; !slv2_results_finished(values); slv2_results_next(values)) {
@@ -491,7 +490,7 @@ LV2Plugin::set_state(const XMLNode& node, int version)
latency_compute_run ();
- return 0;
+ return Plugin::set_state (node, version);
}
int
diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc
index 1a711b5250..3ba0f8ddec 100644
--- a/libs/ardour/plugin.cc
+++ b/libs/ardour/plugin.cc
@@ -62,13 +62,13 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-PBD::Signal0<bool> Plugin::PresetFileExists;
-
Plugin::Plugin (AudioEngine& e, Session& s)
: _engine (e)
, _session (s)
, _cycles (0)
+ , _have_presets (false)
, _have_pending_stop_events (false)
+ , _parameter_changed_since_last_preset (false)
{
}
@@ -79,7 +79,9 @@ Plugin::Plugin (const Plugin& other)
, _session (other._session)
, _info (other._info)
, _cycles (0)
+ , _have_presets (false)
, _have_pending_stop_events (false)
+ , _parameter_changed_since_last_preset (false)
{
}
@@ -94,10 +96,14 @@ Plugin::remove_preset (string name)
{
do_remove_preset (name);
_presets.erase (preset_by_label (name)->uri);
+
+ _last_preset.uri = "";
+ _parameter_changed_since_last_preset = false;
PresetRemoved (); /* EMIT SIGNAL */
}
-bool
+/** @return PresetRecord with empty URI on failure */
+Plugin::PresetRecord
Plugin::save_preset (string name)
{
string const uri = do_save_preset (name);
@@ -106,8 +112,8 @@ Plugin::save_preset (string name)
_presets.insert (make_pair (uri, PresetRecord (uri, name)));
PresetAdded (); /* EMIT SIGNAL */
}
-
- return !uri.empty ();
+
+ return PresetRecord (uri, name);
}
PluginPtr
@@ -243,3 +249,72 @@ Plugin::realtime_handle_transport_stopped ()
_tracker.resolve_notes (_pending_stop_events.get_midi (0), 0);
_have_pending_stop_events = true;
}
+
+vector<Plugin::PresetRecord>
+Plugin::get_presets ()
+{
+ if (!_have_presets) {
+ find_presets ();
+ _have_presets = true;
+ }
+
+ vector<PresetRecord> p;
+ for (map<string, PresetRecord>::const_iterator i = _presets.begin(); i != _presets.end(); ++i) {
+ p.push_back (i->second);
+ }
+
+ return p;
+}
+
+/** Set parameters using a preset */
+bool
+Plugin::load_preset (PresetRecord r)
+{
+ _last_preset = r;
+ _parameter_changed_since_last_preset = false;
+
+ PresetLoaded (); /* EMIT SIGNAL */
+ return true;
+}
+
+void
+Plugin::set_parameter (uint32_t which, float val)
+{
+ _parameter_changed_since_last_preset = true;
+ ParameterChanged (Evoral::Parameter (PluginAutomation, 0, which), val); /* EMIT SIGNAL */
+}
+
+int
+Plugin::set_state (const XMLNode& node, int version)
+{
+ XMLProperty const * p = node.property (X_("last-preset-uri"));
+ if (p) {
+ _last_preset.uri = p->value ();
+ }
+
+ p = node.property (X_("last-preset-label"));
+ if (p) {
+ _last_preset.label = p->value ();
+ }
+
+ p = node.property (X_("parameter-changed-since-last-preset"));
+ if (p) {
+ _parameter_changed_since_last_preset = string_is_affirmative (p->value ());
+ }
+
+ return 0;
+}
+
+XMLNode &
+Plugin::get_state ()
+{
+ XMLNode* root = new XMLNode (state_node_name ());
+ LocaleGuard lg (X_("POSIX"));
+
+ root->add_property (X_("last-preset-uri"), _last_preset.uri);
+ root->add_property (X_("last-preset-label"), _last_preset.label);
+ root->add_property (X_("parameter-changed-since-last-preset"), _parameter_changed_since_last_preset ? X_("yes") : X_("no"));
+
+ add_state (root);
+ return *root;
+}
diff --git a/libs/ardour/session_vst.cc b/libs/ardour/session_vst.cc
index 85b5f13c4c..2aa873c6e6 100644
--- a/libs/ardour/session_vst.cc
+++ b/libs/ardour/session_vst.cc
@@ -70,8 +70,8 @@ long Session::vst_callback (AEffect* effect,
case audioMasterAutomate:
SHOW_CALLBACK ("amc: audioMasterAutomate\n");
// index, value, returns 0
- if (effect) {
- effect->setParameter (effect, index, opt);
+ if (plug) {
+ plug->set_parameter (index, opt);
}
return 0;
diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc
index 1f3cc95c27..92aac83beb 100644
--- a/libs/ardour/vst_plugin.cc
+++ b/libs/ardour/vst_plugin.cc
@@ -125,7 +125,15 @@ void
VSTPlugin::set_parameter (uint32_t which, float val)
{
_plugin->setParameter (_plugin, which, val);
- //ParameterChanged (which, val); /* EMIT SIGNAL */
+
+ if (_fst->want_program == -1 && _fst->want_chunk == 0) {
+ /* Heinous hack: Plugin::set_parameter below updates the `modified' status of the
+ current preset, but if _fst->want_program is not -1 then there is a preset
+ setup pending or in progress, which we don't want any `modified' updates
+ to happen for. So we only do this if _fst->want_program is -1.
+ */
+ Plugin::set_parameter (which, val);
+ }
}
float
@@ -147,7 +155,7 @@ VSTPlugin::nth_parameter (uint32_t n, bool& ok) const
* @return 0-terminated base64-encoded data; must be passed to g_free () by caller.
*/
gchar *
-VSTPlugin::get_chunk (bool single)
+VSTPlugin::get_chunk (bool single) const
{
guchar* data;
int32_t data_size = _plugin->dispatcher (_plugin, 23 /* effGetChunk */, single ? 1 : 0, 0, &data, 0);
@@ -173,10 +181,9 @@ VSTPlugin::set_chunk (gchar const * data, bool single)
return r;
}
-XMLNode&
-VSTPlugin::get_state()
+void
+VSTPlugin::add_state (XMLNode* root) const
{
- XMLNode *root = new XMLNode (state_node_name());
LocaleGuard lg (X_("POSIX"));
if (_fst->current_program != -1) {
@@ -189,7 +196,7 @@ VSTPlugin::get_state()
gchar* data = get_chunk (false);
if (data == 0) {
- return *root;
+ return;
}
/* store information */
@@ -215,12 +222,10 @@ VSTPlugin::get_state()
root->add_child_nocopy (*parameters);
}
-
- return *root;
}
int
-VSTPlugin::set_state(const XMLNode& node, int)
+VSTPlugin::set_state (const XMLNode& node, int version)
{
LocaleGuard lg (X_("POSIX"));
@@ -275,6 +280,7 @@ VSTPlugin::set_state(const XMLNode& node, int)
}
+ Plugin::set_state (node, version);
return ret;
}
@@ -353,15 +359,54 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc)
}
bool
-VSTPlugin::load_preset (const string& name)
+VSTPlugin::load_preset (PresetRecord r)
+{
+ bool s;
+
+ if (r.user) {
+ s = load_user_preset (r);
+ } else {
+ s = load_plugin_preset (r);
+ }
+
+ if (s) {
+ Plugin::load_preset (r);
+ }
+
+ return s;
+}
+
+bool
+VSTPlugin::load_plugin_preset (PresetRecord r)
{
+ /* This is a plugin-provided preset.
+ We can't dispatch directly here; too many plugins expects only one GUI thread.
+ */
+
+ /* Extract the index of this preset from the URI */
+ int id;
+ int index;
+ int const p = sscanf (r.uri.c_str(), "VST:%d:%d", &id, &index);
+ assert (p == 2);
+
+ _fst->want_program = index;
+ return true;
+}
+
+bool
+VSTPlugin::load_user_preset (PresetRecord r)
+{
+ /* This is a user preset; we load it, and this code also knows about the
+ non-direct-dispatch thing.
+ */
+
boost::shared_ptr<XMLTree> t (presets_tree ());
if (t == 0) {
return false;
}
XMLNode* root = t->root ();
-
+
for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
XMLProperty* uri = (*i)->property (X_("uri"));
@@ -369,11 +414,11 @@ VSTPlugin::load_preset (const string& name)
assert (uri);
assert (label);
-
- if (label->value() != name) {
+
+ if (label->value() != r.label) {
continue;
}
-
+
if (_plugin->flags & 32 /* effFlagsProgramsChunks */) {
/* Load a user preset chunk from our XML file and send it via a circuitous route to the plugin */
@@ -395,26 +440,26 @@ VSTPlugin::load_preset (const string& name)
}
return false;
-
+
} else {
for (XMLNodeList::const_iterator j = (*i)->children().begin(); j != (*i)->children().end(); ++j) {
if ((*j)->name() == X_("Parameter")) {
-
- XMLProperty* index = (*j)->property (X_("index"));
- XMLProperty* value = (*j)->property (X_("value"));
-
- assert (index);
- assert (value);
-
- set_parameter (atoi (index->value().c_str()), atof (value->value().c_str ()));
+
+ XMLProperty* index = (*j)->property (X_("index"));
+ XMLProperty* value = (*j)->property (X_("value"));
+
+ assert (index);
+ assert (value);
+
+ set_parameter (atoi (index->value().c_str()), atof (value->value().c_str ()));
}
}
-
+
return true;
}
}
-
+
return false;
}
@@ -556,7 +601,6 @@ VSTPlugin::connect_and_run (BufferSet& bufs,
}
/* we already know it can support processReplacing */
-
_plugin->processReplacing (_plugin, ins, outs, nframes);
return 0;
@@ -670,16 +714,14 @@ VSTPluginInfo::load (Session& session)
}
}
-vector<Plugin::PresetRecord>
-VSTPlugin::get_presets ()
+void
+VSTPlugin::find_presets ()
{
- vector<PresetRecord> p;
-
/* Built-in presets */
int const vst_version = _plugin->dispatcher (_plugin, effGetVstVersion, 0, 0, NULL, 0);
for (int i = 0; i < _plugin->numPrograms; ++i) {
- PresetRecord r (string_compose (X_("VST:%1:%2"), unique_id (), i), "");
+ PresetRecord r (string_compose (X_("VST:%1:%2"), unique_id (), i), "", false);
if (vst_version >= 2) {
char buf[256];
@@ -692,7 +734,6 @@ VSTPlugin::get_presets ()
r.label = string_compose (_("Preset %1"), i);
}
- p.push_back (r);
_presets.insert (make_pair (r.uri, r));
}
@@ -710,13 +751,11 @@ VSTPlugin::get_presets ()
assert (uri);
assert (label);
- PresetRecord r (uri->value(), label->value());
- p.push_back (r);
+ PresetRecord r (uri->value(), label->value(), true);
_presets.insert (make_pair (r.uri, r));
}
}
- return p;
}
/** @return XMLTree with our user presets; could be a new one if no existing