summaryrefslogtreecommitdiffstats
path: root/src/engine/ingen.lv2/ingen_lv2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/ingen.lv2/ingen_lv2.cpp')
-rw-r--r--src/engine/ingen.lv2/ingen_lv2.cpp193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/engine/ingen.lv2/ingen_lv2.cpp b/src/engine/ingen.lv2/ingen_lv2.cpp
new file mode 100644
index 00000000..4c81c42b
--- /dev/null
+++ b/src/engine/ingen.lv2/ingen_lv2.cpp
@@ -0,0 +1,193 @@
+/* Ingen.LV2 - A thin wrapper which allows Ingen to run as an LV2 plugin.
+ * Copyright (C) 2008 Dave 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.
+ */
+
+#ifndef PLUGIN_URI
+#error "This file requires PLUGIN_URI to be defined"
+#endif
+
+#include <stdlib.h>
+#include "lv2.h"
+#include "engine/Engine.hpp"
+#include "engine/AudioDriver.hpp"
+#include "engine/ProcessContext.hpp"
+#include "engine/PatchImpl.hpp"
+#include "module/World.hpp"
+
+extern "C" {
+
+using namespace Ingen;
+
+/* Plugin */
+
+struct IngenLV2Driver : public Ingen::AudioDriver {
+ IngenLV2Driver(Engine& engine, SampleCount buffer_size, SampleCount sample_rate)
+ : _context(engine)
+ , _buffer_size(buffer_size)
+ , _sample_rate(sample_rate)
+ , _frame_time(0)
+ {}
+
+ void activate() {}
+ void deactivate() {}
+ bool is_activated() const { return true; }
+
+ void run(uint32_t nframes) {
+ _context.set_time_slice(nframes, _frame_time, _frame_time + nframes);
+ if (_root_patch)
+ _root_patch->process(_context);
+ _frame_time += nframes;
+ }
+
+ virtual void set_root_patch(PatchImpl* patch) {}
+ virtual PatchImpl* root_patch() { return NULL; }
+
+ virtual void add_port(DriverPort* port) {}
+ virtual DriverPort* remove_port(const Raul::Path& path) { return NULL; }
+
+ virtual DriverPort* create_port(DuplexPort* patch_port) { return NULL; }
+
+ virtual DriverPort* driver_port(const Raul::Path& path) { return NULL; }
+
+ virtual SampleCount buffer_size() 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; }
+
+private:
+ ProcessContext _context;
+ PatchImpl* _root_patch;
+ SampleCount _buffer_size;
+ SampleCount _sample_rate;
+ SampleCount _frame_time;
+};
+
+
+struct IngenPlugin {
+ Ingen::Shared::World* world;
+ SharedPtr<Ingen::Engine> engine;
+};
+
+
+static void
+ingen_activate(LV2_Handle instance)
+{
+ IngenPlugin* plugin = (IngenPlugin*)instance;
+ plugin->engine->activate(1);
+}
+
+
+static void
+ingen_cleanup(LV2_Handle instance)
+{
+ IngenPlugin* plugin = (IngenPlugin*)instance;
+ plugin->engine.reset();
+ Ingen::Shared::destroy_world();
+ free(instance);
+}
+
+
+static void
+ingen_connect_port(LV2_Handle instance, uint32_t port, void* data)
+{
+ //IngenPlugin* plugin = (IngenPlugin*)instance;
+}
+
+
+static LV2_Handle
+ingen_instantiate(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature*const* features)
+{
+ IngenPlugin* plugin = (IngenPlugin*)malloc(sizeof(IngenPlugin));
+
+ plugin->world = Ingen::Shared::get_world();
+ plugin->engine = SharedPtr<Engine>(new Engine(plugin->world));
+ plugin->world->local_engine = plugin->engine;
+
+ // FIXME: fixed buffer size
+ plugin->engine->set_driver(DataType::AUDIO,
+ SharedPtr<Driver>(new IngenLV2Driver(*plugin->engine, rate, 4096)));
+
+ return (LV2_Handle)plugin;
+}
+
+
+static void
+ingen_run(LV2_Handle instance, uint32_t sample_count)
+{
+ IngenPlugin* plugin = (IngenPlugin*)instance;
+ ((IngenLV2Driver*)plugin->engine->audio_driver())->run(sample_count);
+}
+
+
+static const void*
+ingen_extension_data(const char* uri)
+{
+ return NULL;
+}
+
+
+static void
+ingen_deactivate(LV2_Handle instance)
+{
+ IngenPlugin* plugin = (IngenPlugin*)instance;
+ plugin->engine->deactivate();
+}
+
+
+/* Library */
+
+static LV2_Descriptor *ingen_descriptor = NULL;
+
+static void
+init_descriptor()
+{
+ ingen_descriptor = (LV2_Descriptor*)malloc(sizeof(LV2_Descriptor));
+
+ ingen_descriptor->URI = PLUGIN_URI;
+ ingen_descriptor->instantiate = ingen_instantiate;
+ ingen_descriptor->connect_port = ingen_connect_port;
+ ingen_descriptor->activate = ingen_activate;
+ ingen_descriptor->run = ingen_run;
+ ingen_descriptor->deactivate = ingen_deactivate;
+ ingen_descriptor->cleanup = ingen_cleanup;
+ ingen_descriptor->extension_data = ingen_extension_data;
+}
+
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ if (!ingen_descriptor)
+ init_descriptor();
+
+ switch (index) {
+ case 0:
+ return ingen_descriptor;
+ default:
+ return NULL;
+ }
+}
+
+
+} // extern "C"
+