From 4174fb8f94139e0a38da150ffb0874b636497dfe Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 15 Oct 2006 20:46:26 +0000 Subject: Fixed feedback problems (CPU chewing) with port controls. git-svn-id: http://svn.drobilla.net/lad/ingen@176 a436a847-0d15-0410-975c-d299462d15a1 --- src/common/interface/ClientInterface.h | 7 +++ src/libs/client/OSCClientReceiver.cpp | 2 +- src/libs/client/OSCClientReceiver.h | 4 ++ src/libs/client/SigClientInterface.h | 4 ++ src/libs/client/ThreadedSigClientInterface.cpp | 3 + src/libs/client/ThreadedSigClientInterface.h | 7 ++- src/libs/engine/ClientBroadcaster.cpp | 2 +- src/libs/engine/OSCClientSender.cpp | 54 ++++++++++++++++++ src/libs/engine/OSCClientSender.h | 8 ++- src/libs/engine/OSCEngineReceiver.cpp | 15 +++-- src/libs/engine/OSCResponder.cpp | 8 +++ src/libs/engine/Responder.h | 7 ++- src/libs/engine/events/SetPortValueEvent.cpp | 7 --- src/progs/ingenuity/ControlGroups.cpp | 77 +++++--------------------- src/progs/ingenuity/ControlGroups.h | 7 +-- src/progs/ingenuity/ControlPanel.cpp | 4 ++ src/progs/ingenuity/ingenuity.glade | 10 ++-- 17 files changed, 138 insertions(+), 88 deletions(-) diff --git a/src/common/interface/ClientInterface.h b/src/common/interface/ClientInterface.h index 9ff19609..033021b1 100644 --- a/src/common/interface/ClientInterface.h +++ b/src/common/interface/ClientInterface.h @@ -38,6 +38,13 @@ public: virtual void response(int32_t id, bool success, string msg) = 0; + virtual void enable() = 0; + + /** Signifies the client does not wish to receive any messages until + * enable is called. Useful for performance and avoiding feedback. + */ + virtual void disable() = 0; + /** Bundles are a group of messages that are guaranteed to be in an * atomic unit with guaranteed order (eg a packet). For datagram * protocols (like UDP) there is likely an upper limit on bundle size. diff --git a/src/libs/client/OSCClientReceiver.cpp b/src/libs/client/OSCClientReceiver.cpp index eb320df0..14bff1f1 100644 --- a/src/libs/client/OSCClientReceiver.cpp +++ b/src/libs/client/OSCClientReceiver.cpp @@ -67,7 +67,7 @@ OSCClientReceiver::start() } // Print all incoming messages - //lo_server_thread_add_method(_st, NULL, NULL, generic_cb, NULL); + lo_server_thread_add_method(_st, NULL, NULL, generic_cb, NULL); //lo_server_thread_add_method(_st, "/om/response/ok", "i", om_response_ok_cb, this); //lo_server_thread_add_method(_st, "/om/response/error", "is", om_responseerror_cb, this); diff --git a/src/libs/client/OSCClientReceiver.h b/src/libs/client/OSCClientReceiver.h index 287f5e45..57faec77 100644 --- a/src/libs/client/OSCClientReceiver.h +++ b/src/libs/client/OSCClientReceiver.h @@ -60,6 +60,10 @@ public: OSCClientReceiver(int listen_port); ~OSCClientReceiver(); + // Engine side only + //void enable() {} + //void disable() {} + void start(); void stop(); diff --git a/src/libs/client/SigClientInterface.h b/src/libs/client/SigClientInterface.h index 4639bdc7..9f8a4537 100644 --- a/src/libs/client/SigClientInterface.h +++ b/src/libs/client/SigClientInterface.h @@ -67,6 +67,10 @@ protected: // ClientInterface hooks that fire the above signals + // FIXME: implement for this (is implemented for ThreadedSigClientInterface) + void enable() { } + void disable() { } + void bundle_begin() {} void bundle_end() {} diff --git a/src/libs/client/ThreadedSigClientInterface.cpp b/src/libs/client/ThreadedSigClientInterface.cpp index 28719598..bbe336a6 100644 --- a/src/libs/client/ThreadedSigClientInterface.cpp +++ b/src/libs/client/ThreadedSigClientInterface.cpp @@ -27,6 +27,9 @@ namespace Client { void ThreadedSigClientInterface::push_sig(Closure ev) { + if (!_enabled) + return; + bool success = false; bool first = true; diff --git a/src/libs/client/ThreadedSigClientInterface.h b/src/libs/client/ThreadedSigClientInterface.h index 056540fb..57afd0fa 100644 --- a/src/libs/client/ThreadedSigClientInterface.h +++ b/src/libs/client/ThreadedSigClientInterface.h @@ -44,7 +44,8 @@ class ThreadedSigClientInterface : public SigClientInterface { public: ThreadedSigClientInterface(uint32_t queue_size) - : _sigs(queue_size) + : _enabled(true) + , _sigs(queue_size) , response_slot(response_sig.make_slot()) , error_slot(error_sig.make_slot()) , new_plugin_slot(new_plugin_sig.make_slot()) @@ -64,6 +65,8 @@ public: , program_remove_slot(program_remove_sig.make_slot()) {} + void enable() { _enabled = true; } + void disable() { _enabled = false ; } // FIXME: make this insert bundle-boundary-events, where the GTK thread // process all events between start and finish in one cycle, guaranteed @@ -133,6 +136,8 @@ public: private: void push_sig(Closure ev); + bool _enabled; + Queue _sigs; uint32_t _num_plugins; diff --git a/src/libs/engine/ClientBroadcaster.cpp b/src/libs/engine/ClientBroadcaster.cpp index 6e722024..872cbb14 100644 --- a/src/libs/engine/ClientBroadcaster.cpp +++ b/src/libs/engine/ClientBroadcaster.cpp @@ -110,7 +110,7 @@ ClientBroadcaster::client(const ClientKey& key) if ((*i).first == key) return (*i).second; - cerr << "[ClientBroadcaster] Failed to find client." << endl; + cerr << "[ClientBroadcaster] Failed to find client " << key.uri() << endl; return SharedPtr(); } diff --git a/src/libs/engine/OSCClientSender.cpp b/src/libs/engine/OSCClientSender.cpp index 24dc1cb0..2032e47b 100644 --- a/src/libs/engine/OSCClientSender.cpp +++ b/src/libs/engine/OSCClientSender.cpp @@ -100,6 +100,9 @@ OSCClientSender::transfer_end() void OSCClientSender::response(int32_t id, bool success, string msg) { + if (!_enabled) + return; + if (lo_send(_address, "/om/response", "iis", id, success ? 1 : 0, msg.c_str()) < 0) { cerr << "Unable to send response " << id << "! (" << lo_address_errstr(_address) << ")" << endl; @@ -122,6 +125,9 @@ OSCClientSender::response(int32_t id, bool success, string msg) void OSCClientSender::error(string msg) { + if (!_enabled) + return; + lo_send(_address, "/om/error", "s", msg.c_str()); } @@ -143,6 +149,9 @@ OSCClientSender::error(string msg) void OSCClientSender::num_plugins(uint32_t num) { + if (!_enabled) + return; + lo_message m = lo_message_new(); lo_message_add_int32(m, num); lo_send_message(_address, "/om/num_plugins", m); @@ -222,6 +231,9 @@ void OSCClientSender::new_node(string plugin_uri, bool is_polyphonic, uint32_t num_ports) { + if (!_enabled) + return; + //cerr << "Sending node " << node_path << endl; lo_send(_address, "/om/new_node", "ssii", plugin_uri.c_str(), @@ -334,6 +346,9 @@ OSCClientSender::new_port(string path, string data_type, bool is_output) { + if (!_enabled) + return; + //PortInfo* info = port->port_info(); lo_send(_address, "/om/new_port", "ssi", path.c_str(), data_type.c_str(), is_output); @@ -352,6 +367,9 @@ OSCClientSender::new_port(string path, void OSCClientSender::object_destroyed(string path) { + if (!_enabled) + return; + assert(path != "/"); lo_send(_address, "/om/destroyed", "s", path.c_str()); @@ -365,6 +383,9 @@ OSCClientSender::object_destroyed(string path) void OSCClientSender::patch_cleared(string patch_path) { + if (!_enabled) + return; + lo_send(_address, "/om/patch_cleared", "s", patch_path.c_str()); } @@ -376,6 +397,9 @@ OSCClientSender::patch_cleared(string patch_path) void OSCClientSender::patch_enabled(string patch_path) { + if (!_enabled) + return; + lo_send(_address, "/om/patch_enabled", "s", patch_path.c_str()); } @@ -387,6 +411,9 @@ OSCClientSender::patch_enabled(string patch_path) void OSCClientSender::patch_disabled(string patch_path) { + if (!_enabled) + return; + lo_send(_address, "/om/patch_disabled", "s", patch_path.c_str()); } @@ -399,6 +426,9 @@ OSCClientSender::patch_disabled(string patch_path) void OSCClientSender::connection(string src_port_path, string dst_port_path) { + if (!_enabled) + return; + lo_send(_address, "/om/new_connection", "ss", src_port_path.c_str(), dst_port_path.c_str()); } @@ -411,6 +441,9 @@ OSCClientSender::connection(string src_port_path, string dst_port_path) void OSCClientSender::disconnection(string src_port_path, string dst_port_path) { + if (!_enabled) + return; + lo_send(_address, "/om/disconnection", "ss", src_port_path.c_str(), dst_port_path.c_str()); } @@ -424,6 +457,9 @@ OSCClientSender::disconnection(string src_port_path, string dst_port_path) void OSCClientSender::metadata_update(string path, string key, Atom value) { + if (!_enabled) + return; + lo_message m = lo_message_new(); lo_message_add_string(m, path.c_str()); lo_message_add_string(m, key.c_str()); @@ -443,6 +479,9 @@ OSCClientSender::metadata_update(string path, string key, Atom value) void OSCClientSender::control_change(string port_path, float value) { + if (!_enabled) + return; + lo_send(_address, "/om/control_change", "sf", port_path.c_str(), value); } @@ -456,6 +495,9 @@ OSCClientSender::control_change(string port_path, float value) void OSCClientSender::new_plugin(string uri, string name) { + if (!_enabled) + return; + lo_message m = lo_message_new(); lo_message_add_string(m, uri.c_str()); lo_message_add_string(m, name.c_str()); @@ -475,6 +517,9 @@ OSCClientSender::new_plugin(string uri, string name) void OSCClientSender::new_patch(string path, uint32_t poly) { + if (!_enabled) + return; + lo_send(_address, "/om/new_patch", "si", path.c_str(), poly); /* @@ -498,6 +543,9 @@ OSCClientSender::new_patch(string path, uint32_t poly) void OSCClientSender::object_renamed(string old_path, string new_path) { + if (!_enabled) + return; + lo_send(_address, "/om/object_renamed", "ss", old_path.c_str(), new_path.c_str()); } @@ -507,6 +555,9 @@ OSCClientSender::object_renamed(string old_path, string new_path) void OSCClientSender::program_add(string node_path, uint32_t bank, uint32_t program, string name) { + if (!_enabled) + return; + lo_send(_address, "/om/program_add", "siis", node_path.c_str(), bank, program, name.c_str()); } @@ -515,6 +566,9 @@ OSCClientSender::program_add(string node_path, uint32_t bank, uint32_t program, void OSCClientSender::program_remove(string node_path, uint32_t bank, uint32_t program) { + if (!_enabled) + return; + lo_send(_address, "/om/program_remove", "sii", node_path.c_str(), bank, program); } diff --git a/src/libs/engine/OSCClientSender.h b/src/libs/engine/OSCClientSender.h index a2ee9e26..8b465288 100644 --- a/src/libs/engine/OSCClientSender.h +++ b/src/libs/engine/OSCClientSender.h @@ -42,7 +42,8 @@ public: OSCClientSender(const string& url) : _url(url), _address(lo_address_new_from_url(url.c_str())), - _transfer(NULL) + _transfer(NULL), + _enabled(true) {} virtual ~OSCClientSender() @@ -60,6 +61,9 @@ public: //void client_registration(string url, int client_id); + void enable() { _enabled = true; } + void disable() { _enabled = false; } + void bundle_begin(); void bundle_end(); @@ -128,6 +132,8 @@ private: lo_address _address; lo_bundle _transfer; + + bool _enabled; }; diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp index 3354e648..b7e8f3a1 100644 --- a/src/libs/engine/OSCEngineReceiver.cpp +++ b/src/libs/engine/OSCEngineReceiver.cpp @@ -214,11 +214,11 @@ OSCEngineReceiver::set_response_address_cb(const char* path, const char* types, const int id = argv[0]->i; + const lo_address addr = lo_message_get_source(msg); + char* const url = lo_address_get_url(addr); + // Need to respond if (id != -1) { - const lo_address addr = lo_message_get_source(msg); - char* const url = lo_address_get_url(addr); - //cerr << "** need to respond\n"; // Currently have an OSC responder, check if it's still okay @@ -246,12 +246,19 @@ OSCEngineReceiver::set_response_address_cb(const char* path, const char* types, me->set_responder(me->_osc_responder); //cerr << "** Setting response address to " << url << "(2)" << endl; } - + me->set_next_response_id(id); // Don't respond } else { me->disable_responses(); + SharedPtr client = me->_engine->broadcaster()->client( + ClientKey(ClientKey::OSC_URL, (const char*)url)); + if (client) + client->disable(); + else + cerr << "UNKNOWN CLIENT!\n"; + //cerr << "** Not responding." << endl; } diff --git a/src/libs/engine/OSCResponder.cpp b/src/libs/engine/OSCResponder.cpp index acc7e7ac..7a63c180 100644 --- a/src/libs/engine/OSCResponder.cpp +++ b/src/libs/engine/OSCResponder.cpp @@ -54,6 +54,10 @@ OSCResponder::~OSCResponder() void OSCResponder::respond_ok() { + SharedPtr client = this->client(); + if (client) + client->enable(); + _addr = lo_address_new_from_url(_url); //cerr << "OK " << _id << endl; @@ -67,6 +71,10 @@ OSCResponder::respond_ok() void OSCResponder::respond_error(const string& msg) { + SharedPtr client = this->client(); + if (client) + client->enable(); + _addr = lo_address_new_from_url(_url); //cerr << "ERR " << _id << endl; diff --git a/src/libs/engine/Responder.h b/src/libs/engine/Responder.h index acfa6beb..fad5c1a3 100644 --- a/src/libs/engine/Responder.h +++ b/src/libs/engine/Responder.h @@ -44,6 +44,11 @@ using Shared::ClientInterface; * ClientInterface and Responder are seperate because responding might not * actually get exposed to the client interface (eg in simulated blocking * interfaces that wait for responses before returning). + * + * Note for messages that have a "response" and some broadcasted effect + * (eg setting a port value) the "response" MUST be sent first since Responder + * is responsible for controlling whether the client wishes to receive the + * notification. */ class Responder { @@ -51,7 +56,7 @@ public: Responder() {} virtual ~Responder() {} - virtual ClientKey client_key() { return ClientKey(); } + virtual ClientKey client_key() { return ClientKey(); } virtual SharedPtr client() { return SharedPtr(); } virtual void set_id(int32_t id) {} diff --git a/src/libs/engine/events/SetPortValueEvent.cpp b/src/libs/engine/events/SetPortValueEvent.cpp index 417cab32..bba5bc3c 100644 --- a/src/libs/engine/events/SetPortValueEvent.cpp +++ b/src/libs/engine/events/SetPortValueEvent.cpp @@ -81,13 +81,6 @@ SetPortValueEvent::post_process() _responder->respond_ok(); _engine.broadcaster()->send_control_change(m_port_path, m_val); - // Send patch port control change, if this is a bridge port - /*Port* parent_port = m_port->parent_node()->as_port(); - if (parent_port != NULL) { - assert(parent_port->type() == DataType::FLOAT); - _engine.broadcaster()->send_control_change(parent_port->path(), m_val); - }*/ - } else if (m_error == PORT_NOT_FOUND) { string msg = "Unable to find port "; msg.append(m_port_path).append(" for set_port_value"); diff --git a/src/progs/ingenuity/ControlGroups.cpp b/src/progs/ingenuity/ControlGroups.cpp index 6862c499..e228c140 100644 --- a/src/progs/ingenuity/ControlGroups.cpp +++ b/src/progs/ingenuity/ControlGroups.cpp @@ -35,7 +35,8 @@ ControlGroup::ControlGroup(BaseObjectType* cobject, const Glib::RefPtr pm, bool separator) } -void -ControlGroup::metadata_update(const string& key, const Atom& value) -{ - if ( (key == "min") && value.type() == Atom::FLOAT) - set_min(value.get_float()); - else if ( (key == "max") && value.type() == Atom::FLOAT) - set_max(value.get_float()); -} - - // ////////////////// SliderControlGroup ////////////////////// // SliderControlGroup::SliderControlGroup(BaseObjectType* cobject, const Glib::RefPtr& xml) : ControlGroup(cobject, xml), - m_enabled(true), - m_enable_signal(false) + m_enabled(true) { xml->get_widget("control_strip_name_label", m_name_label); xml->get_widget("control_strip_min_spinner", m_min_spinner); @@ -88,15 +78,6 @@ SliderControlGroup::SliderControlGroup(BaseObjectType* cobject, const Glib::RefP void SliderControlGroup::init(ControlPanel* panel, SharedPtr pm, bool separator) -/*: ControlGroup(panel, pm, separator), - m_enabled(true), - m_enable_signal(false), - m_name_label(pm->path().name(), 0.0, 0.0), - m_min_spinner(1.0, (pm->is_integer() ? 0 : 2)), // climb rate, digits - m_max_spinner(1.0, (pm->is_integer() ? 0 : 2)), - m_box(false, 0), - m_value_spinner(1.0, (pm->is_integer() ? 0 : 2)), - m_slider(0, 1, (pm->is_integer() ? 1.0 : 0.0001))*/ { ControlGroup::init(panel, pm, separator); @@ -105,8 +86,6 @@ SliderControlGroup::init(ControlPanel* panel, SharedPtr pm, bool sepa assert(m_max_spinner); assert(m_slider); - //m_slider->set_increments(1.0, 10.0); - //m_slider->set_value_pos(Gtk::POS_RIGHT); m_slider->set_draw_value(true); float min = 0.0f; @@ -124,25 +103,9 @@ SliderControlGroup::init(ControlPanel* panel, SharedPtr pm, bool sepa set_name(pm->path().name()); - //m_name_label->property_use_markup() = true; - -/* - m_value_spinner.set_range(-99999, 99999); - m_value_spinner.set_update_policy(Gtk::UPDATE_ALWAYS); // allow entered values outside range - m_value_spinner.set_value(m_port_model->value()); - m_value_spinner.set_increments(1.0, 10.0); - m_value_spinner.set_digits(2); - m_value_spinner.signal_value_changed().connect( - sigc::mem_fun(*this, &SliderControlGroup::update_value_from_spinner));*/ - //m_min_spinner->set_range(-99999, 99999); m_min_spinner->set_value(min); - //m_min_spinner->set_increments(1.0, 10.0); - //m_min_spinner->set_digits(2); m_min_spinner->signal_value_changed().connect(sigc::mem_fun(*this, &SliderControlGroup::min_changed)); - //m_max_spinner->set_range(-99999, 99999); m_max_spinner->set_value(max); - //m_max_spinner->set_increments(1.0, 10.0); - //m_max_spinner->set_digits(2); m_max_spinner->signal_value_changed().connect(sigc::mem_fun(*this, &SliderControlGroup::max_changed)); m_slider->set_value(m_port_model->value()); @@ -152,15 +115,7 @@ SliderControlGroup::init(ControlPanel* panel, SharedPtr pm, bool sepa m_slider->signal_value_changed().connect( sigc::mem_fun(*this, &SliderControlGroup::update_value_from_slider)); -#if 0 - m_box.pack_start(m_name_label, false, false, 6); - //m_box.pack_start(m_value_spinner, true, true, 1); - m_box.pack_start(m_min_spinner, false, false, 1); - m_box.pack_start(m_slider, true, true, 2); - m_box.pack_start(m_max_spinner, false, false, 1); - pack_start(m_box); -#endif m_slider->set_range(min, max); m_enable_signal = true; @@ -170,29 +125,25 @@ SliderControlGroup::init(ControlPanel* panel, SharedPtr pm, bool sepa void -SliderControlGroup::set_name(const string& name) -{ - string name_label = ""; - name_label += name + ""; - m_name_label->set_markup(name_label); -} - - -void -SliderControlGroup::set_min(float val) +SliderControlGroup::metadata_update(const string& key, const Atom& value) { m_enable_signal = false; - m_min_spinner->set_value(val); + + if ( (key == "min") && value.type() == Atom::FLOAT) + m_min_spinner->set_value(value.get_float()); + else if ( (key == "max") && value.type() == Atom::FLOAT) + m_max_spinner->set_value(value.get_float()); + m_enable_signal = true; } void -SliderControlGroup::set_max(float val) +SliderControlGroup::set_name(const string& name) { - m_enable_signal = false; - m_max_spinner->set_value(val); - m_enable_signal = true; + string name_label = ""; + name_label += name + ""; + m_name_label->set_markup(name_label); } diff --git a/src/progs/ingenuity/ControlGroups.h b/src/progs/ingenuity/ControlGroups.h index 85542dbe..4994a809 100644 --- a/src/progs/ingenuity/ControlGroups.h +++ b/src/progs/ingenuity/ControlGroups.h @@ -54,14 +54,13 @@ public: protected: virtual void set_value(float value) = 0; - virtual void set_min(float min) = 0; - virtual void set_max(float max) = 0; - virtual void metadata_update(const string& key, const Atom& value); + virtual void metadata_update(const string& key, const Atom& value) = 0; ControlPanel* m_control_panel; SharedPtr m_port_model; bool m_has_separator; Gtk::VSeparator* m_separator; + bool m_enable_signal; }; @@ -80,6 +79,7 @@ public: private: void set_name(const string& name); + virtual void metadata_update(const string& key, const Atom& value); inline void set_value(const float val); void set_min(float val); @@ -96,7 +96,6 @@ private: bool slider_pressed(GdkEvent* ev); bool m_enabled; - bool m_enable_signal; Gtk::Label* m_name_label; Gtk::SpinButton* m_min_spinner; diff --git a/src/progs/ingenuity/ControlPanel.cpp b/src/progs/ingenuity/ControlPanel.cpp index eb316860..faffae7a 100644 --- a/src/progs/ingenuity/ControlPanel.cpp +++ b/src/progs/ingenuity/ControlPanel.cpp @@ -214,12 +214,16 @@ void ControlPanel::value_changed(const Path& port_path, float val) { if (m_callback_enabled) { + App::instance().engine()->disable_responses(); + if (m_all_voices_radio->get_active()) { App::instance().engine()->set_port_value(port_path, val); } else { int voice = m_voice_spinbutton->get_value_as_int(); App::instance().engine()->set_port_value(port_path, voice, val); } + + App::instance().engine()->set_next_response_id(rand()); // FIXME: inefficient, probably not good } } diff --git a/src/progs/ingenuity/ingenuity.glade b/src/progs/ingenuity/ingenuity.glade index 7ffe43bd..edfb60dd 100644 --- a/src/progs/ingenuity/ingenuity.glade +++ b/src/progs/ingenuity/ingenuity.glade @@ -2179,7 +2179,7 @@ <b>Name</b> False True - GTK_JUSTIFY_CENTER + GTK_JUSTIFY_LEFT False False 1 @@ -2188,11 +2188,11 @@ 0 PANGO_ELLIPSIZE_NONE -1 - False + True 90 - 2 + 0 False False @@ -2203,11 +2203,11 @@ True True True - GTK_POS_BOTTOM + GTK_POS_RIGHT 2 GTK_UPDATE_CONTINUOUS True - 0.7 0 1 0 0 0 + 0.8 0 1 0 0 0 0 -- cgit v1.2.1