summaryrefslogtreecommitdiffstats
path: root/src/server/ingen_lv2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/ingen_lv2.cpp')
-rw-r--r--src/server/ingen_lv2.cpp223
1 files changed, 115 insertions, 108 deletions
diff --git a/src/server/ingen_lv2.cpp b/src/server/ingen_lv2.cpp
index d709e41a..658f759b 100644
--- a/src/server/ingen_lv2.cpp
+++ b/src/server/ingen_lv2.cpp
@@ -15,7 +15,6 @@
*/
#include "Buffer.hpp"
-#include "BufferRef.hpp"
#include "Driver.hpp"
#include "DuplexPort.hpp"
#include "Engine.hpp"
@@ -26,46 +25,47 @@
#include "ThreadManager.hpp"
#include "types.hpp"
-#include "ingen/AtomReader.hpp"
-#include "ingen/AtomSink.hpp"
-#include "ingen/AtomWriter.hpp"
-#include "ingen/Configuration.hpp"
-#include "ingen/EngineBase.hpp"
-#include "ingen/FilePath.hpp"
-#include "ingen/Forge.hpp"
-#include "ingen/Interface.hpp"
-#include "ingen/Log.hpp"
-#include "ingen/Node.hpp"
-#include "ingen/Parser.hpp"
-#include "ingen/Serialiser.hpp"
-#include "ingen/Store.hpp"
-#include "ingen/URI.hpp"
-#include "ingen/URIs.hpp"
-#include "ingen/World.hpp"
-#include "ingen/ingen.h"
-#include "ingen/memory.hpp"
-#include "ingen/runtime_paths.hpp"
-#include "lv2/atom/atom.h"
-#include "lv2/atom/util.h"
-#include "lv2/buf-size/buf-size.h"
-#include "lv2/core/lv2.h"
-#include "lv2/log/log.h"
-#include "lv2/log/logger.h"
-#include "lv2/options/options.h"
-#include "lv2/state/state.h"
-#include "lv2/urid/urid.h"
-#include "raul/Maid.hpp"
-#include "raul/Path.hpp"
-#include "raul/RingBuffer.hpp"
-#include "raul/Semaphore.hpp"
-#include "raul/Symbol.hpp"
-#include "serd/serd.h"
-#include "sord/sordmm.hpp"
+#include <ingen/AtomReader.hpp>
+#include <ingen/AtomSink.hpp>
+#include <ingen/AtomWriter.hpp>
+#include <ingen/Configuration.hpp>
+#include <ingen/EngineBase.hpp>
+#include <ingen/FilePath.hpp>
+#include <ingen/Forge.hpp>
+#include <ingen/Interface.hpp>
+#include <ingen/Log.hpp>
+#include <ingen/Node.hpp>
+#include <ingen/Parser.hpp>
+#include <ingen/Serialiser.hpp>
+#include <ingen/Store.hpp>
+#include <ingen/URI.hpp>
+#include <ingen/URIs.hpp>
+#include <ingen/World.hpp>
+#include <ingen/ingen.h>
+#include <ingen/memory.hpp>
+#include <ingen/runtime_paths.hpp>
+#include <lv2/atom/atom.h>
+#include <lv2/atom/util.h>
+#include <lv2/buf-size/buf-size.h>
+#include <lv2/core/lv2.h>
+#include <lv2/log/log.h>
+#include <lv2/log/logger.h>
+#include <lv2/options/options.h>
+#include <lv2/state/state.h>
+#include <lv2/urid/urid.h>
+#include <raul/Maid.hpp>
+#include <raul/Path.hpp>
+#include <raul/RingBuffer.hpp>
+#include <raul/Semaphore.hpp>
+#include <raul/Symbol.hpp>
+#include <serd/serd.h>
+#include <sord/sordmm.hpp>
#include <algorithm>
#include <cstdint>
#include <cstdlib>
#include <cstring>
+#include <iterator>
#include <memory>
#include <mutex>
#include <set>
@@ -74,11 +74,9 @@
#include <utility>
#include <vector>
-namespace ingen {
+// #define CLEAR_GRAPH_ON_RESTORE 1
-class Atom;
-
-namespace server {
+namespace ingen::server {
class GraphImpl;
@@ -90,7 +88,8 @@ struct LV2Graph : public Parser::ResourceRecord {
};
/** Ingen LV2 library. */
-class Lib {
+class Lib
+{
public:
explicit Lib(const char* bundle_path);
@@ -99,19 +98,23 @@ public:
Graphs graphs;
};
+namespace {
+
inline size_t
ui_ring_size(SampleCount block_length)
{
- return std::max(static_cast<size_t>(8192u),
- static_cast<size_t>(block_length) * 16u);
+ return std::max(static_cast<size_t>(8192U),
+ static_cast<size_t>(block_length) * 16U);
}
+} // namespace
+
class LV2Driver : public Driver, public ingen::AtomSink
{
public:
LV2Driver(Engine& engine,
SampleCount block_length,
- size_t seq_size,
+ uint32_t seq_size,
SampleCount sample_rate)
: _engine(engine)
, _main_sem(0)
@@ -124,15 +127,9 @@ public:
*this)
, _from_ui(ui_ring_size(block_length))
, _to_ui(ui_ring_size(block_length))
- , _root_graph(nullptr)
- , _notify_capacity(0)
, _block_length(block_length)
, _seq_size(seq_size)
, _sample_rate(sample_rate)
- , _frame_time(0)
- , _to_ui_overflow_sem(0)
- , _to_ui_overflow(false)
- , _instantiated(false)
{}
bool dynamic_ports() const override { return !_instantiated; }
@@ -151,11 +148,11 @@ public:
lv2_atom_total_size(
static_cast<LV2_Atom*>(lv2_buf)));
- if (graph_port->symbol() == "control") { // TODO: Safe to use index?
+ if (graph_port->symbol() == "control") { // TODO: Safe to use index?
auto* seq = reinterpret_cast<LV2_Atom_Sequence*>(lv2_buf);
bool enqueued = false;
- LV2_ATOM_SEQUENCE_FOREACH(seq, ev)
+ LV2_ATOM_SEQUENCE_FOREACH (seq, ev)
{
if (AtomReader::is_message(uris, &ev->body)) {
enqueued = enqueue_message(&ev->body) || enqueued;
@@ -220,13 +217,12 @@ public:
virtual GraphImpl* root_graph() { return _root_graph; }
EnginePort* get_port(const raul::Path& path) override {
- for (auto& p : _ports) {
- if (p->graph_port()->path() == path) {
- return p;
- }
- }
+ const auto i =
+ std::find_if(_ports.begin(), _ports.end(), [&path](const auto& p) {
+ return p->graph_port()->path() == path;
+ });
- return nullptr;
+ return i == _ports.end() ? nullptr : *i;
}
/** Add a port. Called only during init or restore. */
@@ -268,7 +264,7 @@ public:
const URIs& uris = _engine.world().uris();
auto* seq = static_cast<LV2_Atom_Sequence*>(_ports[0]->buffer());
- LV2_ATOM_SEQUENCE_FOREACH(seq, ev) {
+ LV2_ATOM_SEQUENCE_FOREACH (seq, ev) {
if (ev->body.type == uris.atom_Object) {
const LV2_Atom_Object* obj =
reinterpret_cast<LV2_Atom_Object*>(&ev->body);
@@ -322,7 +318,13 @@ public:
break;
}
- buf = realloc(buf, sizeof(LV2_Atom) + atom.size);
+ void* const new_buf = realloc(buf, sizeof(LV2_Atom) + atom.size);
+ if (!new_buf) {
+ _engine.log().rt_error("Failed to allocate for from-UI ring\n");
+ break;
+ }
+
+ buf = new_buf;
memcpy(buf, &atom, sizeof(LV2_Atom));
if (!_from_ui.read(atom.size,
@@ -365,14 +367,14 @@ public:
if (seq->atom.size + lv2_atom_pad_size(
sizeof(LV2_Atom_Event) + atom.size)
> _notify_capacity) {
- break; // Output port buffer full, resume next time
+ break; // Output port buffer full, resume next time
}
auto* ev = reinterpret_cast<LV2_Atom_Event*>(
reinterpret_cast<uint8_t*>(seq) +
lv2_atom_total_size(&seq->atom));
- ev->time.frames = 0; // TODO: Time?
+ ev->time.frames = 0; // TODO: Time?
ev->body = atom;
_to_ui.skip(sizeof(LV2_Atom));
@@ -392,7 +394,7 @@ public:
}
SampleCount block_length() const override { return _block_length; }
- size_t seq_size() const override { return _seq_size; }
+ uint32_t seq_size() const override { return _seq_size; }
SampleCount sample_rate() const override { return _sample_rate; }
SampleCount frame_time() const override { return _frame_time; }
@@ -413,15 +415,15 @@ private:
AtomWriter _writer;
raul::RingBuffer _from_ui;
raul::RingBuffer _to_ui;
- GraphImpl* _root_graph;
- uint32_t _notify_capacity;
+ GraphImpl* _root_graph{nullptr};
+ uint32_t _notify_capacity{0};
SampleCount _block_length;
- size_t _seq_size;
+ uint32_t _seq_size;
SampleCount _sample_rate;
- SampleCount _frame_time;
- raul::Semaphore _to_ui_overflow_sem;
- bool _to_ui_overflow;
- bool _instantiated;
+ SampleCount _frame_time{0};
+ raul::Semaphore _to_ui_overflow_sem{0};
+ bool _to_ui_overflow{false};
+ bool _instantiated{false};
};
struct IngenPlugin {
@@ -465,9 +467,10 @@ find_graphs(const URI& manifest_uri)
URI(INGEN__Graph));
Lib::Graphs graphs;
- for (const auto& r : resources) {
- graphs.push_back(std::make_shared<LV2Graph>(r));
- }
+ std::transform(resources.begin(),
+ resources.end(),
+ std::back_inserter(graphs),
+ [](const auto& r) { return std::make_shared<LV2Graph>(r); });
return graphs;
}
@@ -501,7 +504,9 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
if (!map) {
lv2_log_error(&logger, "host did not provide URI map feature\n");
return nullptr;
- } else if (!unmap) {
+ }
+
+ if (!unmap) {
lv2_log_error(&logger, "host did not provide URI unmap feature\n");
return nullptr;
}
@@ -515,16 +520,16 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
nullptr,
true);
- Lib::Graphs graphs = find_graphs(URI(reinterpret_cast<const char*>(manifest_node.buf)));
+ const Lib::Graphs graphs = find_graphs(URI(reinterpret_cast<const char*>(manifest_node.buf)));
serd_node_free(&manifest_node);
- const LV2Graph* graph = nullptr;
- for (const auto& g : graphs) {
- if (g->uri == descriptor->URI) {
- graph = g.get();
- break;
- }
- }
+ const auto g = std::find_if(graphs.begin(),
+ graphs.end(),
+ [&descriptor](const auto& graph) {
+ return graph->uri == descriptor->URI;
+ });
+
+ const LV2Graph* const graph = g == graphs.end() ? nullptr : g->get();
if (!graph) {
lv2_log_error(&logger, "could not find graph <%s>\n", descriptor->URI);
@@ -533,14 +538,14 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
auto* plugin = new IngenPlugin();
plugin->map = map;
- plugin->world = make_unique<ingen::World>(map, unmap, log);
+ plugin->world = std::make_unique<ingen::World>(map, unmap, log);
plugin->world->load_configuration(plugin->argc, plugin->argv);
- LV2_URID bufsz_max = map->map(map->handle, LV2_BUF_SIZE__maxBlockLength);
- LV2_URID bufsz_seq = map->map(map->handle, LV2_BUF_SIZE__sequenceSize);
- LV2_URID atom_Int = map->map(map->handle, LV2_ATOM__Int);
- int32_t block_length = 0;
- int32_t seq_size = 0;
+ const LV2_URID bufsz_max = map->map(map->handle, LV2_BUF_SIZE__maxBlockLength);
+ const LV2_URID bufsz_seq = map->map(map->handle, LV2_BUF_SIZE__sequenceSize);
+ const LV2_URID atom_Int = map->map(map->handle, LV2_ATOM__Int);
+ int32_t block_length = 0;
+ int32_t seq_size = 0;
if (options) {
for (const LV2_Options_Option* o = options; o->key; ++o) {
if (o->key == bufsz_max && o->type == atom_Int) {
@@ -554,7 +559,7 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
block_length = 4096;
plugin->world->log().warn("No maximum block length given\n");
}
- if (seq_size == 0) {
+ if (seq_size < 1) {
seq_size = 16384;
plugin->world->log().warn("No maximum sequence size given\n");
}
@@ -570,20 +575,21 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
plugin->engine = engine;
plugin->world->set_engine(engine);
- std::shared_ptr<Interface> interface = engine->interface();
+ const std::shared_ptr<Interface> interface = engine->interface();
plugin->world->set_interface(interface);
ThreadManager::set_flag(THREAD_PRE_PROCESS);
ThreadManager::single_threaded = true;
- auto* driver = new LV2Driver(*engine, block_length, seq_size, rate);
+ auto* driver = new LV2Driver(
+ *engine, block_length, static_cast<uint32_t>(seq_size), rate);
engine->set_driver(std::shared_ptr<Driver>(driver));
engine->activate();
ThreadManager::single_threaded = true;
- std::lock_guard<std::mutex> lock(plugin->world->rdf_mutex());
+ const std::lock_guard<std::mutex> lock{plugin->world->rdf_mutex()};
// Locate to time 0 to process initialization events
engine->locate(0, block_length);
@@ -605,7 +611,7 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
/* Register client after loading graph so the to-ui ring does not overflow.
Since we are not yet rolling, it won't be drained, causing a deadlock. */
- std::shared_ptr<Interface> client(&driver->writer(), NullDeleter<Interface>);
+ const std::shared_ptr<Interface> client{&driver->writer(), NullDeleter<Interface>};
interface->set_respondee(client);
engine->register_client(client);
@@ -616,8 +622,8 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
static void
ingen_connect_port(LV2_Handle instance, uint32_t port, void* data)
{
- auto* me = static_cast<IngenPlugin*>(instance);
- Engine* engine = static_cast<Engine*>(me->world->engine().get());
+ auto* me = static_cast<IngenPlugin*>(instance);
+ const Engine* engine = static_cast<Engine*>(me->world->engine().get());
const auto driver = std::static_pointer_cast<LV2Driver>(engine->driver());
if (port < driver->ports().size()) {
driver->ports().at(port)->set_buffer(data);
@@ -633,7 +639,7 @@ ingen_activate(LV2_Handle instance)
auto engine = std::static_pointer_cast<Engine>(me->world->engine());
const auto driver = std::static_pointer_cast<LV2Driver>(engine->driver());
engine->activate();
- me->main = make_unique<std::thread>(ingen_lv2_main, engine, driver);
+ me->main = std::make_unique<std::thread>(ingen_lv2_main, engine, driver);
}
static void
@@ -673,6 +679,7 @@ ingen_cleanup(LV2_Handle instance)
auto world = std::move(me->world);
delete me;
+ world.reset();
}
static void
@@ -706,9 +713,9 @@ ingen_save(LV2_Handle instance,
return LV2_STATE_ERR_NO_FEATURE;
}
- LV2_URID ingen_file = plugin->map->map(plugin->map->handle, INGEN__file);
- LV2_URID atom_Path = plugin->map->map(plugin->map->handle,
- LV2_ATOM__Path);
+ const LV2_URID ingen_file = plugin->map->map(plugin->map->handle, INGEN__file);
+ const LV2_URID atom_Path = plugin->map->map(plugin->map->handle,
+ LV2_ATOM__Path);
char* real_path = make_path->path(make_path->handle, "main.ttl");
char* state_path = map_path->abstract_path(map_path->handle, real_path);
@@ -716,7 +723,7 @@ ingen_save(LV2_Handle instance,
auto root = plugin->world->store()->find(raul::Path("/"));
{
- std::lock_guard<std::mutex> lock(plugin->world->rdf_mutex());
+ const std::lock_guard<std::mutex> lock{plugin->world->rdf_mutex()};
plugin->world->serialiser()->start_to_file(
root->second->path(), FilePath{real_path});
@@ -752,10 +759,10 @@ ingen_restore(LV2_Handle instance,
return LV2_STATE_ERR_NO_FEATURE;
}
- LV2_URID ingen_file = plugin->map->map(plugin->map->handle, INGEN__file);
- size_t size = 0;
- uint32_t type = 0;
- uint32_t valflags = 0;
+ const LV2_URID ingen_file = plugin->map->map(plugin->map->handle, INGEN__file);
+ size_t size = 0;
+ uint32_t type = 0;
+ uint32_t valflags = 0;
// Get abstract path to graph file
const char* path = static_cast<const char*>(
@@ -770,7 +777,7 @@ ingen_restore(LV2_Handle instance,
return LV2_STATE_ERR_UNKNOWN;
}
-#if 0
+#ifdef CLEAR_GRAPH_ON_RESTORE
// Remove existing root graph contents
std::shared_ptr<Engine> engine = plugin->engine;
for (const auto& b : engine->root_graph()->blocks()) {
@@ -787,7 +794,7 @@ ingen_restore(LV2_Handle instance,
#endif
// Load new graph
- std::lock_guard<std::mutex> lock(plugin->world->rdf_mutex());
+ const std::lock_guard<std::mutex> lock{plugin->world->rdf_mutex()};
plugin->world->parser()->parse_file(
*plugin->world, *plugin->world->interface(), real_path);
@@ -850,8 +857,8 @@ lib_get_plugin(LV2_Lib_Handle handle, uint32_t index)
}
} // extern "C"
-} // namespace server
-} // namespace ingen
+
+} // namespace ingen::server
extern "C" {