diff options
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/BlockImpl.hpp | 2 | ||||
-rw-r--r-- | src/server/GraphPlugin.hpp | 3 | ||||
-rw-r--r-- | src/server/InternalBlock.cpp | 2 | ||||
-rw-r--r-- | src/server/InternalPlugin.cpp | 3 | ||||
-rw-r--r-- | src/server/InternalPlugin.hpp | 3 | ||||
-rw-r--r-- | src/server/LV2Block.cpp | 103 | ||||
-rw-r--r-- | src/server/LV2Block.hpp | 9 | ||||
-rw-r--r-- | src/server/LV2Plugin.cpp | 5 | ||||
-rw-r--r-- | src/server/LV2Plugin.hpp | 3 | ||||
-rw-r--r-- | src/server/PluginImpl.hpp | 3 | ||||
-rw-r--r-- | src/server/events/CreateBlock.cpp | 22 |
11 files changed, 109 insertions, 49 deletions
diff --git a/src/server/BlockImpl.hpp b/src/server/BlockImpl.hpp index 2d7211ab..8f937dc5 100644 --- a/src/server/BlockImpl.hpp +++ b/src/server/BlockImpl.hpp @@ -103,7 +103,7 @@ public: virtual LilvState* load_preset(const Raul::URI& uri) { return NULL; } /** Restore `state`. */ - virtual void apply_state(Worker* worker, LilvState* state) {} + virtual void apply_state(Worker* worker, const LilvState* state) {} /** Save current state as preset. */ virtual boost::optional<Resource> diff --git a/src/server/GraphPlugin.hpp b/src/server/GraphPlugin.hpp index 7d365383..9100b058 100644 --- a/src/server/GraphPlugin.hpp +++ b/src/server/GraphPlugin.hpp @@ -43,7 +43,8 @@ public: const Raul::Symbol& symbol, bool polyphonic, GraphImpl* parent, - Engine& engine) + Engine& engine, + const LilvState* state) { return NULL; } diff --git a/src/server/InternalBlock.cpp b/src/server/InternalBlock.cpp index e26bdc10..ffb5163f 100644 --- a/src/server/InternalBlock.cpp +++ b/src/server/InternalBlock.cpp @@ -39,7 +39,7 @@ InternalBlock::duplicate(Engine& engine, BufferFactory& bufs = *engine.buffer_factory(); BlockImpl* copy = reinterpret_cast<InternalPlugin*>(_plugin)->instantiate( - bufs, symbol, _polyphonic, parent_graph(), engine); + bufs, symbol, _polyphonic, parent_graph(), engine, NULL); for (size_t i = 0; i < num_ports(); ++i) { const Atom& value = port_impl(i)->value(); diff --git a/src/server/InternalPlugin.cpp b/src/server/InternalPlugin.cpp index 3d065fe3..1d397f14 100644 --- a/src/server/InternalPlugin.cpp +++ b/src/server/InternalPlugin.cpp @@ -46,7 +46,8 @@ InternalPlugin::instantiate(BufferFactory& bufs, const Raul::Symbol& symbol, bool polyphonic, GraphImpl* parent, - Engine& engine) + Engine& engine, + const LilvState* state) { const SampleCount srate = engine.driver()->sample_rate(); diff --git a/src/server/InternalPlugin.hpp b/src/server/InternalPlugin.hpp index bcbfe71a..d95afa1a 100644 --- a/src/server/InternalPlugin.hpp +++ b/src/server/InternalPlugin.hpp @@ -43,7 +43,8 @@ public: const Raul::Symbol& symbol, bool polyphonic, GraphImpl* parent, - Engine& engine); + Engine& engine, + const LilvState* state); const Raul::Symbol symbol() const { return _symbol; } diff --git a/src/server/LV2Block.cpp b/src/server/LV2Block.cpp index 309b68da..c20abfda 100644 --- a/src/server/LV2Block.cpp +++ b/src/server/LV2Block.cpp @@ -75,20 +75,6 @@ LV2Block::~LV2Block() delete _instances; } -void -LV2Block::load_default_state(Worker* worker) -{ - const LilvPlugin* lplug = _lv2_plugin->lilv_plugin(); - const LilvNode* uri_node = lilv_plugin_get_uri(lplug); - const Raul::URI uri(lilv_node_as_string(uri_node)); - - LilvState* default_state = load_preset(_lv2_plugin->uri()); - if (default_state) { - apply_state(worker, default_state); - lilv_state_free(default_state); - } -} - SPtr<LilvInstance> LV2Block::make_instance(URIs& uris, SampleRate rate, @@ -229,7 +215,7 @@ LV2Block::apply_poly(RunContext& context, Raul::Maid& maid, uint32_t poly) * value is false, this object may not be used. */ bool -LV2Block::instantiate(BufferFactory& bufs) +LV2Block::instantiate(BufferFactory& bufs, const LilvState* state) { const Ingen::URIs& uris = bufs.uris(); Ingen::World* world = bufs.engine().world(); @@ -446,7 +432,20 @@ LV2Block::instantiate(BufferFactory& bufs) } } - load_default_state(NULL); + // Load initial state if no state is explicitly given + LilvState* default_state = NULL; + if (!state) { + state = default_state = load_preset(_lv2_plugin->uri()); + } + + // Apply state + if (state) { + apply_state(NULL, state); + } + + if (default_state) { + lilv_state_free(default_state); + } // FIXME: Polyphony + worker? if (lilv_plugin_has_feature(plug, uris.work_schedule)) { @@ -458,6 +457,38 @@ LV2Block::instantiate(BufferFactory& bufs) return ret; } +bool +LV2Block::save_state(const std::string& dir) const +{ + World* world = _lv2_plugin->world(); + LilvWorld* lworld = world->lilv_world(); + + LilvState* state = lilv_state_new_from_instance( + _lv2_plugin->lilv_plugin(), const_cast<LV2Block*>(this)->instance(0), + &world->uri_map().urid_map_feature()->urid_map, + NULL, dir.c_str(), dir.c_str(), dir.c_str(), NULL, NULL, + LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, NULL); + + if (!state) { + return false; + } else if (lilv_state_get_num_properties(state) == 0) { + lilv_state_free(state); + return false; + } + + lilv_state_save(lworld, + &world->uri_map().urid_map_feature()->urid_map, + &world->uri_map().urid_unmap_feature()->urid_unmap, + state, + NULL, + dir.c_str(), + "state.ttl"); + + lilv_state_free(state); + + return true; +} + BlockImpl* LV2Block::duplicate(Engine& engine, const Raul::Symbol& symbol, @@ -465,9 +496,15 @@ LV2Block::duplicate(Engine& engine, { const SampleRate rate = engine.driver()->sample_rate(); + // Get current state + LilvState* state = lilv_state_new_from_instance( + _lv2_plugin->lilv_plugin(), instance(0), + &engine.world()->uri_map().urid_map_feature()->urid_map, + NULL, NULL, NULL, NULL, NULL, NULL, LV2_STATE_IS_NATIVE, NULL); + // Duplicate and instantiate block LV2Block* dup = new LV2Block(_lv2_plugin, symbol, _polyphonic, parent, rate); - if (!dup->instantiate(*engine.buffer_factory())) { + if (!dup->instantiate(*engine.buffer_factory(), state)) { delete dup; return NULL; } @@ -482,19 +519,6 @@ LV2Block::duplicate(Engine& engine, dup->port_impl(p)->set_properties(port_impl(p)->properties()); } - // Copy internal plugin state - for (uint32_t v = 0; v < _polyphony; ++v) { - LilvState* state = lilv_state_new_from_instance( - _lv2_plugin->lilv_plugin(), instance(v), - &engine.world()->uri_map().urid_map_feature()->urid_map, - NULL, NULL, NULL, NULL, NULL, NULL, LV2_STATE_IS_NATIVE, NULL); - if (state) { - lilv_state_restore(state, dup->instance(v), - NULL, NULL, LV2_STATE_IS_NATIVE, NULL); - lilv_state_free(state); - } - } - return dup; } @@ -593,8 +617,25 @@ LV2Block::load_preset(const Raul::URI& uri) return state; } +LilvState* +LV2Block::load_state(World* world, const std::string& path) +{ + LilvWorld* lworld = world->lilv_world(); + const std::string uri = Glib::filename_to_uri(path); + LilvNode* subject = lilv_new_uri(lworld, uri.c_str()); + + LilvState* state = lilv_state_new_from_file( + lworld, + &world->uri_map().urid_map_feature()->urid_map, + subject, + path.c_str()); + + lilv_node_free(subject); + return state; +} + void -LV2Block::apply_state(Worker* worker, LilvState* state) +LV2Block::apply_state(Worker* worker, const LilvState* state) { World* world = parent_graph()->engine().world(); SPtr<LV2_Feature> sched; diff --git a/src/server/LV2Block.hpp b/src/server/LV2Block.hpp index b8438d9e..b6be8ccf 100644 --- a/src/server/LV2Block.hpp +++ b/src/server/LV2Block.hpp @@ -48,9 +48,10 @@ public: ~LV2Block(); - bool instantiate(BufferFactory& bufs); + bool instantiate(BufferFactory& bufs, const LilvState* state); LilvInstance* instance() { return instance(0); } + bool save_state(const std::string& dir) const; BlockImpl* duplicate(Engine& engine, const Raul::Symbol& symbol, @@ -69,7 +70,7 @@ public: LilvState* load_preset(const Raul::URI& uri); - void apply_state(Worker* worker, LilvState* state); + void apply_state(Worker* worker, const LilvState* state); boost::optional<Resource> save_preset(const Raul::URI& bundle, const Properties& props); @@ -79,14 +80,14 @@ public: BufferRef buf, SampleCount offset); + static LilvState* load_state(World* world, const std::string& path); + protected: SPtr<LilvInstance> make_instance(URIs& uris, SampleRate rate, uint32_t voice, bool preparing); - void load_default_state(Worker* worker); - inline LilvInstance* instance(uint32_t voice) { return (LilvInstance*)(*_instances)[voice].get(); } diff --git a/src/server/LV2Plugin.cpp b/src/server/LV2Plugin.cpp index f8a0ecd8..8e820b8e 100644 --- a/src/server/LV2Plugin.cpp +++ b/src/server/LV2Plugin.cpp @@ -90,12 +90,13 @@ LV2Plugin::instantiate(BufferFactory& bufs, const Raul::Symbol& symbol, bool polyphonic, GraphImpl* parent, - Engine& engine) + Engine& engine, + const LilvState* state) { LV2Block* b = new LV2Block( this, symbol, polyphonic, parent, engine.driver()->sample_rate()); - if (!b->instantiate(bufs)) { + if (!b->instantiate(bufs, state)) { delete b; return NULL; } else { diff --git a/src/server/LV2Plugin.hpp b/src/server/LV2Plugin.hpp index aa10d90a..f490bbfd 100644 --- a/src/server/LV2Plugin.hpp +++ b/src/server/LV2Plugin.hpp @@ -45,7 +45,8 @@ public: const Raul::Symbol& symbol, bool polyphonic, GraphImpl* parent, - Engine& engine); + Engine& engine, + const LilvState* state); const Raul::Symbol symbol() const; diff --git a/src/server/PluginImpl.hpp b/src/server/PluginImpl.hpp index 29daba7b..9728bf36 100644 --- a/src/server/PluginImpl.hpp +++ b/src/server/PluginImpl.hpp @@ -58,7 +58,8 @@ public: const Raul::Symbol& symbol, bool polyphonic, GraphImpl* parent, - Engine& engine) = 0; + Engine& engine, + const LilvState* state) = 0; virtual const Raul::Symbol symbol() const = 0; diff --git a/src/server/events/CreateBlock.cpp b/src/server/events/CreateBlock.cpp index 231df4e2..a43a8bf0 100644 --- a/src/server/events/CreateBlock.cpp +++ b/src/server/events/CreateBlock.cpp @@ -29,6 +29,7 @@ #include "PluginImpl.hpp" #include "PortImpl.hpp" #include "PreProcessContext.hpp" +#include "LV2Block.hpp" namespace Ingen { namespace Server { @@ -118,11 +119,22 @@ CreateBlock::pre_process(PreProcessContext& ctx) PluginImpl* const plugin = _engine.block_factory()->plugin(prototype); if (!plugin) { return Event::pre_process_done(Status::PROTOTYPE_NOT_FOUND, prototype); - } else if (!(_block = plugin->instantiate(*_engine.buffer_factory(), - Raul::Symbol(_path.symbol()), - polyphonic, - _graph, - _engine))) { + } + + // Load state from directory if given in properties + LilvState* state = NULL; + Resource::Properties::iterator s = _properties.find(uris.state_state); + if (s != _properties.end() && s->second.type() == uris.forge.Path) { + state = LV2Block::load_state(_engine.world(), s->second.ptr<char>()); + } + + // Instantiate plugin + if (!(_block = plugin->instantiate(*_engine.buffer_factory(), + Raul::Symbol(_path.symbol()), + polyphonic, + _graph, + _engine, + state))) { return Event::pre_process_done(Status::CREATION_FAILED, _path); } } |