diff options
author | David Robillard <d@drobilla.net> | 2016-09-18 21:36:48 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2016-09-18 21:40:46 -0400 |
commit | bb64f80bb139314a06e0b22fddbea7a330b6e149 (patch) | |
tree | 51e78a387bc8f1df6ecff3c1799ae7f0dc3f2bdc /src/server | |
parent | 01deca45d8aa5fbfff75e204cd248a9dd79ab041 (diff) | |
download | ingen-parameters.tar.gz ingen-parameters.tar.bz2 ingen-parameters.zip |
Preliminary parameter support workparameters
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/BlockImpl.hpp | 6 | ||||
-rw-r--r-- | src/server/ClientUpdate.cpp | 15 | ||||
-rw-r--r-- | src/server/ClientUpdate.hpp | 4 | ||||
-rw-r--r-- | src/server/LV2Block.cpp | 20 | ||||
-rw-r--r-- | src/server/Parameter.hpp | 82 | ||||
-rw-r--r-- | src/server/events/Delta.cpp | 4 |
6 files changed, 127 insertions, 4 deletions
diff --git a/src/server/BlockImpl.hpp b/src/server/BlockImpl.hpp index 47eaa6eb..b2816f7d 100644 --- a/src/server/BlockImpl.hpp +++ b/src/server/BlockImpl.hpp @@ -28,6 +28,7 @@ #include "BufferRef.hpp" #include "NodeImpl.hpp" +#include "Parameter.hpp" #include "PluginImpl.hpp" #include "PortType.hpp" #include "RunContext.hpp" @@ -134,6 +135,10 @@ public: virtual Node* port(uint32_t index) const; virtual PortImpl* port_impl(uint32_t index) const { return (*_ports)[index]; } + typedef std::list<Parameter> Parameters; + Parameters& parameters() { return _parameters; } + const Parameters& parameters() const { return _parameters; } + /** Get a port by symbol. */ virtual PortImpl* port_by_symbol(const char* symbol); @@ -187,6 +192,7 @@ protected: PluginImpl* _plugin; Raul::Array<PortImpl*>* _ports; ///< Access in audio thread only + Parameters _parameters; uint32_t _polyphony; std::set<BlockImpl*> _providers; ///< Blocks connected to this one's input ports std::set<BlockImpl*> _dependants; ///< Blocks this one's output ports are connected to diff --git a/src/server/ClientUpdate.cpp b/src/server/ClientUpdate.cpp index 217d3a32..673c6f9e 100644 --- a/src/server/ClientUpdate.cpp +++ b/src/server/ClientUpdate.cpp @@ -50,6 +50,13 @@ ClientUpdate::put_port(const PortImpl* port) } void +ClientUpdate::put_parameter(const Parameter* parameter) +{ + fprintf(stderr, "Put parameter\n"); + put(parameter->uri(), parameter->properties()); +} + +void ClientUpdate::put_block(const BlockImpl* block) { const PluginImpl* const plugin = block->plugin_impl(); @@ -62,6 +69,9 @@ ClientUpdate::put_block(const BlockImpl* block) for (size_t j = 0; j < block->num_ports(); ++j) { put_port(block->port_impl(j)); } + for (const Parameter& p : block->parameters()) { + put_parameter(&p); + } } } @@ -86,6 +96,11 @@ ClientUpdate::put_graph(const GraphImpl* graph) put_port(graph->port_impl(i)); } + // Enqueue parameters + for (const Parameter& p : graph->parameters()) { + put_parameter(&p); + } + // Enqueue arcs for (const auto& a : graph->arcs()) { const SPtr<const Arc> arc = a.second; diff --git a/src/server/ClientUpdate.hpp b/src/server/ClientUpdate.hpp index dcdcc132..c4181daa 100644 --- a/src/server/ClientUpdate.hpp +++ b/src/server/ClientUpdate.hpp @@ -31,10 +31,11 @@ class URIs; namespace Server { -class PortImpl; class BlockImpl; class GraphImpl; +class Parameter; class PluginImpl; +class PortImpl; /** A sequence of puts/connects/deletes to update clients. * @@ -47,6 +48,7 @@ struct ClientUpdate { Resource::Graph ctx=Resource::Graph::DEFAULT); void put_port(const PortImpl* port); + void put_parameter(const Parameter* parameter); void put_block(const BlockImpl* block); void put_graph(const GraphImpl* graph); void put_plugin(PluginImpl* plugin); diff --git a/src/server/LV2Block.cpp b/src/server/LV2Block.cpp index 7dcfb362..6cb5c1f3 100644 --- a/src/server/LV2Block.cpp +++ b/src/server/LV2Block.cpp @@ -23,8 +23,9 @@ #include <glibmm/convert.h> #include "lv2/lv2plug.in/ns/ext/morph/morph.h" -#include "lv2/lv2plug.in/ns/ext/presets/presets.h" #include "lv2/lv2plug.in/ns/ext/options/options.h" +#include "lv2/lv2plug.in/ns/ext/patch/patch.h" +#include "lv2/lv2plug.in/ns/ext/presets/presets.h" #include "lv2/lv2plug.in/ns/ext/resize-port/resize-port.h" #include "lv2/lv2plug.in/ns/ext/state/state.h" @@ -43,6 +44,7 @@ #include "LV2Block.hpp" #include "LV2Plugin.hpp" #include "OutputPort.hpp" +#include "Parameter.hpp" #include "RunContext.hpp" #include "Worker.hpp" @@ -428,6 +430,22 @@ LV2Block::instantiate(BufferFactory& bufs) lilv_node_free(lv2_connectionOptional); + // Discover properties + bool writable = true; + LilvNodes* properties = lilv_world_find_nodes( + world->lilv_world(), + lilv_plugin_get_uri(plug), + writable ? uris.patch_writable : uris.patch_readable, + NULL); + LILV_FOREACH(nodes, p, properties) { + const LilvNode* property = lilv_nodes_get(properties, p); + _parameters.push_back( + Parameter(world, uris, this, + Raul::URI(lilv_node_as_string(property)), + Raul::Symbol(lilv_node_as_string(lilv_world_get_symbol(world->lilv_world(), property))), + Atom())); + } + if (!ret) { delete _ports; _ports = NULL; diff --git a/src/server/Parameter.hpp b/src/server/Parameter.hpp new file mode 100644 index 00000000..d7c0e42a --- /dev/null +++ b/src/server/Parameter.hpp @@ -0,0 +1,82 @@ +/* + This file is part of Ingen. + Copyright 2016 David Robillard <http://drobilla.net/> + + Ingen is free software: you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 of the License, or any later version. + + Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. + + You should have received a copy of the GNU Affero General Public License + along with Ingen. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef INGEN_ENGINE_PARAMETER_HPP +#define INGEN_ENGINE_PARAMETER_HPP + +#include "ingen/World.hpp" + +namespace Ingen { +namespace Server { + +class BlockImpl; + +/** A parameter (message-based control) on a Block. + * + * \ingroup engine + */ +class Parameter : public NodeImpl +{ +public: + static Atom node_to_atom(Forge& forge, const LilvNode* node) { + if (lilv_node_is_float(node)) { + return forge.make(lilv_node_as_float(node)); + } else if (lilv_node_is_uri(node)) { + return forge.make_urid(Raul::URI(lilv_node_as_uri(node))); + } + return Atom(); + } + + Parameter(Ingen::World* world, + const Ingen::URIs& uris, + NodeImpl* parent, + const Raul::URI& uri, + const Raul::Symbol& symbol, + const Atom& value) + : NodeImpl(uris, parent, symbol) + , _value(value) + { + set_property(uris.rdf_type, uris.ingen_Parameter); + set_property(uris.lv2_symbol, uris.forge.alloc(symbol)); + LilvWorld* lworld = world->lilv_world(); + LilvNode* prop = lilv_new_uri(lworld, uri.c_str()); + LilvNode* range = lilv_world_get(lworld, prop, uris.rdfs_range, NULL); + set_property(uris.rdfs_range, node_to_atom(world->forge(), range)); + LilvNode* min = lilv_world_get(lworld, prop, uris.lv2_minimum, NULL); + LilvNode* max = lilv_world_get(lworld, prop, uris.lv2_maximum, NULL); + LilvNode* def = lilv_world_get(lworld, prop, uris.lv2_default, NULL); + set_property(uris.ingen_value, node_to_atom(world->forge(), def)); + set_property(uris.lv2_minimum, node_to_atom(world->forge(), min)); + set_property(uris.lv2_maximum, node_to_atom(world->forge(), max)); + } + + virtual GraphType graph_type() const { return GraphType::PARAMETER; } + + /** A parameter's parent is always a block. */ + BlockImpl* parent_block() const { return (BlockImpl*)_parent; } + + // n/a + virtual bool prepare_poly(BufferFactory&, uint32_t) { return false; } + virtual bool apply_poly(RunContext&, Raul::Maid&, uint32_t) { return false; } + +protected: + Atom _value; +}; + +} // namespace Server +} // namespace Ingen + +#endif // INGEN_ENGINE_PARAMETER_HPP diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp index 49ea27ff..06269f3a 100644 --- a/src/server/events/Delta.cpp +++ b/src/server/events/Delta.cpp @@ -216,8 +216,8 @@ Delta::pre_process() if (is_graph_object && !_object) { Raul::Path path(Node::uri_to_path(_subject)); - bool is_graph = false, is_block = false, is_port = false, is_output = false; - Ingen::Resource::type(uris, _properties, is_graph, is_block, is_port, is_output); + bool is_graph = false, is_block = false, is_port = false, is_parameter = false, is_output = false; + Ingen::Resource::type(uris, _properties, is_graph, is_block, is_port, is_parameter, is_output); if (is_graph) { _create_event = new CreateGraph( |