summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/BlockImpl.hpp2
-rw-r--r--src/server/GraphPlugin.hpp3
-rw-r--r--src/server/InternalBlock.cpp2
-rw-r--r--src/server/InternalPlugin.cpp3
-rw-r--r--src/server/InternalPlugin.hpp3
-rw-r--r--src/server/LV2Block.cpp103
-rw-r--r--src/server/LV2Block.hpp9
-rw-r--r--src/server/LV2Plugin.cpp5
-rw-r--r--src/server/LV2Plugin.hpp3
-rw-r--r--src/server/PluginImpl.hpp3
-rw-r--r--src/server/events/CreateBlock.cpp22
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);
}
}