From 8e747504412c62f27c599f3f5e001ff3e2e36a82 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 20 Sep 2007 02:43:59 +0000 Subject: Fix voice-specific polyphony controls. Restore patch polyphony correctly on client reattach. Fix crash on multiple polyphony changes w/ LV2 plugins. git-svn-id: http://svn.drobilla.net/lad/ingen@737 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/client/OSCClientReceiver.cpp | 9 +++++++++ src/libs/client/OSCClientReceiver.hpp | 1 + src/libs/client/PatchModel.hpp | 3 ++- src/libs/engine/LV2Node.cpp | 24 ++++++++++++++---------- src/libs/engine/MidiNoteNode.cpp | 2 ++ src/libs/engine/Patch.cpp | 2 ++ src/libs/gui/ControlPanel.cpp | 24 ++++++++++++++++++------ src/libs/gui/ControlPanel.hpp | 2 +- src/libs/gui/NodeControlWindow.cpp | 1 + src/libs/gui/NodeControlWindow.hpp | 4 ++-- src/libs/gui/ingen_gui.glade | 1 + 11 files changed, 53 insertions(+), 20 deletions(-) diff --git a/src/libs/client/OSCClientReceiver.cpp b/src/libs/client/OSCClientReceiver.cpp index c369db0e..d6ce3f81 100644 --- a/src/libs/client/OSCClientReceiver.cpp +++ b/src/libs/client/OSCClientReceiver.cpp @@ -152,6 +152,7 @@ OSCClientReceiver::setup_callbacks() lo_server_thread_add_method(_st, "/ingen/destroyed", "s", destroyed_cb, this); lo_server_thread_add_method(_st, "/ingen/patch_enabled", "s", patch_enabled_cb, this); lo_server_thread_add_method(_st, "/ingen/patch_disabled", "s", patch_disabled_cb, this); + lo_server_thread_add_method(_st, "/ingen/patch_polyphony", "si", patch_polyphony_cb, this); lo_server_thread_add_method(_st, "/ingen/patch_cleared", "s", patch_cleared_cb, this); lo_server_thread_add_method(_st, "/ingen/object_renamed", "ss", object_renamed_cb, this); lo_server_thread_add_method(_st, "/ingen/new_connection", "ss", connection_cb, this); @@ -210,6 +211,14 @@ OSCClientReceiver::_patch_disabled_cb(const char* path, const char* types, lo_ar } +int +OSCClientReceiver::_patch_polyphony_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) +{ + patch_polyphony((const char*)&argv[0]->s, argv[1]->i); + return 0; +} + + int OSCClientReceiver::_patch_cleared_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) { diff --git a/src/libs/client/OSCClientReceiver.hpp b/src/libs/client/OSCClientReceiver.hpp index 41669662..4c036ebf 100644 --- a/src/libs/client/OSCClientReceiver.hpp +++ b/src/libs/client/OSCClientReceiver.hpp @@ -93,6 +93,7 @@ private: LO_HANDLER(destroyed); LO_HANDLER(patch_enabled); LO_HANDLER(patch_disabled); + LO_HANDLER(patch_polyphony); LO_HANDLER(patch_cleared); LO_HANDLER(object_renamed); LO_HANDLER(connection); diff --git a/src/libs/client/PatchModel.hpp b/src/libs/client/PatchModel.hpp index 77b597d5..21e89cee 100644 --- a/src/libs/client/PatchModel.hpp +++ b/src/libs/client/PatchModel.hpp @@ -69,6 +69,7 @@ public: sigc::signal > signal_removed_connection; sigc::signal signal_enabled; sigc::signal signal_disabled; + sigc::signal signal_polyphony; sigc::signal signal_editable; private: @@ -83,7 +84,7 @@ private: } void filename(const string& f) { _filename = f; } - void poly(size_t p) { _poly = p; } + void poly(size_t p) { _poly = p; signal_polyphony.emit(p); } void enable(); void disable(); void clear(); diff --git a/src/libs/engine/LV2Node.cpp b/src/libs/engine/LV2Node.cpp index c8c13f38..146bc4bf 100644 --- a/src/libs/engine/LV2Node.cpp +++ b/src/libs/engine/LV2Node.cpp @@ -43,9 +43,11 @@ LV2Node::LV2Node(const Plugin* plugin, Patch* parent, SampleRate srate, size_t buffer_size) -: NodeBase(plugin, name, poly, parent, srate, buffer_size), - _lv2_plugin(plugin->slv2_plugin()), - _instances(NULL) + : NodeBase(plugin, name, poly, parent, srate, buffer_size) + , _lv2_plugin(plugin->slv2_plugin()) + , _instances(NULL) + , _prepared_instances(NULL) + , _prepared_poly(poly) { assert(_lv2_plugin); } @@ -83,13 +85,15 @@ LV2Node::apply_poly(Raul::Maid& maid, uint32_t poly) NodeBase::apply_poly(maid, poly); - maid.push(_instances); - _instances = _prepared_instances; - - for (uint32_t port=0; port < num_ports(); ++port) - for (uint32_t voice = _polyphony; voice < _prepared_poly; ++voice) - slv2_instance_connect_port((*_instances)[voice], port, - _ports->at(port)->buffer(voice)->raw_data()); + if (_prepared_instances) { + maid.push(_instances); + _instances = _prepared_instances; + + for (uint32_t port=0; port < num_ports(); ++port) + for (uint32_t voice = _polyphony; voice < _prepared_poly; ++voice) + slv2_instance_connect_port((*_instances)[voice], port, + _ports->at(port)->buffer(voice)->raw_data()); + } _polyphony = poly; _prepared_instances = NULL; diff --git a/src/libs/engine/MidiNoteNode.cpp b/src/libs/engine/MidiNoteNode.cpp index 91c9d542..03dc01b3 100644 --- a/src/libs/engine/MidiNoteNode.cpp +++ b/src/libs/engine/MidiNoteNode.cpp @@ -38,6 +38,8 @@ namespace Ingen { MidiNoteNode::MidiNoteNode(const string& path, uint32_t poly, Patch* parent, SampleRate srate, size_t buffer_size) : InternalNode(new Plugin(Plugin::Internal, "ingen:note_node"), path, poly, parent, srate, buffer_size), _voices(new Raul::Array(poly)), + _prepared_voices(NULL), + _prepared_poly(poly), _sustain(false) { _ports = new Raul::Array(5); diff --git a/src/libs/engine/Patch.cpp b/src/libs/engine/Patch.cpp index 77b043eb..3d8e7756 100644 --- a/src/libs/engine/Patch.cpp +++ b/src/libs/engine/Patch.cpp @@ -129,6 +129,8 @@ Patch::apply_internal_poly(Raul::Maid& maid, uint32_t poly) for (Raul::List::iterator i = _nodes.begin(); i != _nodes.end(); ++i) (*i)->apply_poly(maid, poly); + + _internal_poly = poly; return true; } diff --git a/src/libs/gui/ControlPanel.cpp b/src/libs/gui/ControlPanel.cpp index 5a4fbb95..be524814 100644 --- a/src/libs/gui/ControlPanel.cpp +++ b/src/libs/gui/ControlPanel.cpp @@ -39,9 +39,11 @@ ControlPanel::ControlPanel(BaseObjectType* cobject, const Glib::RefPtrget_widget("control_panel_specific_voice_radio", _specific_voice_radio); xml->get_widget("control_panel_voice_spinbutton", _voice_spinbutton); - _all_voices_radio->signal_toggled().connect(sigc::mem_fun(this, &ControlPanel::all_voices_selected)); - _specific_voice_radio->signal_toggled().connect(sigc::mem_fun(this, &ControlPanel::specific_voice_selected)); - _voice_spinbutton->signal_value_changed().connect(sigc::mem_fun(this, &ControlPanel::voice_selected)); + _all_voices_radio->signal_toggled().connect( + sigc::mem_fun(this, &ControlPanel::all_voices_selected)); + + _specific_voice_radio->signal_toggled().connect( + sigc::mem_fun(this, &ControlPanel::specific_voice_selected)); show_all(); } @@ -60,15 +62,23 @@ ControlPanel::init(SharedPtr node, uint32_t poly) assert(node != NULL); assert(poly > 0); - if (poly > 1) { + if (node->polyphonic()) { _voice_spinbutton->set_range(0, poly - 1); + _voice_control_box->show(); } else { - remove(*_voice_control_box); + //remove(*_voice_control_box); + _voice_control_box->hide(); } for (PortModelList::const_iterator i = node->ports().begin(); i != node->ports().end(); ++i) { add_port(*i); } + + if (node->parent()) + ((PatchModel*)node->parent().get())->signal_polyphony.connect( + sigc::mem_fun(this, &ControlPanel::polyphony_changed)); + else + cerr << "[ControlPanel] No parent, polyphonic controls disabled" << endl; _callback_enabled = true; } @@ -254,8 +264,10 @@ ControlPanel::specific_voice_selected() void -ControlPanel::voice_selected() +ControlPanel::polyphony_changed(uint32_t poly) { + cerr << "POLY CHANGED" << endl; + _voice_spinbutton->set_range(0, poly - 1); } diff --git a/src/libs/gui/ControlPanel.hpp b/src/libs/gui/ControlPanel.hpp index 1c206c52..bab865b2 100644 --- a/src/libs/gui/ControlPanel.hpp +++ b/src/libs/gui/ControlPanel.hpp @@ -73,7 +73,7 @@ public: private: void all_voices_selected(); void specific_voice_selected(); - void voice_selected(); + void polyphony_changed(uint32_t poly); bool _callback_enabled; diff --git a/src/libs/gui/NodeControlWindow.cpp b/src/libs/gui/NodeControlWindow.cpp index 482f2c3b..853a15bb 100644 --- a/src/libs/gui/NodeControlWindow.cpp +++ b/src/libs/gui/NodeControlWindow.cpp @@ -48,6 +48,7 @@ NodeControlWindow::NodeControlWindow(SharedPtr node, uint32_t poly) Glib::RefPtr xml = GladeFactory::new_glade_reference("warehouse_win"); xml->get_widget_derived("control_panel_vbox", _control_panel); + _control_panel->reparent(*this); _control_panel->init(_node, poly); diff --git a/src/libs/gui/NodeControlWindow.hpp b/src/libs/gui/NodeControlWindow.hpp index a749fe86..84e462c5 100644 --- a/src/libs/gui/NodeControlWindow.hpp +++ b/src/libs/gui/NodeControlWindow.hpp @@ -61,8 +61,8 @@ protected: private: SharedPtr _node; - ControlPanel* _control_panel; - bool _callback_enabled; + ControlPanel* _control_panel; + bool _callback_enabled; bool _position_stored; int _x; diff --git a/src/libs/gui/ingen_gui.glade b/src/libs/gui/ingen_gui.glade index 849f5f8a..8d1b157e 100644 --- a/src/libs/gui/ingen_gui.glade +++ b/src/libs/gui/ingen_gui.glade @@ -1210,6 +1210,7 @@ True + True True Apply changed controls to all voices All Voices -- cgit v1.2.1