Clean up plugin preset handling a bit.
git-svn-id: svn://localhost/ardour2/branches/3.0@8301 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
bb7dbe6d86
commit
5f4bdb233a
|
@ -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;
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
update_sensitivity ();
|
||||
--_no_load_preset;
|
||||
}
|
||||
|
||||
void
|
||||
PlugUIBase::update_sensitivity ()
|
||||
PlugUIBase::update_preset ()
|
||||
{
|
||||
bool const have_user_preset =
|
||||
!preset_combo.get_model()->children().empty() && preset_combo.get_active_row_number() >= plugin->first_user_preset_index();
|
||||
|
||||
save_button.set_sensitive (have_user_preset);
|
||||
delete_button.set_sensitive (have_user_preset);
|
||||
Plugin::PresetRecord p = plugin->last_preset();
|
||||
|
||||
++_no_load_preset;
|
||||
_preset_combo.set_active_text (p.label);
|
||||
--_no_load_preset;
|
||||
|
||||
save_button.set_sensitive (!p.uri.empty() && p.user);
|
||||
delete_button.set_sensitive (!p.uri.empty() && p.user);
|
||||
|
||||
update_preset_modified ();
|
||||
}
|
||||
|
||||
void
|
||||
PlugUIBase::update_preset_modified ()
|
||||
{
|
||||
if (plugin->last_preset().uri.empty()) {
|
||||
_preset_modified.set_text ("");
|
||||
return;
|
||||
}
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
PBD::Signal2<void,uint32_t,float> ParameterChanged;
|
||||
virtual bool has_editor () const = 0;
|
||||
|
||||
/** 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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue