diff options
author | David Robillard <d@drobilla.net> | 2007-09-19 23:54:39 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2007-09-19 23:54:39 +0000 |
commit | ad558bdafde7e40b5de79b47d8586aec53cf3f7e (patch) | |
tree | a4431ddd696eb66eceb3119a9f7da933f3585ea4 | |
parent | 0b8415c61e321d032d62b5b1cbda65bab6f178d7 (diff) | |
download | ingen-ad558bdafde7e40b5de79b47d8586aec53cf3f7e.tar.gz ingen-ad558bdafde7e40b5de79b47d8586aec53cf3f7e.tar.bz2 ingen-ad558bdafde7e40b5de79b47d8586aec53cf3f7e.zip |
Toggling of individual node polyphonic state.
git-svn-id: http://svn.drobilla.net/lad/ingen@733 a436a847-0d15-0410-975c-d299462d15a1
30 files changed, 207 insertions, 80 deletions
diff --git a/src/common/interface/ClientInterface.hpp b/src/common/interface/ClientInterface.hpp index 0f28ac31..110f2905 100644 --- a/src/common/interface/ClientInterface.hpp +++ b/src/common/interface/ClientInterface.hpp @@ -86,6 +86,9 @@ public: const std::string& data_type, bool is_output) = 0; + virtual void polyphonic(const std::string& path, + bool polyphonic) = 0; + virtual void patch_enabled(const std::string& path) = 0; virtual void patch_disabled(const std::string& path) = 0; diff --git a/src/libs/client/DirectSigClientInterface.hpp b/src/libs/client/DirectSigClientInterface.hpp index 43877992..72265d11 100644 --- a/src/libs/client/DirectSigClientInterface.hpp +++ b/src/libs/client/DirectSigClientInterface.hpp @@ -74,6 +74,9 @@ private: virtual void new_port(const string& path, const string& data_type, bool is_output) { new_port_sig.emit(path, data_type, is_output); } + virtual void polyphonic(const string& path, bool polyphonic) + { polyphonic_sig.emit(path, polyphonic); } + virtual void patch_enabled(const string& path) { patch_enabled_sig.emit(path); } diff --git a/src/libs/client/NodeModel.cpp b/src/libs/client/NodeModel.cpp index 3ba343e3..c5aa3f61 100644 --- a/src/libs/client/NodeModel.cpp +++ b/src/libs/client/NodeModel.cpp @@ -26,7 +26,8 @@ namespace Client { NodeModel::NodeModel(SharedPtr<PluginModel> plugin, const Path& path, bool polyphonic) -: ObjectModel(path), + + : ObjectModel(path, polyphonic), _polyphonic(polyphonic), _plugin_uri(plugin->uri()), _plugin(plugin) @@ -34,8 +35,7 @@ NodeModel::NodeModel(SharedPtr<PluginModel> plugin, const Path& path, bool polyp } NodeModel::NodeModel(const string& plugin_uri, const Path& path, bool polyphonic) -: ObjectModel(path), - _polyphonic(polyphonic), +: ObjectModel(path, polyphonic), _plugin_uri(plugin_uri) { } diff --git a/src/libs/client/OSCClientReceiver.cpp b/src/libs/client/OSCClientReceiver.cpp index d223e211..9c68f2dd 100644 --- a/src/libs/client/OSCClientReceiver.cpp +++ b/src/libs/client/OSCClientReceiver.cpp @@ -159,6 +159,8 @@ OSCClientReceiver::setup_callbacks() lo_server_thread_add_method(_st, "/ingen/new_node", "ssTi", new_node_cb, this); lo_server_thread_add_method(_st, "/ingen/new_node", "ssFi", new_node_cb, this); lo_server_thread_add_method(_st, "/ingen/new_port", "ssi", new_port_cb, this); + lo_server_thread_add_method(_st, "/ingen/polyphonic", "sT", polyphonic_cb, this); + lo_server_thread_add_method(_st, "/ingen/polyphonic", "sF", polyphonic_cb, this); lo_server_thread_add_method(_st, "/ingen/metadata_update", NULL, metadata_update_cb, this); lo_server_thread_add_method(_st, "/ingen/control_change", "sf", control_change_cb, this); lo_server_thread_add_method(_st, "/ingen/program_add", "siis", program_add_cb, this); @@ -336,6 +338,20 @@ OSCClientReceiver::_new_port_cb(const char* path, const char* types, lo_arg** ar } +/** Notification of an object's polyphonic flag + */ +int +OSCClientReceiver::_polyphonic_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) +{ + const char* obj_path = &argv[0]->s; + const bool poly = (types[1] == 'T'); + + polyphonic(obj_path, poly); + + return 0; +} + + /** Notification of a new or updated piece of metadata. */ int diff --git a/src/libs/client/OSCClientReceiver.hpp b/src/libs/client/OSCClientReceiver.hpp index 45273201..41669662 100644 --- a/src/libs/client/OSCClientReceiver.hpp +++ b/src/libs/client/OSCClientReceiver.hpp @@ -99,6 +99,7 @@ private: LO_HANDLER(disconnection); LO_HANDLER(new_node); LO_HANDLER(new_port); + LO_HANDLER(polyphonic); LO_HANDLER(metadata_update); LO_HANDLER(control_change); LO_HANDLER(program_add); diff --git a/src/libs/client/OSCEngineSender.cpp b/src/libs/client/OSCEngineSender.cpp index e7b94e48..46181195 100644 --- a/src/libs/client/OSCEngineSender.cpp +++ b/src/libs/client/OSCEngineSender.cpp @@ -283,11 +283,11 @@ OSCEngineSender::set_polyphonic(const string& path, bool poly) { assert(_engine_addr); if (poly) { - lo_send(_engine_addr, "/ingen/set_polyphony", "isT", + lo_send(_engine_addr, "/ingen/set_polyphonic", "isT", next_id(), path.c_str()); } else { - lo_send(_engine_addr, "/ingen/set_polyphony", "isF", + lo_send(_engine_addr, "/ingen/set_polyphonic", "isF", next_id(), path.c_str()); } diff --git a/src/libs/client/ObjectModel.cpp b/src/libs/client/ObjectModel.cpp index f1393232..fe7b6aaf 100644 --- a/src/libs/client/ObjectModel.cpp +++ b/src/libs/client/ObjectModel.cpp @@ -25,8 +25,9 @@ namespace Ingen { namespace Client { -ObjectModel::ObjectModel(const Path& path) -: _path(path) +ObjectModel::ObjectModel(const Path& path, bool polyphonic) + : _path(path) + , _polyphonic(polyphonic) { } @@ -106,6 +107,14 @@ ObjectModel::add_metadata(const MetadataMap& data) } +void +ObjectModel::set_polyphonic(bool polyphonic) +{ + _polyphonic = polyphonic; + polyphonic_sig.emit(polyphonic); +} + + /** Merge the data of @a model with self, as much as possible. * * This will merge the two models, but with any conflict take the value in diff --git a/src/libs/client/ObjectModel.hpp b/src/libs/client/ObjectModel.hpp index 429f5359..6d2675fb 100644 --- a/src/libs/client/ObjectModel.hpp +++ b/src/libs/client/ObjectModel.hpp @@ -62,10 +62,11 @@ public: typedef Raul::Table<string, SharedPtr<ObjectModel> > Children; - const MetadataMap& metadata() const { return _metadata; } - const Children& children() const { return _children; } - inline const Path& path() const { return _path; } - SharedPtr<ObjectModel> parent() const { return _parent; } + const MetadataMap& metadata() const { return _metadata; } + const Children& children() const { return _children; } + inline const Path& path() const { return _path; } + SharedPtr<ObjectModel> parent() const { return _parent; } + bool polyphonic() const { return _polyphonic; } SharedPtr<ObjectModel> get_child(const string& name) const; @@ -73,13 +74,14 @@ public: sigc::signal<void, const string&, const Atom&> metadata_update_sig; sigc::signal<void, SharedPtr<ObjectModel> > new_child_sig; sigc::signal<void, SharedPtr<ObjectModel> > removed_child_sig; + sigc::signal<void, bool> polyphonic_sig; sigc::signal<void> destroyed_sig; sigc::signal<void> renamed_sig; protected: friend class Store; - ObjectModel(const Path& path); + ObjectModel(const Path& path, bool polyphonic); virtual void set_path(const Path& p) { _path = p; renamed_sig.emit(); } virtual void set_parent(SharedPtr<ObjectModel> p) { assert(p); _parent = p; } @@ -87,10 +89,12 @@ protected: virtual bool remove_child(SharedPtr<ObjectModel> c); void add_metadata(const MetadataMap& data); + void set_polyphonic(bool); void set(SharedPtr<ObjectModel> model); Path _path; + bool _polyphonic; SharedPtr<ObjectModel> _parent; MetadataMap _metadata; diff --git a/src/libs/client/PortModel.hpp b/src/libs/client/PortModel.hpp index cf8b94f0..b8d1f094 100644 --- a/src/libs/client/PortModel.hpp +++ b/src/libs/client/PortModel.hpp @@ -74,7 +74,7 @@ private: friend class Store; PortModel(const Path& path, const string& type, Direction dir) - : ObjectModel(path), + : ObjectModel(path, false), _type(type), _direction(dir), _current_val(0.0f), diff --git a/src/libs/client/SigClientInterface.hpp b/src/libs/client/SigClientInterface.hpp index 29c13741..7e020ca2 100644 --- a/src/libs/client/SigClientInterface.hpp +++ b/src/libs/client/SigClientInterface.hpp @@ -53,6 +53,7 @@ public: sigc::signal<void, string, uint32_t> new_patch_sig; sigc::signal<void, string, string, bool, uint32_t> new_node_sig; sigc::signal<void, string, string, bool> new_port_sig; + sigc::signal<void, string, bool> polyphonic_sig; sigc::signal<void, string> patch_enabled_sig; sigc::signal<void, string> patch_disabled_sig; sigc::signal<void, string, uint32_t> patch_polyphony_sig; diff --git a/src/libs/client/Store.cpp b/src/libs/client/Store.cpp index 84528d00..1ca94cce 100644 --- a/src/libs/client/Store.cpp +++ b/src/libs/client/Store.cpp @@ -42,6 +42,7 @@ Store::Store(SharedPtr<EngineInterface> engine, SharedPtr<SigClientInterface> em emitter->new_patch_sig.connect(sigc::mem_fun(this, &Store::new_patch_event)); emitter->new_node_sig.connect(sigc::mem_fun(this, &Store::new_node_event)); emitter->new_port_sig.connect(sigc::mem_fun(this, &Store::new_port_event)); + emitter->polyphonic_sig.connect(sigc::mem_fun(this, &Store::polyphonic_event)); emitter->patch_enabled_sig.connect(sigc::mem_fun(this, &Store::patch_enabled_event)); emitter->patch_disabled_sig.connect(sigc::mem_fun(this, &Store::patch_disabled_event)); emitter->patch_polyphony_sig.connect(sigc::mem_fun(this, &Store::patch_polyphony_event)); @@ -434,6 +435,15 @@ Store::new_port_event(const Path& path, const string& type, bool is_output) resolve_connection_orphans(p); } + +void +Store::polyphonic_event(const Path& path, bool polyphonic) +{ + SharedPtr<ObjectModel> object = this->object(path); + if (object) + object->set_polyphonic(polyphonic); +} + void Store::patch_enabled_event(const Path& path) diff --git a/src/libs/client/Store.hpp b/src/libs/client/Store.hpp index e5309484..4565dbc2 100644 --- a/src/libs/client/Store.hpp +++ b/src/libs/client/Store.hpp @@ -97,6 +97,7 @@ private: void new_patch_event(const Path& path, uint32_t poly); void new_node_event(const string& plugin_uri, const Path& node_path, bool is_polyphonic, uint32_t num_ports); void new_port_event(const Path& path, const string& data_type, bool is_output); + void polyphonic_event(const Path& path, bool polyphonic); void patch_enabled_event(const Path& path); void patch_disabled_event(const Path& path); void patch_polyphony_event(const Path& path, uint32_t poly); diff --git a/src/libs/client/ThreadedSigClientInterface.hpp b/src/libs/client/ThreadedSigClientInterface.hpp index 71ee96d2..105db4f4 100644 --- a/src/libs/client/ThreadedSigClientInterface.hpp +++ b/src/libs/client/ThreadedSigClientInterface.hpp @@ -54,6 +54,7 @@ public: , new_patch_slot(new_patch_sig.make_slot()) , new_node_slot(new_node_sig.make_slot()) , new_port_slot(new_port_sig.make_slot()) + , polyphonic_slot(polyphonic_sig.make_slot()) , connection_slot(connection_sig.make_slot()) , patch_enabled_slot(patch_enabled_sig.make_slot()) , patch_disabled_slot(patch_disabled_sig.make_slot()) @@ -73,9 +74,8 @@ public: virtual void subscribe(Shared::EngineInterface* engine) { throw; } // FIXME - // FIXME: make this insert bundle-boundary-events, where the GTK thread - // process all events between start and finish in one cycle, guaranteed - // (no more node jumping) + // TODO: make this insert bundle-boundary-events, where the GTK thread + // process all events between start and finish in one (GTK) "cycle", guaranteed void bundle_begin() {} void bundle_end() {} @@ -104,6 +104,9 @@ public: void new_port(const string& path, const string& data_type, bool is_output) { push_sig(sigc::bind(new_port_slot, path, data_type, is_output)); } + + void polyphonic(const string& path, bool polyphonic) + { push_sig(sigc::bind(polyphonic_slot, path, polyphonic)); } void connection(const string& src_port_path, const string& dst_port_path) { push_sig(sigc::bind(connection_slot, src_port_path, dst_port_path)); } @@ -162,6 +165,7 @@ private: sigc::slot<void, string, uint32_t> new_patch_slot; sigc::slot<void, string, string, bool, int> new_node_slot; sigc::slot<void, string, string, bool> new_port_slot; + sigc::slot<void, string, bool> polyphonic_slot; sigc::slot<void, string, string> connection_slot; sigc::slot<void, string> patch_enabled_slot; sigc::slot<void, string> patch_disabled_slot; diff --git a/src/libs/engine/ClientBroadcaster.cpp b/src/libs/engine/ClientBroadcaster.cpp index 0a98c05c..6193b586 100644 --- a/src/libs/engine/ClientBroadcaster.cpp +++ b/src/libs/engine/ClientBroadcaster.cpp @@ -190,6 +190,15 @@ ClientBroadcaster::send_destroyed(const string& path) (*i).second->object_destroyed(path); } + +void +ClientBroadcaster::send_polyphonic(const string& path, bool polyphonic) +{ + for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) + (*i).second->polyphonic(path, polyphonic); +} + + void ClientBroadcaster::send_patch_cleared(const string& patch_path) { diff --git a/src/libs/engine/ClientBroadcaster.hpp b/src/libs/engine/ClientBroadcaster.hpp index 1c1217bc..42bd817b 100644 --- a/src/libs/engine/ClientBroadcaster.hpp +++ b/src/libs/engine/ClientBroadcaster.hpp @@ -74,6 +74,7 @@ public: void send_node(const Node* const node, bool recursive); void send_port(const Port* port); void send_destroyed(const string& path); + void send_polyphonic(const string& path, bool polyphonic); void send_patch_cleared(const string& patch_path); void send_connection(const Connection* const connection); void send_disconnection(const string& src_port_path, const string& dst_port_path); diff --git a/src/libs/engine/GraphObject.hpp b/src/libs/engine/GraphObject.hpp index 1a6f0d7e..a2cfd5f0 100644 --- a/src/libs/engine/GraphObject.hpp +++ b/src/libs/engine/GraphObject.hpp @@ -31,13 +31,12 @@ using std::string; using Raul::Atom; using Raul::Path; + +namespace Raul { class Maid; } + namespace Ingen { class Patch; -class Node; -class Port; -class ObjectStore; - /** An object on the audio graph - Patch, Node, Port, etc. * @@ -52,8 +51,8 @@ class GraphObject : public Raul::Deletable public: typedef std::map<string, Atom> MetadataMap; - GraphObject(GraphObject* parent, const string& name) - : _store(NULL), _parent(parent), _name(name) + GraphObject(GraphObject* parent, const string& name, bool polyphonic=false) + : _parent(parent), _name(name), _polyphonic(polyphonic) { assert(parent == NULL || _name.length() > 0); assert(_name.find("/") == string::npos); @@ -62,6 +61,9 @@ public: virtual ~GraphObject() {} + bool polyphonic() const { return _polyphonic; } + virtual void set_polyphonic(Raul::Maid& maid, bool p) { _polyphonic = p; } + inline GraphObject* parent() const { return _parent; } inline const string& name() const { return _name; } @@ -99,9 +101,9 @@ public: } protected: - ObjectStore* _store; GraphObject* _parent; string _name; + bool _polyphonic; private: MetadataMap _metadata; diff --git a/src/libs/engine/Node.hpp b/src/libs/engine/Node.hpp index 470075a6..83a31c67 100644 --- a/src/libs/engine/Node.hpp +++ b/src/libs/engine/Node.hpp @@ -49,7 +49,10 @@ namespace Shared { class ClientInterface; } class Node : public GraphObject { public: - Node(GraphObject* parent, const std::string& name) : GraphObject(parent, name) {} + Node(GraphObject* parent, const std::string& name, bool poly) + : GraphObject(parent, name, poly) + {} + virtual ~Node() {} /** Activate this Node. @@ -122,9 +125,6 @@ public: virtual const Raul::Array<Port*>& ports() const = 0; virtual uint32_t num_ports() const = 0; - - virtual bool polyphonic() const = 0; - virtual uint32_t polyphony() const = 0; /** Used by the process order finding algorithm (ie during connections) */ virtual bool traversed() const = 0; diff --git a/src/libs/engine/NodeBase.cpp b/src/libs/engine/NodeBase.cpp index faef4a32..e8df05d6 100644 --- a/src/libs/engine/NodeBase.cpp +++ b/src/libs/engine/NodeBase.cpp @@ -34,9 +34,8 @@ namespace Ingen { NodeBase::NodeBase(const Plugin* plugin, const string& name, bool poly, Patch* parent, SampleRate srate, size_t buffer_size) -: Node(parent, name), +: Node(parent, name, poly), _plugin(plugin), - _polyphonic(poly), _polyphony(parent ? parent->internal_poly() : 1), _srate(srate), _buffer_size(buffer_size), diff --git a/src/libs/engine/NodeBase.hpp b/src/libs/engine/NodeBase.hpp index 8e1bb7f3..9f12c95f 100644 --- a/src/libs/engine/NodeBase.hpp +++ b/src/libs/engine/NodeBase.hpp @@ -80,7 +80,6 @@ public: SampleRate sample_rate() const { return _srate; } size_t buffer_size() const { return _buffer_size; } uint32_t num_ports() const { return _ports ? _ports->size() : 0; } - bool polyphonic() const { return _polyphonic; } uint32_t polyphony() const { return _polyphony; } bool traversed() const { return _traversed; } void traversed(bool b) { _traversed = b; } @@ -107,7 +106,6 @@ protected: const Plugin* _plugin; - bool _polyphonic; uint32_t _polyphony; SampleRate _srate; size_t _buffer_size; diff --git a/src/libs/engine/OSCClientSender.cpp b/src/libs/engine/OSCClientSender.cpp index 75353981..a2034cda 100644 --- a/src/libs/engine/OSCClientSender.cpp +++ b/src/libs/engine/OSCClientSender.cpp @@ -382,6 +382,30 @@ OSCClientSender::new_port(const std::string& path, /** \page client_osc_namespace + * <p> \b /ingen/polyphonic - Notification an object's polyphonic property has changed. + * \arg \b path (string) - Path of object + * \arg \b polyphonic (bool) - Whether or not object is polyphonic (from it's parent's perspective). + * + * \li This is a notification that the object is <em>externally</em> polyphonic, + * i.e. its parent sees several independent buffers for a single port, one for each voice. + * An object can be internally polyphonic but externally not if the voices are mixed down; + * this is true of DSSI plugins and subpatches with mismatched polyphony. </p> \n \n + */ +void +OSCClientSender::polyphonic(const std::string& path, + bool polyphonic) +{ + if (!_enabled) + return; + + if (polyphonic) + lo_send(_address, "/ingen/polyphonic", "sT", path.c_str()); + else + lo_send(_address, "/ingen/polyphonic", "sF", path.c_str()); +} + + +/** \page client_osc_namespace * <p> \b /ingen/destroyed - Notification an object has been destroyed * \arg \b path (const std::string&) - Path of object (which no longer exists) </p> \n \n */ diff --git a/src/libs/engine/OSCClientSender.hpp b/src/libs/engine/OSCClientSender.hpp index ac45bef4..b1fcc0f4 100644 --- a/src/libs/engine/OSCClientSender.hpp +++ b/src/libs/engine/OSCClientSender.hpp @@ -90,6 +90,9 @@ public: const std::string& data_type, bool is_output); + virtual void polyphonic(const std::string& path, + bool polyphonic); + virtual void patch_enabled(const std::string& path); virtual void patch_disabled(const std::string& path); diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp index 68790300..d750118e 100644 --- a/src/libs/engine/OSCEngineReceiver.cpp +++ b/src/libs/engine/OSCEngineReceiver.cpp @@ -84,6 +84,8 @@ OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t 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", "isi", set_polyphony_cb, this); + lo_server_add_method(_server, "/ingen/set_polyphonic", "isT", set_polyphonic_cb, this); + lo_server_add_method(_server, "/ingen/set_polyphonic", "isF", set_polyphonic_cb, this); lo_server_add_method(_server, "/ingen/create_port", "issi", create_port_cb, this); lo_server_add_method(_server, "/ingen/create_node", "issssT", create_node_cb, this); lo_server_add_method(_server, "/ingen/create_node", "issssF", create_node_cb, this); @@ -458,6 +460,23 @@ OSCEngineReceiver::_set_polyphony_cb(const char* path, const char* types, lo_arg /** \page engine_osc_namespace + * <p> \b /ingen/set_polyphonic - Toggle a node's or port's polyphonic mode + * \arg \b response-id (integer) + * \arg \b path - Object's path + * \arg \b polyphonic (bool) </p> \n \n + */ +int +OSCEngineReceiver::_set_polyphonic_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) +{ + const char* object_path = &argv[1]->s; + bool polyphonic = (types[2] == 'T'); + + set_polyphonic(object_path, polyphonic); + return 0; +} + + +/** \page engine_osc_namespace * <p> \b /ingen/create_port - Add a port into a given patch (load a plugin by URI) * \arg \b response-id (integer) * \arg \b path (string) - Full path of the new port (ie. /patch2/subpatch/newport) @@ -490,7 +509,6 @@ OSCEngineReceiver::_create_node_by_uri_cb(const char* path, const char* types, l bool polyphonic = (types[3] == 'T'); create_node(node_path, plug_uri, polyphonic); - return 0; } @@ -719,7 +737,6 @@ OSCEngineReceiver::_midi_learn_cb(const char* path, const char* types, lo_arg** const char* patch_path = &argv[1]->s; midi_learn(patch_path); - return 0; } @@ -743,7 +760,6 @@ OSCEngineReceiver::_metadata_set_cb(const char* path, const char* types, lo_arg* Raul::Atom value = Raul::AtomLiblo::lo_arg_to_atom(types[3], argv[3]); set_metadata(object_path, key, value); - return 0; } @@ -763,7 +779,6 @@ OSCEngineReceiver::_metadata_get_cb(const char* path, const char* types, lo_arg* const char* key = &argv[2]->s; request_metadata(object_path, key); - return 0; } @@ -780,7 +795,6 @@ OSCEngineReceiver::_request_plugin_cb(const char* path, const char* types, lo_ar const char* uri = &argv[1]->s; request_plugin(uri); - return 0; } @@ -797,7 +811,6 @@ OSCEngineReceiver::_request_object_cb(const char* path, const char* types, lo_ar const char* object_path = &argv[1]->s; request_object(object_path); - return 0; } diff --git a/src/libs/engine/OSCEngineReceiver.hpp b/src/libs/engine/OSCEngineReceiver.hpp index 559a56b2..264b66c1 100644 --- a/src/libs/engine/OSCEngineReceiver.hpp +++ b/src/libs/engine/OSCEngineReceiver.hpp @@ -93,6 +93,7 @@ private: LO_HANDLER(disable_patch); LO_HANDLER(clear_patch); LO_HANDLER(set_polyphony); + LO_HANDLER(set_polyphonic); LO_HANDLER(destroy); LO_HANDLER(connect); LO_HANDLER(disconnect); diff --git a/src/libs/engine/Patch.cpp b/src/libs/engine/Patch.cpp index 08d15c69..77b043eb 100644 --- a/src/libs/engine/Patch.cpp +++ b/src/libs/engine/Patch.cpp @@ -261,7 +261,7 @@ Patch::add_node(Raul::ListNode<Node*>* ln) assert(ln != NULL); assert(ln->elem() != NULL); assert(ln->elem()->parent_patch() == this); - assert(ln->elem()->polyphony() == _internal_poly); + //assert(ln->elem()->polyphony() == _internal_poly); _nodes.push_back(ln); } diff --git a/src/libs/engine/events/SetPolyphonicEvent.cpp b/src/libs/engine/events/SetPolyphonicEvent.cpp index 369abbd2..17313f96 100644 --- a/src/libs/engine/events/SetPolyphonicEvent.cpp +++ b/src/libs/engine/events/SetPolyphonicEvent.cpp @@ -31,10 +31,10 @@ namespace Ingen { -SetPolyphonicEvent::SetPolyphonicEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& patch_path, bool poly) +SetPolyphonicEvent::SetPolyphonicEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& path, bool poly) : QueuedEvent(engine, responder, time, true, source), - _patch_path(patch_path), - _patch(NULL), + _path(path), + _object(NULL), _poly(poly) { } @@ -43,12 +43,9 @@ SetPolyphonicEvent::SetPolyphonicEvent(Engine& engine, SharedPtr<Responder> resp void SetPolyphonicEvent::pre_process() { - /* - _patch = _engine.object_store()->find_patch(_patch_path); - if (_patch && _poly > _patch->internal_poly()) - _patch->prepare_internal_poly(_poly); -*/ - QueuedEvent::pre_process(); + _object = _engine.object_store()->find_object(_path); + + QueuedEvent::pre_process(); } @@ -56,10 +53,10 @@ void SetPolyphonicEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { QueuedEvent::execute(nframes, start, end); -/* - if (_patch) - _patch->apply_internal_poly(*_engine.maid(), _poly); -*/ + + if (_object) + _object->set_polyphonic(*_engine.maid(), _poly); + _source->unblock(); } @@ -67,12 +64,12 @@ SetPolyphonicEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) void SetPolyphonicEvent::post_process() { - /* - if (_patch) + if (_object) { _responder->respond_ok(); - else - _responder->respond_error("Unable to find patch"); - */ + _engine.broadcaster()->send_polyphonic(_path, _poly); + } else { + _responder->respond_error("Unable to find object"); + } } diff --git a/src/libs/engine/events/SetPolyphonicEvent.hpp b/src/libs/engine/events/SetPolyphonicEvent.hpp index 42988f72..3e3aa81e 100644 --- a/src/libs/engine/events/SetPolyphonicEvent.hpp +++ b/src/libs/engine/events/SetPolyphonicEvent.hpp @@ -26,7 +26,7 @@ using std::string; namespace Ingen { -class Patch; +class GraphObject; /** Delete all nodes from a patch. @@ -36,16 +36,16 @@ class Patch; class SetPolyphonicEvent : public QueuedEvent { public: - SetPolyphonicEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& patch_path, bool poly); + SetPolyphonicEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& path, bool poly); void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: - string _patch_path; - Patch* _patch; - bool _poly; + string _path; + GraphObject* _object; + bool _poly; }; diff --git a/src/libs/gui/NodeMenu.cpp b/src/libs/gui/NodeMenu.cpp index 3a09e34f..9f99cfe3 100644 --- a/src/libs/gui/NodeMenu.cpp +++ b/src/libs/gui/NodeMenu.cpp @@ -30,8 +30,9 @@ namespace GUI { NodeMenu::NodeMenu(SharedPtr<NodeModel> node) -: _node(node) -, _controls_menuitem(NULL) + : _enable_signal(false) + , _node(node) + , _controls_menuitem(NULL) { App& app = App::instance(); @@ -77,6 +78,16 @@ NodeMenu::NodeMenu(SharedPtr<NodeModel> node) sigc::bind( sigc::mem_fun(app.window_factory(), &WindowFactory::present_properties), node))); + + Gtk::Menu_Helpers::CheckMenuElem poly_elem = Gtk::Menu_Helpers::CheckMenuElem( + "Polyphonic", sigc::mem_fun(this, &NodeMenu::on_menu_polyphonic)); + items().push_back(poly_elem); + _polyphonic_menuitem = static_cast<Gtk::RadioMenuItem*>(&items().back()); + _polyphonic_menuitem->set_active(node->polyphonic()); + + node->polyphonic_sig.connect(sigc::mem_fun(this, &NodeMenu::polyphonic_changed)); + + _enable_signal = true; //model->new_port_sig.connect(sigc::mem_fun(this, &NodeMenu::add_port)); //model->destroyed_sig.connect(sigc::mem_fun(this, &NodeMenu::destroy)); @@ -176,6 +187,23 @@ NodeMenu::on_menu_destroy() void +NodeMenu::on_menu_polyphonic() +{ + if (_enable_signal) + App::instance().engine()->set_polyphonic(_node->path(), _polyphonic_menuitem->get_active()); +} + + +void +NodeMenu::polyphonic_changed(bool polyphonic) +{ + _enable_signal = false; + _polyphonic_menuitem->set_active(polyphonic); + _enable_signal = true; +} + + +void NodeMenu::on_menu_clone() { cerr << "FIXME: clone broken\n"; diff --git a/src/libs/gui/NodeMenu.hpp b/src/libs/gui/NodeMenu.hpp index 0290d861..e6f63d73 100644 --- a/src/libs/gui/NodeMenu.hpp +++ b/src/libs/gui/NodeMenu.hpp @@ -51,9 +51,6 @@ public: bool has_control_inputs(); - //virtual void show_menu(GdkEventButton* event) - //{ _menu.popup(event->button, event->time); } - protected: virtual void enable_controls_menuitem(); @@ -62,13 +59,17 @@ protected: //virtual void add_port(SharedPtr<PortModel> pm); void on_menu_destroy(); + void on_menu_polyphonic(); void on_menu_clone(); void on_menu_learn(); void on_menu_disconnect_all(); - //Gtk::Menu _menu; - SharedPtr<NodeModel> _node; + void polyphonic_changed(bool p); + + bool _enable_signal; + SharedPtr<NodeModel> _node; Glib::RefPtr<Gtk::MenuItem> _controls_menuitem; + Gtk::CheckMenuItem* _polyphonic_menuitem; }; diff --git a/src/libs/gui/NodeModule.cpp b/src/libs/gui/NodeModule.cpp index ecaafa65..9cba9abd 100644 --- a/src/libs/gui/NodeModule.cpp +++ b/src/libs/gui/NodeModule.cpp @@ -42,15 +42,15 @@ NodeModule::NodeModule(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<NodeMode { assert(_node); - if (node->polyphonic()) - set_stacked_border(true); - node->new_port_sig.connect(sigc::bind(sigc::mem_fun(this, &NodeModule::add_port), true)); node->removed_port_sig.connect(sigc::mem_fun(this, &NodeModule::remove_port)); - node->metadata_update_sig.connect(sigc::mem_fun(this, &NodeModule::metadata_update)); - + node->metadata_update_sig.connect(sigc::mem_fun(this, &NodeModule::set_metadata)); + node->polyphonic_sig.connect(sigc::mem_fun(this, &NodeModule::set_stacked_border)); + node->renamed_sig.connect(sigc::mem_fun(this, &NodeModule::rename)); + signal_clicked.connect(sigc::mem_fun(this, &NodeModule::on_click)); - node->renamed_sig.connect(sigc::mem_fun(this, &NodeModule::renamed)); + + set_stacked_border(node->polyphonic()); } @@ -77,7 +77,7 @@ NodeModule::create(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<NodeModel> n ret = boost::shared_ptr<NodeModule>(new NodeModule(canvas, node)); for (MetadataMap::const_iterator m = node->metadata().begin(); m != node->metadata().end(); ++m) - ret->metadata_update(m->first, m->second); + ret->set_metadata(m->first, m->second); for (PortModelList::const_iterator p = node->ports().begin(); p != node->ports().end(); ++p) ret->add_port(*p, false); @@ -89,7 +89,7 @@ NodeModule::create(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<NodeModel> n void -NodeModule::renamed() +NodeModule::rename() { set_name(_node->path().name()); } @@ -157,7 +157,7 @@ NodeModule::on_click(GdkEventButton* event) void -NodeModule::metadata_update(const string& key, const Atom& value) +NodeModule::set_metadata(const string& key, const Atom& value) { if (key == "ingenuity:canvas-x" && value.type() == Atom::FLOAT) move_to(value.get_float(), property_y()); diff --git a/src/libs/gui/NodeModule.hpp b/src/libs/gui/NodeModule.hpp index b554a64c..aa77e780 100644 --- a/src/libs/gui/NodeModule.hpp +++ b/src/libs/gui/NodeModule.hpp @@ -74,13 +74,12 @@ protected: virtual void on_double_click(GdkEventButton* ev) { show_control_window(); } virtual void on_middle_click(GdkEventButton* ev) { show_control_window(); } - void metadata_update(const string& key, const Atom& value); + void rename(); + void set_metadata(const string& key, const Atom& value); void add_port(SharedPtr<PortModel> port, bool resize=true); void remove_port(SharedPtr<PortModel> port); - void renamed(); - SharedPtr<NodeModel> _node; NodeMenu _menu; }; |