diff options
author | David Robillard <d@drobilla.net> | 2011-02-17 03:11:41 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2011-02-17 03:11:41 +0000 |
commit | df7a87fe043440d99b23378efc6664b5deed8b42 (patch) | |
tree | faf7f20f1dc209f0e16b565008df58e1af096585 /src/engine | |
parent | 8c6a7c4ad5f5cb6b3b583aefbfe6b0cf57414294 (diff) | |
download | ingen-df7a87fe043440d99b23378efc6664b5deed8b42.tar.gz ingen-df7a87fe043440d99b23378efc6664b5deed8b42.tar.bz2 ingen-df7a87fe043440d99b23378efc6664b5deed8b42.zip |
Fix "Ingen as an LV2", i.e. make Ingen bundles working LV2 plugins.
Fix module loading/unloading (don't use statics).
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2973 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine')
-rw-r--r-- | src/engine/ingen_engine.cpp | 10 | ||||
-rw-r--r-- | src/engine/ingen_http.cpp | 10 | ||||
-rw-r--r-- | src/engine/ingen_jack.cpp | 10 | ||||
-rw-r--r-- | src/engine/ingen_lv2.cpp | 161 | ||||
-rw-r--r-- | src/engine/ingen_osc.cpp | 10 |
5 files changed, 84 insertions, 117 deletions
diff --git a/src/engine/ingen_engine.cpp b/src/engine/ingen_engine.cpp index 5d278803..2c728603 100644 --- a/src/engine/ingen_engine.cpp +++ b/src/engine/ingen_engine.cpp @@ -37,16 +37,12 @@ struct IngenEngineModule : public Ingen::Shared::Module { } }; -static IngenEngineModule* module = NULL; - extern "C" { Ingen::Shared::Module* -ingen_module_load() { - if (!module) - module = new IngenEngineModule(); - - return module; +ingen_module_load() +{ + return new IngenEngineModule(); } } // extern "C" diff --git a/src/engine/ingen_http.cpp b/src/engine/ingen_http.cpp index 878c8f6b..6eb5cd9f 100644 --- a/src/engine/ingen_http.cpp +++ b/src/engine/ingen_http.cpp @@ -33,16 +33,12 @@ struct IngenHTTPModule : public Ingen::Shared::Module { } }; -static IngenHTTPModule* module = NULL; - extern "C" { Ingen::Shared::Module* -ingen_module_load() { - if (!module) - module = new IngenHTTPModule(); - - return module; +ingen_module_load() +{ + return new IngenHTTPModule(); } } // extern "C" diff --git a/src/engine/ingen_jack.cpp b/src/engine/ingen_jack.cpp index 05a6b673..77dfff55 100644 --- a/src/engine/ingen_jack.cpp +++ b/src/engine/ingen_jack.cpp @@ -32,16 +32,12 @@ struct IngenJackModule : public Ingen::Shared::Module { } }; -static IngenJackModule* module = NULL; - extern "C" { Ingen::Shared::Module* -ingen_module_load() { - if (!module) - module = new IngenJackModule(); - - return module; +ingen_module_load() +{ + return new IngenJackModule(); } } // extern "C" diff --git a/src/engine/ingen_lv2.cpp b/src/engine/ingen_lv2.cpp index 1c5db44c..3b62eca9 100644 --- a/src/engine/ingen_lv2.cpp +++ b/src/engine/ingen_lv2.cpp @@ -1,5 +1,5 @@ /* Ingen.LV2 - A thin wrapper which allows Ingen to run as an LV2 plugin. - * Copyright (C) 2008-2009 David Robillard <http://drobilla.net> + * Copyright (C) 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 @@ -16,11 +16,12 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include <glib.h> #include <stdlib.h> #include <string> #include <vector> + +#include <glib.h> #include <glibmm/convert.h> #include <glibmm/miscutils.h> @@ -47,12 +48,7 @@ #include "ingen-config.h" -using namespace Ingen; - -namespace Ingen { -namespace LV2 { - -/** Record of a patch found in this LV2 bundle */ +/** Record of a patch in this Ingen LV2 bundle */ struct LV2Patch { LV2Patch(const std::string& u, const std::string& f); @@ -61,16 +57,24 @@ struct LV2Patch { LV2_Descriptor descriptor; }; +class Lib { +public: + Lib(); + ~Lib(); + + typedef std::vector< SharedPtr<const LV2Patch> > Patches; + + Patches patches; + Ingen::Configuration conf; + int argc; + char** argv; +}; -/* Static library data */ -typedef std::vector< SharedPtr<const LV2Patch> > LV2Patches; -static bool initialised = false; -static LV2Patches patches; -static Configuration conf; -static int argc = 0; -static char** argv = NULL; -static Shared::World* world = NULL; +/** Library state (constructed/destructed on library load/unload) */ +Lib lib; +namespace Ingen { +namespace LV2 { struct LV2Driver; @@ -120,7 +124,6 @@ private: void* _buffer; }; - struct LV2Driver : public Driver { private: typedef std::vector<LV2Port*> Ports; @@ -177,7 +180,6 @@ public: return NULL; } - virtual bool supports(Shared::PortType port_type, Shared::EventType event_type) { return true; } @@ -217,29 +219,33 @@ private: } // namespace LV2 } // namespace Ingen - -/* LV2 Plugin Interface */ - extern "C" { +/** 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); - + using namespace Ingen; using namespace LV2; + Shared::set_bundle_path(bundle_path); + const LV2Patch* patch = NULL; - for (LV2Patches::iterator i = patches.begin(); i != patches.end(); ++i) { + for (Lib::Patches::iterator i = lib.patches.begin(); i != lib.patches.end(); ++i) { if (&(*i)->descriptor == descriptor) { patch = (*i).get(); break; @@ -252,14 +258,19 @@ ingen_instantiate(const LV2_Descriptor* descriptor, } IngenPlugin* plugin = (IngenPlugin*)malloc(sizeof(IngenPlugin)); - //plugin->world = ingen_world_new(&conf, argc, argv); - plugin->world = LV2::world; + plugin->world = ingen_world_new(&lib.conf, lib.argc, lib.argv); + if (!plugin->world->load("ingen_serialisation")) { + ingen_world_free(plugin->world); + return NULL; + } SharedPtr<Engine> engine(new Engine(plugin->world)); plugin->world->set_local_engine(engine); SharedPtr<QueuedEngineInterface> interface( - new Ingen::QueuedEngineInterface(*plugin->world->local_engine(), event_queue_size)); + new Ingen::QueuedEngineInterface(*plugin->world->local_engine(), + event_queue_size)); + plugin->world->set_engine(interface); plugin->world->local_engine()->add_event_source(interface); @@ -283,7 +294,8 @@ ingen_instantiate(const LV2_Descriptor* descriptor, engine->post_processor()->process(); plugin->world->parser()->parse_document(plugin->world, - plugin->world->engine().get(), patch->filename); + plugin->world->engine().get(), + patch->filename); while (!interface->empty()) { interface->process(*engine->post_processor(), context, false); @@ -295,12 +307,12 @@ ingen_instantiate(const LV2_Descriptor* descriptor, return (LV2_Handle)plugin; } - static void ingen_connect_port(LV2_Handle instance, uint32_t port, void* data) { - IngenPlugin* me = (IngenPlugin*)instance; - LV2::LV2Driver* driver = (LV2::LV2Driver*)me->world->local_engine()->driver(); + IngenPlugin* me = (IngenPlugin*)instance; + SharedPtr<Ingen::Engine> engine = me->world->local_engine(); + Ingen::LV2::LV2Driver* driver = (Ingen::LV2::LV2Driver*)engine->driver(); if (port < driver->ports().size()) { driver->ports().at(port)->set_buffer(data); assert(driver->ports().at(port)->patch_port()->index() == port); @@ -309,7 +321,6 @@ ingen_connect_port(LV2_Handle instance, uint32_t port, void* data) } } - static void ingen_activate(LV2_Handle instance) { @@ -317,17 +328,15 @@ ingen_activate(LV2_Handle instance) me->world->local_engine()->activate(); } - static void ingen_run(LV2_Handle instance, uint32_t sample_count) { IngenPlugin* me = (IngenPlugin*)instance; // FIXME: don't do this every call - Raul::Thread::get().set_context(THREAD_PROCESS); - ((LV2::LV2Driver*)me->world->local_engine()->driver())->run(sample_count); + Raul::Thread::get().set_context(Ingen::THREAD_PROCESS); + ((Ingen::LV2::LV2Driver*)me->world->local_engine()->driver())->run(sample_count); } - static void ingen_deactivate(LV2_Handle instance) { @@ -335,32 +344,25 @@ ingen_deactivate(LV2_Handle instance) me->world->local_engine()->deactivate(); } - static void ingen_cleanup(LV2_Handle instance) { IngenPlugin* me = (IngenPlugin*)instance; - me->world->set_local_engine(SharedPtr<Engine>()); - me->world->set_engine(SharedPtr<EngineInterface>()); - //ingen_world_free(me->world); + me->world->set_local_engine(SharedPtr<Ingen::Engine>()); + me->world->set_engine(SharedPtr<Ingen::EngineInterface>()); + ingen_world_free(me->world); free(instance); } - static const void* ingen_extension_data(const char* uri) { return NULL; } - -/* Library Code */ - -namespace Ingen { -namespace LV2 { - LV2Patch::LV2Patch(const std::string& u, const std::string& f) - : uri(u), filename(f) + : uri(u) + , filename(f) { descriptor.URI = uri.c_str(); descriptor.instantiate = ingen_instantiate; @@ -372,63 +374,44 @@ LV2Patch::LV2Patch(const std::string& u, const std::string& f) descriptor.extension_data = ingen_extension_data; } -} // namespace LV2 -} // namespace Ingen - - -static void -init() +/** Library constructor (called on shared library load) */ +Lib::Lib() + : argc(0) + , argv(NULL) { - Shared::set_bundle_path_from_code((void*)&init); + if (!Glib::thread_supported()) + Glib::thread_init(); + using namespace Ingen; using namespace LV2; - //Shared::World* world = ingen_world_new(&conf, argc, argv); + Ingen::Shared::set_bundle_path_from_code((void*)&lv2_descriptor); - world = ingen_world_new(&conf, argc, argv); + Ingen::Shared::World* world = ingen_world_new(&conf, argc, argv); if (!world->load("ingen_serialisation")) { - Raul::error << "Unable to load serialisation module" << std::endl; - //ingen_world_free(world); + ingen_world_free(world); return; } + assert(world->parser()); + + typedef Serialisation::Parser::PatchRecords Records; - Serialisation::Parser::PatchRecords records( - world->parser()->find_patches(world, - Glib::filename_to_uri(Shared::bundle_file_path("manifest.ttl")))); + Records records(world->parser()->find_patches( + world, Glib::filename_to_uri( + Shared::bundle_file_path("manifest.ttl")))); - for (Serialisation::Parser::PatchRecords::iterator i = records.begin(); - i != records.end(); ++i) { + for (Records::iterator i = records.begin(); i != records.end(); ++i) { patches.push_back(SharedPtr<const LV2Patch>( - new LV2Patch(i->uri.str(), i->filename))); + new LV2Patch(i->uri.str(), i->filename))); } - - //ingen_world_free(world); - - initialised = true; + ingen_world_free(world); } - -/* LV2 Library Interface */ - -extern "C" { - -LV2_SYMBOL_EXPORT -const LV2_Descriptor* -lv2_descriptor(uint32_t index) +/** Library destructor (called on shared library unload) */ +Lib::~Lib() { - if (!LV2::initialised) - init(); - - if (index >= LV2::patches.size()) - return NULL; - else - return &LV2::patches[index]->descriptor; } -} - - } // extern "C" - diff --git a/src/engine/ingen_osc.cpp b/src/engine/ingen_osc.cpp index 30958833..d5cffdce 100644 --- a/src/engine/ingen_osc.cpp +++ b/src/engine/ingen_osc.cpp @@ -34,16 +34,12 @@ struct IngenOSCModule : public Ingen::Shared::Module { } }; -static IngenOSCModule* module = NULL; - extern "C" { Ingen::Shared::Module* -ingen_module_load() { - if (!module) - module = new IngenOSCModule(); - - return module; +ingen_module_load() +{ + return new IngenOSCModule(); } } // extern "C" |