summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-09-19 23:54:39 +0000
committerDavid Robillard <d@drobilla.net>2007-09-19 23:54:39 +0000
commitad558bdafde7e40b5de79b47d8586aec53cf3f7e (patch)
treea4431ddd696eb66eceb3119a9f7da933f3585ea4
parent0b8415c61e321d032d62b5b1cbda65bab6f178d7 (diff)
downloadingen-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
-rw-r--r--src/common/interface/ClientInterface.hpp3
-rw-r--r--src/libs/client/DirectSigClientInterface.hpp3
-rw-r--r--src/libs/client/NodeModel.cpp6
-rw-r--r--src/libs/client/OSCClientReceiver.cpp16
-rw-r--r--src/libs/client/OSCClientReceiver.hpp1
-rw-r--r--src/libs/client/OSCEngineSender.cpp4
-rw-r--r--src/libs/client/ObjectModel.cpp13
-rw-r--r--src/libs/client/ObjectModel.hpp14
-rw-r--r--src/libs/client/PortModel.hpp2
-rw-r--r--src/libs/client/SigClientInterface.hpp1
-rw-r--r--src/libs/client/Store.cpp10
-rw-r--r--src/libs/client/Store.hpp1
-rw-r--r--src/libs/client/ThreadedSigClientInterface.hpp10
-rw-r--r--src/libs/engine/ClientBroadcaster.cpp9
-rw-r--r--src/libs/engine/ClientBroadcaster.hpp1
-rw-r--r--src/libs/engine/GraphObject.hpp16
-rw-r--r--src/libs/engine/Node.hpp8
-rw-r--r--src/libs/engine/NodeBase.cpp3
-rw-r--r--src/libs/engine/NodeBase.hpp2
-rw-r--r--src/libs/engine/OSCClientSender.cpp24
-rw-r--r--src/libs/engine/OSCClientSender.hpp3
-rw-r--r--src/libs/engine/OSCEngineReceiver.cpp25
-rw-r--r--src/libs/engine/OSCEngineReceiver.hpp1
-rw-r--r--src/libs/engine/Patch.cpp2
-rw-r--r--src/libs/engine/events/SetPolyphonicEvent.cpp33
-rw-r--r--src/libs/engine/events/SetPolyphonicEvent.hpp10
-rw-r--r--src/libs/gui/NodeMenu.cpp32
-rw-r--r--src/libs/gui/NodeMenu.hpp11
-rw-r--r--src/libs/gui/NodeModule.cpp18
-rw-r--r--src/libs/gui/NodeModule.hpp5
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;
};