diff options
-rw-r--r-- | include/ingen/client/NodeModel.hpp | 5 | ||||
-rw-r--r-- | include/ingen/client/PortModel.hpp | 2 | ||||
-rw-r--r-- | src/client/ClientStore.cpp | 4 | ||||
-rw-r--r-- | src/client/NodeModel.cpp | 15 | ||||
-rw-r--r-- | src/client/ObjectModel.cpp | 6 | ||||
-rw-r--r-- | src/client/PortModel.cpp | 4 | ||||
-rw-r--r-- | src/gui/App.cpp | 28 | ||||
-rw-r--r-- | src/gui/App.hpp | 8 | ||||
-rw-r--r-- | src/gui/Controls.cpp | 10 | ||||
-rw-r--r-- | src/gui/NodeMenu.cpp | 2 | ||||
-rw-r--r-- | src/gui/Port.cpp | 22 | ||||
-rw-r--r-- | src/gui/PortPropertiesWindow.cpp | 3 | ||||
-rw-r--r-- | src/server/events/RegisterClient.cpp | 16 | ||||
-rw-r--r-- | src/shared/LV2URIMap.cpp | 3 | ||||
-rw-r--r-- | src/shared/LV2URIMap.hpp | 3 | ||||
-rw-r--r-- | src/shared/ResourceImpl.cpp | 8 |
16 files changed, 108 insertions, 31 deletions
diff --git a/include/ingen/client/NodeModel.hpp b/include/ingen/client/NodeModel.hpp index efc8514a..c874e6fb 100644 --- a/include/ingen/client/NodeModel.hpp +++ b/include/ingen/client/NodeModel.hpp @@ -66,9 +66,10 @@ public: const Ports& ports() const { return _ports; } void default_port_value_range(SharedPtr<const PortModel> port, - float& min, float& max) const; + float& min, float& max, uint32_t srate=1) const; + void port_value_range(SharedPtr<const PortModel> port, - float& min, float& max) const; + float& min, float& max, uint32_t srate=1) const; std::string port_label(SharedPtr<const PortModel> port) const; diff --git a/include/ingen/client/PortModel.hpp b/include/ingen/client/PortModel.hpp index e8e74f8a..36ab847f 100644 --- a/include/ingen/client/PortModel.hpp +++ b/include/ingen/client/PortModel.hpp @@ -51,7 +51,7 @@ public: inline bool is_input() const { return (_direction == INPUT); } inline bool is_output() const { return (_direction == OUTPUT); } - bool port_property(const std::string& uri) const; + bool port_property(const Raul::URI& uri) const; bool is_numeric() const { return is_a(PortType::CONTROL); } bool is_logarithmic() const { return port_property("http://drobilla.net/ns/ingen#logarithmic"); } diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp index 2d7f0a4b..e1ebd97c 100644 --- a/src/client/ClientStore.cpp +++ b/src/client/ClientStore.cpp @@ -401,6 +401,10 @@ ClientStore::delta(const URI& uri, void ClientStore::set_property(const URI& subject_uri, const URI& predicate, const Atom& value) { + if (subject_uri == _uris->ingen_engine) { + LOG(info) << "Engine property " << predicate << " = " << value << endl; + return; + } SharedPtr<Resource> subject = _resource(subject_uri); if (subject) { subject->set_property(predicate, value); diff --git a/src/client/NodeModel.cpp b/src/client/NodeModel.cpp index 73ee5a5a..09350448 100644 --- a/src/client/NodeModel.cpp +++ b/src/client/NodeModel.cpp @@ -165,7 +165,7 @@ NodeModel::port(uint32_t index) const void NodeModel::default_port_value_range(SharedPtr<const PortModel> port, - float& min, float& max) const + float& min, float& max, uint32_t srate) const { // Default control values min = 0.0; @@ -186,10 +186,16 @@ NodeModel::default_port_value_range(SharedPtr<const PortModel> port, if (!std::isnan(_max_values[port->index()])) max = _max_values[port->index()]; } + + if (port->port_property(_uris.lv2_sampleRate)) { + min *= srate; + max *= srate; + } } void -NodeModel::port_value_range(SharedPtr<const PortModel> port, float& min, float& max) const +NodeModel::port_value_range(SharedPtr<const PortModel> port, + float& min, float& max, uint32_t srate) const { assert(port->parent().get() == this); @@ -205,6 +211,11 @@ NodeModel::port_value_range(SharedPtr<const PortModel> port, float& min, float& if (max <= min) max = min + 1.0; + + if (port->port_property(_uris.lv2_sampleRate)) { + min *= srate; + max *= srate; + } } std::string diff --git a/src/client/ObjectModel.cpp b/src/client/ObjectModel.cpp index 69b40154..03b21247 100644 --- a/src/client/ObjectModel.cpp +++ b/src/client/ObjectModel.cpp @@ -50,8 +50,9 @@ ObjectModel::~ObjectModel() Raul::Atom& ObjectModel::set_property(const Raul::URI& key, const Raul::Atom& value) { - _signal_property.emit(key, value); - return ResourceImpl::set_property(key, value); + Raul::Atom& my_value = ResourceImpl::set_property(key, value); + _signal_property.emit(key, my_value); + return my_value; } void @@ -69,6 +70,7 @@ ObjectModel::get_property(const Raul::URI& key) const return (i != properties().end()) ? i->second : null_atom; } + bool ObjectModel::polyphonic() const { diff --git a/src/client/PortModel.cpp b/src/client/PortModel.cpp index 50731ef0..be6d74a5 100644 --- a/src/client/PortModel.cpp +++ b/src/client/PortModel.cpp @@ -39,9 +39,9 @@ PortModel::supports(const Raul::URI& value_type) const } bool -PortModel::port_property(const std::string& uri) const +PortModel::port_property(const Raul::URI& uri) const { - return has_property(_uris.lv2_portProperty, Raul::URI(uri)); + return has_property(_uris.lv2_portProperty, uri); } void diff --git a/src/gui/App.cpp b/src/gui/App.cpp index edd4ec06..35d31b3e 100644 --- a/src/gui/App.cpp +++ b/src/gui/App.cpp @@ -50,6 +50,8 @@ #include "WindowFactory.hpp" #include "Port.hpp" +#define LOG(s) s << "[GUI] " + using namespace std; using namespace Raul; using namespace Ingen::Client; @@ -73,6 +75,7 @@ App::App(Ingen::Shared::World* world) , _about_dialog(NULL) , _window_factory(new WindowFactory()) , _world(world) + , _sample_rate(48000) , _enable_signal(true) { Glib::set_application_name("Ingen"); @@ -146,7 +149,7 @@ App::run() { assert(_main); _main->run(); - info << "[GUI] Exiting" << endl; + LOG(info) << "Exiting" << endl; } void @@ -168,6 +171,8 @@ App::attach(SharedPtr<SigClientInterface> client) sigc::mem_fun(this, &App::error_response)); _client->signal_error().connect( sigc::mem_fun(this, &App::error_message)); + _client->signal_property_change().connect( + sigc::mem_fun(this, &App::property_change)); } void @@ -211,6 +216,21 @@ App::error_message(const string& str) } void +App::property_change(const Raul::URI& subject, + const Raul::URI& key, + const Raul::Atom& value) +{ + if (subject == uris().ingen_engine && key == uris().ingen_sampleRate) { + if (value.type() == Atom::INT) { + LOG(info) << "Sample rate: " << value << std::endl; + _sample_rate = value.get_int32(); + } else { + error << "Engine sample rate property is not an integer" << std::endl; + } + } +} + +void App::port_activity(Port* port) { std::pair<ActivityPorts::iterator, bool> inserted = _activity_ports.insert(make_pair(port, false)); @@ -373,6 +393,12 @@ App::can_control(const Ingen::Port* port) const || port->supports(uris().atom_String))); } +uint32_t +App::sample_rate() const +{ + return _sample_rate; +} + } // namespace GUI } // namespace Ingen diff --git a/src/gui/App.hpp b/src/gui/App.hpp index 96cd0152..bd753078 100644 --- a/src/gui/App.hpp +++ b/src/gui/App.hpp @@ -92,6 +92,8 @@ public: bool disable_signals() { bool old = _enable_signal; _enable_signal = false; return old; } void enable_signals(bool b) { _enable_signal = b; } + uint32_t sample_rate() const; + ConnectWindow* connect_window() const { return _connect_window; } MessagesWindow* messages_dialog() const { return _messages_window; } PatchTreeWindow* patch_tree() const { return _patch_tree_window; } @@ -136,6 +138,10 @@ protected: bool animate(); void error_response(int32_t id, const std::string& str); + void property_change(const Raul::URI& subject, + const Raul::URI& key, + const Raul::Atom& value); + static void* icon_destroyed(void* data); static Gtk::Main* _main; @@ -155,6 +161,8 @@ protected: Ingen::Shared::World* _world; + uint32_t _sample_rate; + typedef std::map<Port*, bool> ActivityPorts; ActivityPorts _activity_ports; diff --git a/src/gui/Controls.cpp b/src/gui/Controls.cpp index 98b1c726..e31c8d52 100644 --- a/src/gui/Controls.cpp +++ b/src/gui/Controls.cpp @@ -152,7 +152,7 @@ SliderControl::init(ControlPanel* panel, SharedPtr<const PortModel> pm) boost::shared_ptr<NodeModel> parent = PtrCast<NodeModel>(_port_model->parent()); if (parent) - parent->port_value_range(_port_model, min, max); + parent->port_value_range(_port_model, min, max, App::instance().sample_rate()); if (pm->is_integer() || pm->is_toggle()) { _slider->set_increments(1, 10); @@ -164,7 +164,8 @@ SliderControl::init(ControlPanel* panel, SharedPtr<const PortModel> pm) pm->signal_property().connect( sigc::mem_fun(this, &SliderControl::port_property_changed)); - _slider->set_range(std::min(min, pm->value().get_float()), std::max(max, pm->value().get_float())); + set_range(std::min(min, pm->value().get_float()), + std::max(max, pm->value().get_float())); set_value(pm->value()); @@ -201,10 +202,8 @@ SliderControl::set_value(const Atom& atom) if (val < lower || val > upper) set_range(min(lower, val), max(lower, val)); _slider->set_value(val); - } - - if (_value_spinner->get_value() != val) _value_spinner->set_value(val); + } _enable_signal = true; } @@ -231,6 +230,7 @@ SliderControl::set_range(float min, float max) max = min + 1.0; _slider->set_range(min, max); + _value_spinner->set_range(min, max); } void diff --git a/src/gui/NodeMenu.cpp b/src/gui/NodeMenu.cpp index 6cbba39d..0432d888 100644 --- a/src/gui/NodeMenu.cpp +++ b/src/gui/NodeMenu.cpp @@ -142,7 +142,7 @@ NodeMenu::on_menu_randomize() for (NodeModel::Ports::const_iterator i = nm->ports().begin(); i != nm->ports().end(); ++i) { if ((*i)->is_input() && App::instance().can_control(i->get())) { float min = 0.0f, max = 1.0f; - nm->port_value_range(*i, min, max); + nm->port_value_range(*i, min, max, App::instance().sample_rate()); const float val = ((rand() / (float)RAND_MAX) * (max - min) + min); App::instance().engine()->set_property((*i)->path(), App::instance().uris().ingen_value, val); diff --git a/src/gui/Port.cpp b/src/gui/Port.cpp index 25edf685..9b2a1c8f 100644 --- a/src/gui/Port.cpp +++ b/src/gui/Port.cpp @@ -111,7 +111,7 @@ Port::update_metadata() if (parent) { float min = 0.0f; float max = 1.0f; - parent->port_value_range(pm, min, max); + parent->port_value_range(pm, min, max, App::instance().sample_rate()); set_control_min(min); set_control_max(max); } @@ -193,12 +193,20 @@ Port::property_changed(const URI& key, const Atom& value) { const LV2URIMap& uris = App::instance().uris(); if (value.type() == Atom::FLOAT) { - if (key == uris.ingen_value && !_pressed) - set_control(value.get_float(), false); - else if (key == uris.lv2_minimum) - set_control_min(value.get_float()); - else if (key == uris.lv2_maximum) - set_control_max(value.get_float()); + float val = value.get_float(); + if (key == uris.ingen_value && !_pressed) { + set_control(val, false); + } else if (key == uris.lv2_minimum) { + if (model()->port_property(uris.lv2_sampleRate)) { + val *= App::instance().sample_rate(); + } + set_control_min(val); + } else if (key == uris.lv2_maximum) { + if (model()->port_property(uris.lv2_sampleRate)) { + val *= App::instance().sample_rate(); + } + set_control_max(val); + } } else if (key == uris.lv2_portProperty) { if (value == uris.lv2_toggled) set_toggled(true); diff --git a/src/gui/PortPropertiesWindow.cpp b/src/gui/PortPropertiesWindow.cpp index a584939c..0b51074b 100644 --- a/src/gui/PortPropertiesWindow.cpp +++ b/src/gui/PortPropertiesWindow.cpp @@ -70,7 +70,8 @@ PortPropertiesWindow::present(SharedPtr<const PortModel> pm) float min = 0.0f, max = 1.0f; boost::shared_ptr<NodeModel> parent = PtrCast<NodeModel>(_port_model->parent()); if (parent) - parent->port_value_range(_port_model, min, max); + parent->port_value_range(_port_model, min, max, + App::instance().sample_rate()); _initial_min = min; _initial_max = max; diff --git a/src/server/events/RegisterClient.cpp b/src/server/events/RegisterClient.cpp index 71ec26bc..32c1a0c9 100644 --- a/src/server/events/RegisterClient.cpp +++ b/src/server/events/RegisterClient.cpp @@ -15,10 +15,12 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "ClientBroadcaster.hpp" +#include "Driver.hpp" +#include "Engine.hpp" #include "Request.hpp" #include "events/RegisterClient.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" +#include "shared/LV2URIMap.hpp" using namespace Raul; @@ -49,6 +51,16 @@ void RegisterClient::post_process() { _request->respond_ok(); + + /* Tell the client the engine's sample rate (which it needs to know to + interpret control bounds for lv2:sampleRate ports). This is a bit of a + kludge. TODO: keep a proper RDF model to describe the engine and send + that to clients. + */ + const Ingen::Shared::LV2URIMap& uris = *_engine.world()->uris().get(); + _client->set_property(uris.ingen_engine, + uris.ingen_sampleRate, + int32_t(_engine.driver()->sample_rate())); } } // namespace Server diff --git a/src/shared/LV2URIMap.cpp b/src/shared/LV2URIMap.cpp index d2c4f270..4ca5a033 100644 --- a/src/shared/LV2URIMap.cpp +++ b/src/shared/LV2URIMap.cpp @@ -81,10 +81,12 @@ LV2URIMap::LV2URIMap() , ingen_controlBinding (NS_INGEN "controlBinding") , ingen_document (NS_INGEN "document") , ingen_enabled (NS_INGEN "enabled") + , ingen_engine (NS_INGEN "engine") , ingen_nil (NS_INGEN "nil") , ingen_node (NS_INGEN "node") , ingen_polyphonic (NS_INGEN "polyphonic") , ingen_polyphony (NS_INGEN "polyphony") + , ingen_sampleRate (NS_INGEN "sampleRate") , ingen_selected (NS_INGEN "selected") , ingen_value (NS_INGEN "value") , ingenui_canvas_x (NS_INGENUI "canvas-x") @@ -101,6 +103,7 @@ LV2URIMap::LV2URIMap() , lv2_minimum (NS_LV2 "minimum") , lv2_name (NS_LV2 "name") , lv2_portProperty (NS_LV2 "portProperty") + , lv2_sampleRate (NS_LV2 "sampleRate") , lv2_symbol (NS_LV2 "symbol") , lv2_toggled (NS_LV2 "toggled") , midi_Bender (NS_MIDI "Bender") diff --git a/src/shared/LV2URIMap.hpp b/src/shared/LV2URIMap.hpp index b7d0ff7b..75f6748e 100644 --- a/src/shared/LV2URIMap.hpp +++ b/src/shared/LV2URIMap.hpp @@ -113,10 +113,12 @@ public: const Quark ingen_controlBinding; const Quark ingen_document; const Quark ingen_enabled; + const Quark ingen_engine; const Quark ingen_nil; const Quark ingen_node; const Quark ingen_polyphonic; const Quark ingen_polyphony; + const Quark ingen_sampleRate; const Quark ingen_selected; const Quark ingen_value; const Quark ingenui_canvas_x; @@ -133,6 +135,7 @@ public: const Quark lv2_minimum; const Quark lv2_name; const Quark lv2_portProperty; + const Quark lv2_sampleRate; const Quark lv2_symbol; const Quark lv2_toggled; const Quark midi_Bender; diff --git a/src/shared/ResourceImpl.cpp b/src/shared/ResourceImpl.cpp index 9f663be1..d315b8f0 100644 --- a/src/shared/ResourceImpl.cpp +++ b/src/shared/ResourceImpl.cpp @@ -152,11 +152,9 @@ ResourceImpl::type( void ResourceImpl::set_properties(const Properties& p) { - typedef Resource::Properties::const_iterator iterator; - for (iterator i = p.begin(); i != p.end(); ++i) - _properties.erase(i->first); - for (iterator i = p.begin(); i != p.end(); ++i) - add_property(i->first, i->second); + for (Resource::Properties::const_iterator i = p.begin(); i != p.end(); ++i) { + set_property(i->first, i->second); + } } void |