summaryrefslogtreecommitdiffstats
path: root/src/engine/ingen_lv2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/ingen_lv2.cpp')
-rw-r--r--src/engine/ingen_lv2.cpp422
1 files changed, 0 insertions, 422 deletions
diff --git a/src/engine/ingen_lv2.cpp b/src/engine/ingen_lv2.cpp
deleted file mode 100644
index c6a250b7..00000000
--- a/src/engine/ingen_lv2.cpp
+++ /dev/null
@@ -1,422 +0,0 @@
-/* Ingen.LV2 - A thin wrapper which allows Ingen to run as an LV2 plugin.
- * Copyright 2008-2011 David Robillard <http://drobilla.net>
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This library 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 General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdlib.h>
-
-#include <string>
-#include <vector>
-
-#include <glib.h>
-#include <glibmm/convert.h>
-#include <glibmm/miscutils.h>
-
-#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
-
-#include "raul/SharedPtr.hpp"
-#include "raul/Thread.hpp"
-#include "raul/log.hpp"
-
-#include "engine/AudioBuffer.hpp"
-#include "engine/Driver.hpp"
-#include "engine/Engine.hpp"
-#include "engine/PatchImpl.hpp"
-#include "engine/PostProcessor.hpp"
-#include "engine/ProcessContext.hpp"
-#include "engine/QueuedEngineInterface.hpp"
-#include "engine/ThreadManager.hpp"
-#include "ingen/EngineInterface.hpp"
-#include "shared/World.hpp"
-#include "serialisation/Parser.hpp"
-#include "shared/Configuration.hpp"
-#include "shared/runtime_paths.hpp"
-
-#include "ingen-config.h"
-
-/** Record of a patch in this Ingen LV2 bundle */
-struct LV2Patch {
- LV2Patch(const std::string& u, const std::string& f);
-
- const std::string uri;
- const std::string filename;
- LV2_Descriptor descriptor;
-};
-
-class Lib {
-public:
- Lib();
- ~Lib();
-
- typedef std::vector< SharedPtr<const LV2Patch> > Patches;
-
- Patches patches;
- Ingen::Shared::Configuration conf;
- int argc;
- char** argv;
-};
-
-/** Library state (constructed/destructed on library load/unload) */
-Lib lib;
-
-namespace Ingen {
-namespace Engine {
-
-class LV2Driver;
-
-class LV2Port : public DriverPort
-{
-public:
- LV2Port(LV2Driver* driver, DuplexPort* patch_port)
- : DriverPort(patch_port)
- , _driver(driver)
- , _buffer(NULL)
- {}
-
- // TODO: LV2 dynamic ports
- void create() {}
- void destroy() {}
- void move(const Raul::Path& path) {}
-
- void pre_process(ProcessContext& context) {
- if (!is_input() || !_buffer)
- return;
-
- if (_patch_port->buffer_type() == PortType::AUDIO) {
- AudioBuffer* patch_buf = (AudioBuffer*)_patch_port->buffer(0).get();
- patch_buf->copy((Sample*)_buffer, 0, context.nframes() - 1);
- } else if (_patch_port->buffer_type() == PortType::EVENTS) {
- //Raul::warn << "TODO: LV2 event I/O" << std::endl;
- }
- }
-
- void post_process(ProcessContext& context) {
- if (is_input() || !_buffer)
- return;
-
- if (_patch_port->buffer_type() == PortType::AUDIO) {
- AudioBuffer* patch_buf = (AudioBuffer*)_patch_port->buffer(0).get();
- memcpy((Sample*)_buffer, patch_buf->data(), context.nframes() * sizeof(Sample));
- } else if (_patch_port->buffer_type() == PortType::EVENTS) {
- //Raul::warn << "TODO: LV2 event I/O" << std::endl;
- }
- }
-
- void* buffer() const { return _buffer; }
- void set_buffer(void* buf) { _buffer = buf; }
-
-private:
- LV2Driver* _driver;
- void* _buffer;
-};
-
-class LV2Driver : public Ingen::Engine::Driver {
-private:
- typedef std::vector<LV2Port*> Ports;
-
-public:
- LV2Driver(Engine& engine, SampleCount buffer_size, SampleCount sample_rate)
- : _context(engine)
- , _root_patch(NULL)
- , _buffer_size(buffer_size)
- , _sample_rate(sample_rate)
- , _frame_time(0)
- {}
-
- void run(uint32_t nframes) {
- _context.locate(_frame_time, nframes, 0);
-
- for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i)
- (*i)->pre_process(_context);
-
- _context.engine().process_events(_context);
-
- if (_root_patch)
- _root_patch->process(_context);
-
- for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i)
- (*i)->post_process(_context);
-
- _frame_time += nframes;
- }
-
- virtual void set_root_patch(PatchImpl* patch) { _root_patch = patch; }
- virtual PatchImpl* root_patch() { return _root_patch; }
-
- virtual void add_port(DriverPort* port) {
- // Note this doesn't have to be realtime safe since there's no dynamic LV2 ports
- ThreadManager::assert_thread(THREAD_PROCESS);
- assert(dynamic_cast<LV2Port*>(port));
- assert(port->patch_port()->index() == _ports.size());
- _ports.push_back((LV2Port*)port);
- }
-
- virtual Raul::Deletable* remove_port(const Raul::Path& path,
- DriverPort** port=NULL) {
- // Note this doesn't have to be realtime safe since there's no dynamic LV2 ports
- ThreadManager::assert_thread(THREAD_PROCESS);
-
- for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
- if ((*i)->patch_port()->path() == path) {
- _ports.erase(i);
- return NULL;
- }
- }
-
- Raul::warn << "Unable to find port " << path << std::endl;
- return NULL;
- }
-
- virtual bool supports(PortType port_type, EventType event_type) {
- return true;
- }
-
- virtual DriverPort* create_port(DuplexPort* patch_port) {
- return new LV2Port(this, patch_port);
- }
-
- virtual DriverPort* driver_port(const Raul::Path& path) {
- ThreadManager::assert_thread(THREAD_PROCESS);
-
- for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i)
- if ((*i)->patch_port()->path() == path)
- return (*i);
-
- return NULL;
- }
-
- virtual SampleCount block_length() const { return _buffer_size; }
- virtual SampleCount sample_rate() const { return _sample_rate; }
- virtual SampleCount frame_time() const { return _frame_time;}
-
- virtual bool is_realtime() const { return true; }
- virtual ProcessContext& context() { return _context; }
-
- Ports& ports() { return _ports; }
-
-private:
- ProcessContext _context;
- PatchImpl* _root_patch;
- SampleCount _buffer_size;
- SampleCount _sample_rate;
- SampleCount _frame_time;
- Ports _ports;
-};
-
-} // namespace Engine
-} // namespace Ingen
-
-extern "C" {
-
-using namespace Ingen;
-using namespace Ingen::Engine;
-
-/** LV2 plugin library entry point */
-LV2_SYMBOL_EXPORT
-const LV2_Descriptor*
-lv2_descriptor(uint32_t index)
-{
- return index < lib.patches.size() ? &lib.patches[index]->descriptor : NULL;
-}
-
-struct IngenPlugin {
- Ingen::Shared::World* world;
-};
-
-static LV2_Handle
-ingen_instantiate(const LV2_Descriptor* descriptor,
- double rate,
- const char* bundle_path,
- const LV2_Feature*const* features)
-{
- Shared::set_bundle_path(bundle_path);
-
- const LV2Patch* patch = NULL;
- for (Lib::Patches::iterator i = lib.patches.begin(); i != lib.patches.end(); ++i) {
- if (&(*i)->descriptor == descriptor) {
- patch = (*i).get();
- break;
- }
- }
-
- if (!patch) {
- Raul::error << "Could not find patch " << descriptor->URI << std::endl;
- return NULL;
- }
-
- IngenPlugin* plugin = (IngenPlugin*)malloc(sizeof(IngenPlugin));
- plugin->world = new Ingen::Shared::World(&lib.conf, lib.argc, lib.argv);
- if (!plugin->world->load_module("serialisation")) {
- delete plugin->world;
- return NULL;
- }
-
- SharedPtr<Engine::Engine> engine(new Engine::Engine(plugin->world));
- plugin->world->set_local_engine(engine);
-
- SharedPtr<Engine::QueuedEngineInterface> interface(
- new Engine::QueuedEngineInterface(
- *engine.get(),
- engine->event_queue_size()));
-
- plugin->world->set_engine(interface);
- engine->add_event_source(interface);
-
- Raul::Thread::get().set_context(Engine::THREAD_PRE_PROCESS);
- Engine::ThreadManager::single_threaded = true;
-
- // FIXME: fixed (or at least maximum) buffer size
- LV2Driver* driver = new LV2Driver(*engine.get(), rate, 4096);
- engine->set_driver(SharedPtr<Ingen::Engine::Driver>(driver));
-
- engine->activate();
- Engine::ThreadManager::single_threaded = true;
-
- ProcessContext context(*engine.get());
- context.locate(0, UINT_MAX, 0);
-
- engine->post_processor()->set_end_time(UINT_MAX);
-
- // TODO: Load only necessary plugins
- plugin->world->engine()->get("ingen:plugins");
- interface->process(*engine->post_processor(), context, false);
- engine->post_processor()->process();
-
- plugin->world->parser()->parse_file(plugin->world,
- plugin->world->engine().get(),
- patch->filename);
-
- while (!interface->empty()) {
- interface->process(*engine->post_processor(), context, false);
- engine->post_processor()->process();
- }
-
- engine->deactivate();
-
- return (LV2_Handle)plugin;
-}
-
-static void
-ingen_connect_port(LV2_Handle instance, uint32_t port, void* data)
-{
- using namespace Ingen::Engine;
-
- IngenPlugin* me = (IngenPlugin*)instance;
- Engine::Engine* engine = (Engine::Engine*)me->world->local_engine().get();
- LV2Driver* driver = (LV2Driver*)engine->driver();
- if (port < driver->ports().size()) {
- driver->ports().at(port)->set_buffer(data);
- assert(driver->ports().at(port)->patch_port()->index() == port);
- } else {
- Raul::warn << "Connect to non-existent port " << port << std::endl;
- }
-}
-
-static void
-ingen_activate(LV2_Handle instance)
-{
- IngenPlugin* me = (IngenPlugin*)instance;
- me->world->local_engine()->activate();
-}
-
-static void
-ingen_run(LV2_Handle instance, uint32_t sample_count)
-{
- IngenPlugin* me = (IngenPlugin*)instance;
- Engine::Engine* engine = (Engine::Engine*)me->world->local_engine().get();
- // FIXME: don't do this every call
- Raul::Thread::get().set_context(Ingen::Engine::THREAD_PROCESS);
- ((LV2Driver*)engine->driver())->run(sample_count);
-}
-
-static void
-ingen_deactivate(LV2_Handle instance)
-{
- IngenPlugin* me = (IngenPlugin*)instance;
- me->world->local_engine()->deactivate();
-}
-
-static void
-ingen_cleanup(LV2_Handle instance)
-{
- IngenPlugin* me = (IngenPlugin*)instance;
- me->world->set_local_engine(SharedPtr<Ingen::Engine::Engine>());
- me->world->set_engine(SharedPtr<Ingen::EngineInterface>());
- delete me->world;
- free(instance);
-}
-
-static const void*
-ingen_extension_data(const char* uri)
-{
- return NULL;
-}
-
-LV2Patch::LV2Patch(const std::string& u, const std::string& f)
- : uri(u)
- , filename(f)
-{
- descriptor.URI = uri.c_str();
- descriptor.instantiate = ingen_instantiate;
- descriptor.connect_port = ingen_connect_port;
- descriptor.activate = ingen_activate;
- descriptor.run = ingen_run;
- descriptor.deactivate = ingen_deactivate;
- descriptor.cleanup = ingen_cleanup;
- descriptor.extension_data = ingen_extension_data;
-}
-
-/** Library constructor (called on shared library load) */
-Lib::Lib()
- : argc(0)
- , argv(NULL)
-{
- if (!Glib::thread_supported())
- Glib::thread_init();
-
- using namespace Ingen;
-
- Ingen::Shared::set_bundle_path_from_code((void*)&lv2_descriptor);
-
- Ingen::Shared::World* world = new Ingen::Shared::World(&conf, argc, argv);
- if (!world->load_module("serialisation")) {
- delete world;
- return;
- }
-
- assert(world->parser());
-
- typedef Serialisation::Parser::PatchRecords Records;
-
- Records records(world->parser()->find_patches(
- world, Glib::filename_to_uri(
- Shared::bundle_file_path("manifest.ttl"))));
-
- for (Records::iterator i = records.begin(); i != records.end(); ++i) {
- patches.push_back(
- SharedPtr<const LV2Patch>(new LV2Patch(i->patch_uri.str(),
- i->file_uri)));
- }
-
- delete world;
-}
-
-/** Library destructor (called on shared library unload) */
-Lib::~Lib()
-{
-}
-
-} // extern "C"