From 49d6f5b2cc495052d6c5ddbb0629e178c9a2cc14 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 19 Sep 2007 02:46:47 +0000 Subject: More work on dynamic polyphony. git-svn-id: http://svn.drobilla.net/lad/ingen@721 a436a847-0d15-0410-975c-d299462d15a1 --- src/common/interface/EngineInterface.hpp | 4 + src/libs/client/OSCClientReceiver.cpp | 1 + src/libs/client/OSCEngineSender.cpp | 27 + src/libs/client/OSCEngineSender.hpp | 4 + src/libs/engine/LV2Node.cpp | 54 +- src/libs/engine/LV2Node.hpp | 11 +- src/libs/engine/Makefile.am | 4 + src/libs/engine/Node.hpp | 7 +- src/libs/engine/NodeBase.cpp | 8 +- src/libs/engine/NodeBase.hpp | 4 +- src/libs/engine/OSCEngineReceiver.cpp | 52 +- src/libs/engine/OSCEngineReceiver.hpp | 1 + src/libs/engine/Patch.cpp | 26 + src/libs/engine/Patch.hpp | 16 + src/libs/engine/Port.cpp | 9 +- src/libs/engine/Port.hpp | 4 +- src/libs/engine/QueuedEngineInterface.cpp | 14 + src/libs/engine/QueuedEngineInterface.hpp | 4 + src/libs/engine/QueuedEventSource.cpp | 12 - src/libs/engine/QueuedEventSource.hpp | 12 + src/libs/engine/events.hpp | 42 +- src/libs/engine/events/AddPortEvent.cpp | 6 +- src/libs/engine/events/ClearPatchEvent.cpp | 2 +- src/libs/engine/events/DestroyEvent.cpp | 6 +- src/libs/engine/events/LoadPluginsEvent.cpp | 2 +- src/libs/engine/events/Makefile.am | 4 + src/libs/gui/PatchView.cpp | 11 +- src/libs/gui/PatchView.hpp | 1 + src/libs/gui/ingen_gui.glade | 918 ++++++++++++++-------------- 29 files changed, 720 insertions(+), 546 deletions(-) (limited to 'src') diff --git a/src/common/interface/EngineInterface.hpp b/src/common/interface/EngineInterface.hpp index 192357a7..3d28bbd2 100644 --- a/src/common/interface/EngineInterface.hpp +++ b/src/common/interface/EngineInterface.hpp @@ -80,6 +80,10 @@ public: virtual void destroy(const string& path) = 0; virtual void clear_patch(const string& patch_path) = 0; + + virtual void set_polyphony(const string& patch_path, uint32_t poly) = 0; + + virtual void set_polyphonic(const string& path, bool poly) = 0; virtual void enable_patch(const string& patch_path) = 0; diff --git a/src/libs/client/OSCClientReceiver.cpp b/src/libs/client/OSCClientReceiver.cpp index 0479cea9..de51ad22 100644 --- a/src/libs/client/OSCClientReceiver.cpp +++ b/src/libs/client/OSCClientReceiver.cpp @@ -32,6 +32,7 @@ namespace Client { OSCClientReceiver::OSCClientReceiver(int listen_port) : ClientInterface("localhost"), + _listen_port(listen_port), _st(NULL)//, // _receiving_node(false), // _receiving_node_model(NULL), diff --git a/src/libs/client/OSCEngineSender.cpp b/src/libs/client/OSCEngineSender.cpp index 76b094a0..89939b6b 100644 --- a/src/libs/client/OSCEngineSender.cpp +++ b/src/libs/client/OSCEngineSender.cpp @@ -253,6 +253,33 @@ OSCEngineSender::clear_patch(const string& patch_path) patch_path.c_str()); } + +void +OSCEngineSender::set_polyphony(const string& patch_path, uint32_t poly) +{ + assert(_engine_addr); + lo_send(_engine_addr, "/ingen/set_polyphony", "isi", + next_id(), + patch_path.c_str(), + poly); +} + + +void +OSCEngineSender::set_polyphonic(const string& path, bool poly) +{ + assert(_engine_addr); + if (poly) { + lo_send(_engine_addr, "/ingen/set_polyphony", "isT", + next_id(), + path.c_str()); + } else { + lo_send(_engine_addr, "/ingen/set_polyphony", "isF", + next_id(), + path.c_str()); + } +} + void OSCEngineSender::enable_patch(const string& patch_path) diff --git a/src/libs/client/OSCEngineSender.hpp b/src/libs/client/OSCEngineSender.hpp index fc3c100d..c3a9b46a 100644 --- a/src/libs/client/OSCEngineSender.hpp +++ b/src/libs/client/OSCEngineSender.hpp @@ -94,6 +94,10 @@ public: void destroy(const string& path); void clear_patch(const string& patch_path); + + void set_polyphony(const string& patch_path, uint32_t poly); + + void set_polyphonic(const string& path, bool poly); void enable_patch(const string& patch_path); diff --git a/src/libs/engine/LV2Node.cpp b/src/libs/engine/LV2Node.cpp index 36bfd319..8e2e9b81 100644 --- a/src/libs/engine/LV2Node.cpp +++ b/src/libs/engine/LV2Node.cpp @@ -15,12 +15,13 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "LV2Node.hpp" +#include #include #include #include #include #include +#include "LV2Node.hpp" #include "InputPort.hpp" #include "OutputPort.hpp" #include "Plugin.hpp" @@ -50,17 +51,44 @@ LV2Node::LV2Node(const Plugin* plugin, } -void +bool LV2Node::prepare_poly(uint32_t poly) { NodeBase::prepare_poly(poly); + + if (poly <= _prepared_poly) + return true; + + _prepared_poly = poly; + _prepared_instances = new Raul::Array(_prepared_poly, *_instances); + for (uint32_t i=_poly; i < _prepared_poly; ++i) { + _prepared_instances->at(i) = slv2_plugin_instantiate(_lv2_plugin, _srate, NULL); + if ((*_instances)[i] == NULL) { + cerr << "Failed to instantiate plugin!" << endl; + return false; + } + } + + for (uint32_t j=0; j < num_ports(); ++j) + _ports->at(j)->prepare_poly(poly); + + return true; } -void +bool LV2Node::apply_poly(Raul::Maid& maid, uint32_t poly) { + assert(poly <= _prepared_poly); + NodeBase::apply_poly(maid, poly); + + maid.push(_instances); + _instances = _prepared_instances; + _poly = poly; + _prepared_instances = NULL; + + return true; } @@ -80,13 +108,13 @@ LV2Node::instantiate() _ports = new Raul::Array(num_ports); - _instances = new SLV2Instance[_poly]; + _instances = new Raul::Array(_poly); uint32_t port_buffer_size = 0; for (uint32_t i=0; i < _poly; ++i) { - _instances[i] = slv2_plugin_instantiate(_lv2_plugin, _srate, NULL); - if (_instances[i] == NULL) { + (*_instances)[i] = slv2_plugin_instantiate(_lv2_plugin, _srate, NULL); + if ((*_instances)[i] == NULL) { cerr << "Failed to instantiate plugin!" << endl; return false; } @@ -156,7 +184,7 @@ LV2Node::instantiate() LV2Node::~LV2Node() { for (uint32_t i=0; i < _poly; ++i) - slv2_instance_free(_instances[i]); + slv2_instance_free((*_instances)[i]); delete[] _instances; } @@ -180,7 +208,7 @@ LV2Node::activate() ((AudioBuffer*)port->buffer(i))->set(0.0f, 0); } } - slv2_instance_activate(_instances[i]); + slv2_instance_activate((*_instances)[i]); } } @@ -191,7 +219,7 @@ LV2Node::deactivate() NodeBase::deactivate(); for (uint32_t i=0; i < _poly; ++i) - slv2_instance_deactivate(_instances[i]); + slv2_instance_deactivate((*_instances)[i]); } @@ -201,7 +229,7 @@ LV2Node::process(SampleCount nframes, FrameTime start, FrameTime end) NodeBase::pre_process(nframes, start, end); for (uint32_t i=0; i < _poly; ++i) - slv2_instance_run(_instances[i], nframes); + slv2_instance_run((*_instances)[i], nframes); NodeBase::post_process(nframes, start, end); } @@ -213,11 +241,11 @@ LV2Node::set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf) assert(voice < _poly); if (buf->type() == DataType::FLOAT) { - slv2_instance_connect_port(_instances[voice], port_num, ((AudioBuffer*)buf)->data()); + slv2_instance_connect_port((*_instances)[voice], port_num, ((AudioBuffer*)buf)->data()); } else if (buf->type() == DataType::MIDI) { - slv2_instance_connect_port(_instances[voice], port_num, ((MidiBuffer*)buf)->data()); + slv2_instance_connect_port((*_instances)[voice], port_num, ((MidiBuffer*)buf)->data()); } else if (buf->type() == DataType::OSC) { - slv2_instance_connect_port(_instances[voice], port_num, ((OSCBuffer*)buf)->data()); + slv2_instance_connect_port((*_instances)[voice], port_num, ((OSCBuffer*)buf)->data()); } } diff --git a/src/libs/engine/LV2Node.hpp b/src/libs/engine/LV2Node.hpp index 88ae5ffc..52f7d6a1 100644 --- a/src/libs/engine/LV2Node.hpp +++ b/src/libs/engine/LV2Node.hpp @@ -45,8 +45,8 @@ public: virtual bool instantiate(); - void prepare_poly(uint32_t poly); - void apply_poly(Raul::Maid& maid, uint32_t poly); + bool prepare_poly(uint32_t poly); + bool apply_poly(Raul::Maid& maid, uint32_t poly); void activate(); void deactivate(); @@ -58,9 +58,10 @@ public: protected: //void get_port_vals(ulong port_index, PortInfo* info); - SLV2Plugin _lv2_plugin; - SLV2Instance* _instances; - SLV2Instance* _prepared_instances; + SLV2Plugin _lv2_plugin; + Raul::Array* _instances; + Raul::Array* _prepared_instances; + uint32_t _prepared_poly; }; diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am index 8d082d50..185c7804 100644 --- a/src/libs/engine/Makefile.am +++ b/src/libs/engine/Makefile.am @@ -154,6 +154,10 @@ libingen_engine_la_SOURCES = \ events/SetMetadataEvent.hpp \ events/SetPortValueEvent.cpp \ events/SetPortValueEvent.hpp \ + events/SetPolyphonyEvent.hpp \ + events/SetPolyphonyEvent.cpp \ + events/SetPolyphonicEvent.hpp \ + events/SetPolyphonicEvent.cpp \ events/SetPortValueQueuedEvent.cpp \ events/SetPortValueQueuedEvent.hpp \ events/UnregisterClientEvent.cpp \ diff --git a/src/libs/engine/Node.hpp b/src/libs/engine/Node.hpp index ca495904..3114d369 100644 --- a/src/libs/engine/Node.hpp +++ b/src/libs/engine/Node.hpp @@ -65,17 +65,18 @@ public: /** Prepare for a new (external) polyphony value. * * Preprocessor thread, poly is actually applied by apply_poly. + * \return true on success. */ - virtual void prepare_poly(uint32_t poly) = 0; + virtual bool prepare_poly(uint32_t poly) = 0; - /** Apply a new polyphony value. + /** Apply a new (external) polyphony value. * * Audio thread. * * \param poly Must be < the most recent value passed to prepare_poly. * \param maid Any objects no longer needed will be pushed to this */ - virtual void apply_poly(Raul::Maid& maid, uint32_t poly) = 0; + virtual bool apply_poly(Raul::Maid& maid, uint32_t poly) = 0; /** Parallelism: Reset flags for start of a new cycle. */ diff --git a/src/libs/engine/NodeBase.cpp b/src/libs/engine/NodeBase.cpp index 32b641e0..35d3be4e 100644 --- a/src/libs/engine/NodeBase.cpp +++ b/src/libs/engine/NodeBase.cpp @@ -82,21 +82,25 @@ NodeBase::deactivate() } -void +bool NodeBase::prepare_poly(uint32_t poly) { if (_ports) for (size_t i=0; i < _ports->size(); ++i) _ports->at(i)->prepare_poly(poly); + + return true; } -void +bool NodeBase::apply_poly(Raul::Maid& maid, uint32_t poly) { if (_ports) for (size_t i=0; i < _ports->size(); ++i) _ports->at(i)->apply_poly(maid, poly); + + return true; } diff --git a/src/libs/engine/NodeBase.hpp b/src/libs/engine/NodeBase.hpp index ed3cd80d..e74c0d12 100644 --- a/src/libs/engine/NodeBase.hpp +++ b/src/libs/engine/NodeBase.hpp @@ -55,8 +55,8 @@ public: virtual void deactivate(); bool activated() { return _activated; } - virtual void prepare_poly(uint32_t poly); - virtual void apply_poly(Raul::Maid& maid, uint32_t poly); + virtual bool prepare_poly(uint32_t poly); + virtual bool apply_poly(Raul::Maid& maid, uint32_t poly); virtual void reset_input_ready(); virtual bool process_lock(); diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp index 75be643c..4d31d836 100644 --- a/src/libs/engine/OSCEngineReceiver.cpp +++ b/src/libs/engine/OSCEngineReceiver.cpp @@ -83,6 +83,7 @@ OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t lo_server_add_method(_server, "/ingen/enable_patch", "is", enable_patch_cb, this); lo_server_add_method(_server, "/ingen/disable_patch", "is", disable_patch_cb, this); lo_server_add_method(_server, "/ingen/clear_patch", "is", clear_patch_cb, this); + lo_server_add_method(_server, "/ingen/set_polyphony", "ii", set_polyphony_cb, this); lo_server_add_method(_server, "/ingen/create_port", "issi", create_port_cb, this); lo_server_add_method(_server, "/ingen/create_node", "issssi", create_node_cb, this); lo_server_add_method(_server, "/ingen/create_node", "issi", create_node_by_uri_cb, this); @@ -206,7 +207,7 @@ OSCEngineReceiver::set_response_address_cb(const char* path, const char* types, if (argc < 1 || types[0] != 'i') // Not a valid Ingen message return 0; // Save liblo the trouble - const int id = argv[0]->i; + const int32_t id = argv[0]->i; const lo_address addr = lo_message_get_source(msg); char* const url = lo_address_get_url(addr); @@ -367,8 +368,8 @@ OSCEngineReceiver::_engine_deactivate_cb(const char* path, const char* types, lo int OSCEngineReceiver::_create_patch_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) { - const char* patch_path = &argv[1]->s; - const int poly = argv[2]->i; + const char* patch_path = &argv[1]->s; + const int32_t poly = argv[2]->i; create_patch(patch_path, poly); return 0; @@ -437,6 +438,23 @@ OSCEngineReceiver::_clear_patch_cb(const char* path, const char* types, lo_arg** } +/** \page engine_osc_namespace + *

\b /ingen/set_polyphony - Set the polyphony of a patch + * \arg \b response-id (integer) + * \arg \b patch-path - Patch's path + * \arg \b poly (integer)

\n \n + */ +int +OSCEngineReceiver::_set_polyphony_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) +{ + const char* patch_path = &argv[1]->s; + const uint32_t poly = argv[1]->i; + + set_polyphony(patch_path, poly); + return 0; +} + + /** \page engine_osc_namespace *

\b /ingen/create_port - Add a port into a given patch (load a plugin by URI) * \arg \b response-id (integer) @@ -447,9 +465,9 @@ OSCEngineReceiver::_clear_patch_cb(const char* path, const char* types, lo_arg** int OSCEngineReceiver::_create_port_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) { - const char* port_path = &argv[1]->s; - const char* data_type = &argv[2]->s; - const int direction = argv[3]->i; + const char* port_path = &argv[1]->s; + const char* data_type = &argv[2]->s; + const int32_t direction = argv[3]->i; create_port(port_path, data_type, (direction == 1)); return 0; @@ -465,9 +483,9 @@ OSCEngineReceiver::_create_port_cb(const char* path, const char* types, lo_arg** int OSCEngineReceiver::_create_node_by_uri_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) { - const char* node_path = &argv[1]->s; - const char* plug_uri = &argv[2]->s; - const int poly = argv[3]->i; + const char* node_path = &argv[1]->s; + const char* plug_uri = &argv[2]->s; + const int32_t poly = argv[3]->i; // FIXME: make sure poly is valid @@ -492,11 +510,11 @@ OSCEngineReceiver::_create_node_by_uri_cb(const char* path, const char* types, l int OSCEngineReceiver::_create_node_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) { - const char* node_path = &argv[1]->s; - const char* type = &argv[2]->s; - const char* lib_name = &argv[3]->s; - const char* plug_label = &argv[4]->s; - const int poly = argv[5]->i; + const char* node_path = &argv[1]->s; + const char* type = &argv[2]->s; + const char* lib_name = &argv[3]->s; + const char* plug_label = &argv[4]->s; + const int32_t poly = argv[5]->i; create_node(node_path, type, lib_name, plug_label, (poly == 1)); return 0; @@ -594,9 +612,9 @@ OSCEngineReceiver::_set_port_value_cb(const char* path, const char* types, lo_ar int OSCEngineReceiver::_set_port_value_voice_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) { - const char* port_path = &argv[1]->s; - const int voice = argv[2]->i; - const float value = argv[3]->f; + const char* port_path = &argv[1]->s; + const int32_t voice = argv[2]->i; + const float value = argv[3]->f; set_port_value(port_path, voice, value); return 0; diff --git a/src/libs/engine/OSCEngineReceiver.hpp b/src/libs/engine/OSCEngineReceiver.hpp index c08386ec..559a56b2 100644 --- a/src/libs/engine/OSCEngineReceiver.hpp +++ b/src/libs/engine/OSCEngineReceiver.hpp @@ -92,6 +92,7 @@ private: LO_HANDLER(enable_patch); LO_HANDLER(disable_patch); LO_HANDLER(clear_patch); + LO_HANDLER(set_polyphony); LO_HANDLER(destroy); LO_HANDLER(connect); LO_HANDLER(disconnect); diff --git a/src/libs/engine/Patch.cpp b/src/libs/engine/Patch.cpp index a03f2415..e8833da8 100644 --- a/src/libs/engine/Patch.cpp +++ b/src/libs/engine/Patch.cpp @@ -107,6 +107,32 @@ Patch::disable() (*i)->clear_buffers(); } + +bool +Patch::prepare_internal_poly(uint32_t poly) +{ + /* TODO: ports? internal/external poly? */ + + for (Raul::List::iterator i = _nodes.begin(); i != _nodes.end(); ++i) + (*i)->prepare_poly(poly); + + /* FIXME: Deal with failure */ + + return true; +} + + +bool +Patch::apply_internal_poly(Raul::Maid& maid, uint32_t poly) +{ + /* TODO: ports? internal/external poly? */ + + for (Raul::List::iterator i = _nodes.begin(); i != _nodes.end(); ++i) + (*i)->apply_poly(maid, poly); + + return true; +} + /** Run the patch for the specified number of frames. * diff --git a/src/libs/engine/Patch.hpp b/src/libs/engine/Patch.hpp index 8d17ee7c..32a02f76 100644 --- a/src/libs/engine/Patch.hpp +++ b/src/libs/engine/Patch.hpp @@ -58,6 +58,22 @@ public: void set_buffer_size(size_t size); + /** Prepare for a new (internal) polyphony value. + * + * Preprocessor thread, poly is actually applied by apply_internal_poly. + * \return true on success. + */ + bool prepare_internal_poly(uint32_t poly); + + /** Apply a new (internal) polyphony value. + * + * Audio thread. + * + * \param poly Must be < the most recent value passed to prepare_internal_poly. + * \param maid Any objects no longer needed will be pushed to this + */ + bool apply_internal_poly(Raul::Maid& maid, uint32_t poly); + // Patch specific stuff not inherited from Node void add_node(Raul::ListNode* tn); diff --git a/src/libs/engine/Port.cpp b/src/libs/engine/Port.cpp index 8f9e9ce7..fe9e2c09 100644 --- a/src/libs/engine/Port.cpp +++ b/src/libs/engine/Port.cpp @@ -37,6 +37,7 @@ Port::Port(Node* const node, const string& name, uint32_t index, uint32_t poly, , _type(type) , _buffer_size(buffer_size) , _fixed_buffers(false) + , _buffers(new Raul::Array(poly)) { assert(node != NULL); assert(_poly > 0); @@ -55,7 +56,7 @@ Port::~Port() } -void +bool Port::prepare_poly(uint32_t poly) { /* FIXME: poly never goes down, harsh on memory.. */ @@ -65,10 +66,12 @@ Port::prepare_poly(uint32_t poly) for (uint32_t i = _poly; i < _prepared_poly; ++i) _buffers->at(i) = BufferFactory::create(_type, _buffer_size); } + + return true; } -void +bool Port::apply_poly(Raul::Maid& maid, uint32_t poly) { assert(poly <= _prepared_poly); @@ -80,6 +83,8 @@ Port::apply_poly(Raul::Maid& maid, uint32_t poly) } _poly = poly; + + return true; } diff --git a/src/libs/engine/Port.hpp b/src/libs/engine/Port.hpp index 5b1c86b2..64fde9cc 100644 --- a/src/libs/engine/Port.hpp +++ b/src/libs/engine/Port.hpp @@ -53,7 +53,7 @@ public: * * Preprocessor thread, poly is actually applied by apply_poly. */ - virtual void prepare_poly(uint32_t poly); + virtual bool prepare_poly(uint32_t poly); /** Apply a new polyphony value. * @@ -61,7 +61,7 @@ public: * * \param poly Must be < the most recent value passed to prepare_poly. */ - virtual void apply_poly(Raul::Maid& maid, uint32_t poly); + virtual bool apply_poly(Raul::Maid& maid, uint32_t poly); Buffer* buffer(uint32_t voice) const { return _buffers->at(voice); } diff --git a/src/libs/engine/QueuedEngineInterface.cpp b/src/libs/engine/QueuedEngineInterface.cpp index 511246da..badbf78d 100644 --- a/src/libs/engine/QueuedEngineInterface.cpp +++ b/src/libs/engine/QueuedEngineInterface.cpp @@ -178,6 +178,20 @@ QueuedEngineInterface::clear_patch(const string& patch_path) push_queued(new ClearPatchEvent(_engine, _responder, now(), this, patch_path)); } + +void +QueuedEngineInterface::set_polyphony(const string& patch_path, uint32_t poly) +{ + push_queued(new SetPolyphonyEvent(_engine, _responder, now(), this, patch_path, poly)); +} + + +void +QueuedEngineInterface::set_polyphonic(const string& path, bool poly) +{ + push_queued(new SetPolyphonicEvent(_engine, _responder, now(), this, path, poly)); +} + void QueuedEngineInterface::enable_patch(const string& patch_path) diff --git a/src/libs/engine/QueuedEngineInterface.hpp b/src/libs/engine/QueuedEngineInterface.hpp index eb19923e..396615c0 100644 --- a/src/libs/engine/QueuedEngineInterface.hpp +++ b/src/libs/engine/QueuedEngineInterface.hpp @@ -101,6 +101,10 @@ public: virtual void destroy(const string& path); virtual void clear_patch(const string& patch_path); + + virtual void set_polyphony(const string& patch_path, uint32_t poly); + + virtual void set_polyphonic(const string& path, bool poly); virtual void enable_patch(const string& patch_path); diff --git a/src/libs/engine/QueuedEventSource.cpp b/src/libs/engine/QueuedEventSource.cpp index ac03ef16..634b94da 100644 --- a/src/libs/engine/QueuedEventSource.cpp +++ b/src/libs/engine/QueuedEventSource.cpp @@ -145,18 +145,6 @@ QueuedEventSource::pop_earliest_queued_before(const SampleCount time) // Private // -/** Signal that the blocking event is finished. - * - * When this is called preparing will resume. This MUST be called by - * blocking events in their post_process() method. - */ -void -QueuedEventSource::unblock() -{ - _blocking_semaphore.post(); -} - - /** Pre-process a single event */ void QueuedEventSource::_whipped() diff --git a/src/libs/engine/QueuedEventSource.hpp b/src/libs/engine/QueuedEventSource.hpp index df1a4824..d4cbc1ab 100644 --- a/src/libs/engine/QueuedEventSource.hpp +++ b/src/libs/engine/QueuedEventSource.hpp @@ -105,6 +105,18 @@ QueuedEventSource::pop_earliest_stamped_before(const SampleCount time) } +/** Signal that the blocking event is finished. + * + * When this is called preparing will resume. This MUST be called by + * blocking events in their post_process() method. + */ +inline void +QueuedEventSource::unblock() +{ + _blocking_semaphore.post(); +} + + } // namespace Ingen #endif // QUEUEDEVENTSOURCE_H diff --git a/src/libs/engine/events.hpp b/src/libs/engine/events.hpp index 84bde550..2660c6c1 100644 --- a/src/libs/engine/events.hpp +++ b/src/libs/engine/events.hpp @@ -20,35 +20,37 @@ #include CONFIG_H_PATH -#include "DeactivateEvent.hpp" -#include "EnablePatchEvent.hpp" -#include "DisablePatchEvent.hpp" +#include "AddNodeEvent.hpp" +#include "AddPortEvent.hpp" +#include "AllNotesOffEvent.hpp" #include "ClearPatchEvent.hpp" -#include "SetPortValueEvent.hpp" -#include "SetPortValueQueuedEvent.hpp" #include "ConnectionEvent.hpp" -#include "DisconnectionEvent.hpp" -#include "AddPortEvent.hpp" -#include "AddNodeEvent.hpp" #include "CreatePatchEvent.hpp" +#include "DeactivateEvent.hpp" #include "DestroyEvent.hpp" -#include "SetMetadataEvent.hpp" +#include "DisablePatchEvent.hpp" +#include "DisconnectionEvent.hpp" +#include "DisconnectNodeEvent.hpp" +#include "EnablePatchEvent.hpp" +#include "LoadPluginsEvent.hpp" +#include "MidiLearnEvent.hpp" +#include "NoteOffEvent.hpp" +#include "NoteOnEvent.hpp" +#include "PingQueuedEvent.hpp" +#include "RegisterClientEvent.hpp" +#include "RenameEvent.hpp" +#include "RequestAllObjectsEvent.hpp" #include "RequestMetadataEvent.hpp" #include "RequestObjectEvent.hpp" #include "RequestPluginEvent.hpp" -#include "RequestPortValueEvent.hpp" -#include "RequestAllObjectsEvent.hpp" #include "RequestPluginsEvent.hpp" -#include "LoadPluginsEvent.hpp" -#include "NoteOnEvent.hpp" -#include "NoteOffEvent.hpp" -#include "AllNotesOffEvent.hpp" -#include "DisconnectNodeEvent.hpp" -#include "RegisterClientEvent.hpp" +#include "RequestPortValueEvent.hpp" +#include "SetMetadataEvent.hpp" +#include "SetPolyphonyEvent.hpp" +#include "SetPolyphonicEvent.hpp" +#include "SetPortValueEvent.hpp" +#include "SetPortValueQueuedEvent.hpp" #include "UnregisterClientEvent.hpp" -#include "RenameEvent.hpp" -#include "PingQueuedEvent.hpp" -#include "MidiLearnEvent.hpp" #ifdef HAVE_DSSI #include "DSSIUpdateEvent.hpp" diff --git a/src/libs/engine/events/AddPortEvent.cpp b/src/libs/engine/events/AddPortEvent.cpp index 1d016c5d..28273815 100644 --- a/src/libs/engine/events/AddPortEvent.cpp +++ b/src/libs/engine/events/AddPortEvent.cpp @@ -154,15 +154,15 @@ AddPortEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) _engine.midi_driver()->add_port(_driver_port); else if (_type == "ingen:osc") cerr << "OSC DRIVER PORT" << endl; + + if (_source) + _source->unblock(); } void AddPortEvent::post_process() { - if (_source) - _source->unblock(); - if (!_patch_port) { const string msg = string("Could not create port - ").append(_path); _responder->respond_error(msg); diff --git a/src/libs/engine/events/ClearPatchEvent.cpp b/src/libs/engine/events/ClearPatchEvent.cpp index 5a914901..aa72cd54 100644 --- a/src/libs/engine/events/ClearPatchEvent.cpp +++ b/src/libs/engine/events/ClearPatchEvent.cpp @@ -113,7 +113,7 @@ ClearPatchEvent::post_process() _responder->respond_error(string("Patch ") + _patch_path + " not found"); } - _source->unblock(); + _source->unblock(); // FIXME: can be done earlier in execute? } diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp index ba4da6ec..38a8fe3e 100644 --- a/src/libs/engine/events/DestroyEvent.cpp +++ b/src/libs/engine/events/DestroyEvent.cpp @@ -192,15 +192,15 @@ DestroyEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) _driver_port = _engine.midi_driver()->remove_port(_port->path()); } } + + if (_source) + _source->unblock(); } void DestroyEvent::post_process() { - if (_source) - _source->unblock(); - if (_store_iterator != _engine.object_store()->objects().end()) { _engine.broadcaster()->send_destroyed(_path); } else { diff --git a/src/libs/engine/events/LoadPluginsEvent.cpp b/src/libs/engine/events/LoadPluginsEvent.cpp index 2eae055a..df5ff5d9 100644 --- a/src/libs/engine/events/LoadPluginsEvent.cpp +++ b/src/libs/engine/events/LoadPluginsEvent.cpp @@ -31,7 +31,7 @@ namespace Ingen { LoadPluginsEvent::LoadPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, QueuedEventSource* source) : QueuedEvent(engine, responder, timestamp, true, source) { - /* Not sure why this has to be blocking, but it fixes some nasty bugs.. */ + /* FIXME: Not sure why this has to be blocking, but it fixes some nasty bugs.. */ } void diff --git a/src/libs/engine/events/Makefile.am b/src/libs/engine/events/Makefile.am index bc698678..f3190756 100644 --- a/src/libs/engine/events/Makefile.am +++ b/src/libs/engine/events/Makefile.am @@ -60,6 +60,10 @@ EXTRA_DIST = \ RequestPortValueEvent.hpp \ SetMetadataEvent.cpp \ SetMetadataEvent.hpp \ + SetPolyphonyEvent.hpp \ + SetPolyphonyEvent.cpp \ + SetPolyphonicEvent.hpp \ + SetPolyphonicEvent.cpp \ SetPortValueEvent.cpp \ SetPortValueEvent.hpp \ SetPortValueQueuedEvent.cpp \ diff --git a/src/libs/gui/PatchView.cpp b/src/libs/gui/PatchView.cpp index 0a624dc0..c313f5ac 100644 --- a/src/libs/gui/PatchView.cpp +++ b/src/libs/gui/PatchView.cpp @@ -95,7 +95,9 @@ PatchView::set_patch(SharedPtr patch) _edit_mode_but->signal_toggled().connect(sigc::mem_fun( *this, &PatchView::editable_toggled)); - + + _poly_spin->signal_value_changed().connect( + sigc::mem_fun(*this, &PatchView::poly_changed)); _canvas->grab_focus(); } @@ -153,6 +155,13 @@ PatchView::process_toggled() } +void +PatchView::poly_changed() +{ + App::instance().engine()->set_polyphony(_patch->path(), _poly_spin->get_value_as_int()); +} + + void PatchView::clear_clicked() { diff --git a/src/libs/gui/PatchView.hpp b/src/libs/gui/PatchView.hpp index dcc2ffcc..7952ee72 100644 --- a/src/libs/gui/PatchView.hpp +++ b/src/libs/gui/PatchView.hpp @@ -69,6 +69,7 @@ private: void set_patch(SharedPtr patch); void process_toggled(); + void poly_changed(); void clear_clicked(); void refresh_clicked(); void on_editable_sig(bool locked); diff --git a/src/libs/gui/ingen_gui.glade b/src/libs/gui/ingen_gui.glade index 402be871..fbe6fedd 100644 --- a/src/libs/gui/ingen_gui.glade +++ b/src/libs/gui/ingen_gui.glade @@ -481,62 +481,53 @@ 3 12 - + True - True - Clear filter text (show all plugins) - gtk-clear - True - 0 + 1 + Node Name: + True - 2 - 3 + 2 + 3 GTK_FILL - + True - Name contains: + 1 + 2 + 1 + 2 GTK_FILL - - + True - True - True - Search string to filter plugin list - * - 1 - 2 - 6 + 1 + 2 + GTK_FILL + GTK_FILL - + True - False - True - Add selected plugin to patch - gtk-add - True - 0 2 3 - 2 - 3 + 1 + 2 GTK_FILL - + GTK_FILL @@ -579,51 +570,60 @@ - + True + False + True + Add selected plugin to patch + gtk-add + True + 0 2 3 - 1 - 2 + 2 + 3 GTK_FILL - GTK_FILL + - + True + True + True + Search string to filter plugin list + * - 1 - 2 - GTK_FILL - GTK_FILL + 1 + 2 + 6 - + True + Name contains: - 1 - 2 - 1 - 2 GTK_FILL + - + True - 1 - Node Name: - True + True + Clear filter text (show all plugins) + gtk-clear + True + 0 - 2 - 3 + 2 + 3 GTK_FILL @@ -654,61 +654,61 @@ 2 2 - + True - True - True - * - True + 0 + Name: - 1 - 2 - - 4 + GTK_FILL + GTK_EXPAND + 5 - + True - True - 1 0 100 1 10 10 - 1 + 0 + Polyphony: - 1 - 2 1 2 GTK_FILL - - 4 + GTK_EXPAND + 5 - + True - 0 - Polyphony: + True + 1 0 100 1 10 10 + 1 + 1 + 2 1 2 GTK_FILL - GTK_EXPAND - 5 + + 4 - + True - 0 - Name: + True + True + * + True - GTK_FILL - GTK_EXPAND - 5 + 1 + 2 + + 4 @@ -810,71 +810,63 @@ 12 4 - + True - - - True - True - Specify the name for the new patch - Specify: - True - 0 - True - load_subpatch_name_from_file_radio - - - False - False - - - - - True - False - True - Specify the name for the new patch - * - True - - - False - 1 - - + 0 + <b>Name: </b> + True - 3 - 4 - GTK_FILL + GTK_FILL + - + True 0 + <b>Polyphony: </b> + True - 2 - 3 + 1 + 2 GTK_FILL - + True True - Set polyphony to the same value as the parent (containing) patch - Same as parent (?) + Use the name stored in the patch file + Load from file True 0 + True True - load_subpatch_poly_from_file_radio - 2 - 3 + 1 + 2 + GTK_FILL + + + + + + True + True + Use the polyphony value stored in the patch file + Load from file + True + 0 + True + True + + + 1 + 2 1 2 GTK_FILL @@ -925,19 +917,19 @@ - + True True - Use the polyphony value stored in the patch file - Load from file + Set polyphony to the same value as the parent (containing) patch + Same as parent (?) True 0 - True True + load_subpatch_poly_from_file_radio - 1 - 2 + 2 + 3 1 2 GTK_FILL @@ -945,47 +937,55 @@ - - True - True - Use the name stored in the patch file - Load from file - True - 0 - True - True - - - 1 - 2 - GTK_FILL - - - - - + True 0 - <b>Polyphony: </b> - True - 1 - 2 + 2 + 3 GTK_FILL - + True - 0 - <b>Name: </b> - True + + + True + True + Specify the name for the new patch + Specify: + True + 0 + True + load_subpatch_name_from_file_radio + + + False + False + + + + + True + False + True + Specify the name for the new patch + * + True + + + False + 1 + + - GTK_FILL - + 3 + 4 + GTK_FILL @@ -1047,91 +1047,91 @@ 12 4 - + True - - - True - True - Specify: - True - 0 - True - load_patch_poly_from_current_radio - - - False - False - - - - - True - False - True - Specify a custom polyphony value for new patch - 1 0 100 1 10 10 - 1 - - - False - 1 - - + 0 + <b>Polyphony: </b> + True - 3 - 4 GTK_FILL - GTK_FILL + - + True True - Use the polyphony value stored in the patch file - Load from file + Use the same polyphony as the current patch + Keep current True 0 + True True - load_patch_poly_from_current_radio - 2 - 3 + 1 + 2 GTK_FILL - + True True - Use the same polyphony as the current patch - Keep current + Use the polyphony value stored in the patch file + Load from file True 0 - True True + load_patch_poly_from_current_radio - 1 - 2 + 2 + 3 GTK_FILL - + True - 0 - <b>Polyphony: </b> - True + + + True + True + Specify: + True + 0 + True + load_patch_poly_from_current_radio + + + False + False + + + + + True + False + True + Specify a custom polyphony value for new patch + 1 0 100 1 10 10 + 1 + + + False + 1 + + + 3 + 4 GTK_FILL - + GTK_FILL @@ -1197,22 +1197,46 @@ - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 - + True - 0 - 4 - 4 - <b>Name</b> - True - True + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + + + True + GTK_SHADOW_NONE + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + + + + + + + + True + True + + + True + Apply changed controls to all voices + All Voices + True + 0 + True False @@ -1220,67 +1244,54 @@ - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 1 - 1 - 0 - 0 - 2 - 2 - 2 + 5 - + True True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 12 - 0 -9.9999999999999999e+45 1.0000000000000001e+63 1 10 10 - 4 + Apply changed controls to one voice only + Specific Voice: + True + 0 + True + control_panel_all_voices_radio + + + False + False + + + + + True + False + True + Voice control changes are applied to + 1 1 100 1 10 10 + 1 True + + 1 + + False + False 1 False - False - - - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 -1e+113 1e+137 0 0 0 - 63 - False - - - False + 5 1 - - 3 - 4 - - - - - True - - - 1 - 2 - GTK_FILL - @@ -1546,46 +1557,32 @@ Hold <Ctrl> to play controls in either mode. - + + True + + + 1 + 2 + GTK_FILL + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True - 0 + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True - True - GTK_POLICY_NEVER - GTK_POLICY_AUTOMATIC - - - True - GTK_SHADOW_NONE - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - - - - - - - - - True - True - - - True - Apply changed controls to all voices - All Voices - True - 0 - True + 0 + 4 + 4 + <b>Name</b> + True + True False @@ -1593,54 +1590,57 @@ Hold <Ctrl> to play controls in either mode. - + True - 5 - - - True - True - Apply changed controls to one voice only - Specific Voice: - True - 0 - True - control_panel_all_voices_radio - - - False - False - - + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 1 + 1 + 0 + 0 + 2 + 2 + 2 - + True - False True - Voice control changes are applied to - 1 1 100 1 10 10 - 1 + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + 0 -9.9999999999999999e+45 1.0000000000000001e+63 1 10 10 + 4 True - - 1 - - False - False 1 False - 5 + False + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 -1e+113 1e+137 0 0 0 + 63 + False + + + False 1 + + 3 + 4 + @@ -1730,51 +1730,51 @@ Hold <Ctrl> to play controls in either mode. 2 2 - + True - 0 + <b>Patch Search Path: </b> + True - 1 - 2 GTK_FILL - + True - <i>Example: /foo/bar:/home/john/patches:/usr/share/om/patches</i> - True + True + * 1 2 - 1 - 2 - GTK_FILL - + True - True - * + <i>Example: /foo/bar:/home/john/patches:/usr/share/om/patches</i> + True 1 2 + 1 + 2 + GTK_FILL - + True - <b>Patch Search Path: </b> - True + 0 + 1 + 2 GTK_FILL @@ -2150,7 +2150,7 @@ Hold <Ctrl> to play controls in either mode. 10 6 - + True 0 - @@ -2158,34 +2158,28 @@ Hold <Ctrl> to play controls in either mode. 1 2 - 2 - 3 GTK_FILL - + True 0 - Name: + Type: - 2 - 3 GTK_FILL - + True 0 - - + URI: - 1 - 2 1 2 GTK_FILL @@ -2193,12 +2187,14 @@ Hold <Ctrl> to play controls in either mode. - + True 0 - URI: + - + 1 + 2 1 2 GTK_FILL @@ -2206,18 +2202,20 @@ Hold <Ctrl> to play controls in either mode. - + True 0 - Type: + Name: + 2 + 3 GTK_FILL - + True 0 - @@ -2225,6 +2223,8 @@ Hold <Ctrl> to play controls in either mode. 1 2 + 2 + 3 GTK_FILL @@ -2379,33 +2379,64 @@ Contributors: 2 8 - + True - 0 + + + True + False + True + 16180 1 65535 1 10 10 + 1 + True + + + False + False + + + + + 1 + 2 + 1 + 2 + GTK_FILL + 8 + + + + + True + + + True + True + * + True + 28 + osc.udp://localhost:16180 + + 1 2 - 2 - 3 GTK_FILL - + GTK_FILL + 8 - + True - False True - Use internal engine + Connect to running server at: True 0 True - connect_server_radiobutton - 2 - 3 GTK_FILL @@ -2428,66 +2459,35 @@ Contributors: - + True + False True - Connect to running server at: + Use internal engine True 0 True + connect_server_radiobutton + 2 + 3 GTK_FILL - + True - - - True - True - * - True - 28 - osc.udp://localhost:16180 - - + 0 1 2 + 2 + 3 GTK_FILL - GTK_FILL - 8 - - - - - True - - - True - False - True - 16180 1 65535 1 10 10 - 1 - True - - - False - False - - - - - 1 - 2 - 1 - 2 - GTK_FILL - 8 + @@ -2828,26 +2828,19 @@ Contributors: 2 8 - - True - 0 - Short Name: - - - 1 - 2 - GTK_FILL - - - - - + True - 0 - Symbol: + True + Enter a short name suitable for use as an identifier or filename. + +The first character must be one of _, a-z or A-Z and subsequenct characters can be from _, a-z, A-Z or 0-9. + + * + True - GTK_FILL + 1 + 2 @@ -2868,19 +2861,26 @@ Contributors: - + True - True - Enter a short name suitable for use as an identifier or filename. - -The first character must be one of _, a-z or A-Z and subsequenct characters can be from _, a-z, A-Z or 0-9. - - * - True + 0 + Symbol: - 1 - 2 + GTK_FILL + + + + + + True + 0 + Short Name: + + + 1 + 2 + GTK_FILL @@ -3026,26 +3026,17 @@ Thank you for contributing. 2 4 - - True - 0 - Maximum Value: - - - 1 - 2 - GTK_FILL - - - - - + True - 0 - Minimum Value: + True + 0 -100000000 100000000 1 10 10 + 1 + 5 + True - GTK_FILL + 1 + 2 @@ -3067,17 +3058,26 @@ Thank you for contributing. - + True - True - 0 -100000000 100000000 1 10 10 - 1 - 5 - True + 0 + Minimum Value: - 1 - 2 + GTK_FILL + + + + + + True + 0 + Maximum Value: + + + 1 + 2 + GTK_FILL -- cgit v1.2.1