From bcc2b2a1032306711591ae59205b81ed67d08387 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 21 Oct 2011 05:16:22 +0000 Subject: Fix running as an LV2 plugin. Install template bundles for loading Ingen in LV2 hosts. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@3555 a436a847-0d15-0410-975c-d299462d15a1 --- ingen.lv2/manifest.ttl | 28 +++++++++++++ ingen.lv2/mono_effect.ttl | 71 ++++++++++++++++++++++++++++++++ ingen.lv2/mono_synth.ttl | 56 ++++++++++++++++++++++++++ ingen.lv2/stereo_effect.ttl | 96 ++++++++++++++++++++++++++++++++++++++++++++ ingen.lv2/stereo_synth.ttl | 67 +++++++++++++++++++++++++++++++ src/serialisation/Parser.cpp | 11 +++-- src/server/Engine.cpp | 4 ++ src/server/Engine.hpp | 6 +-- src/server/events/Get.cpp | 15 ++++--- src/server/ingen_lv2.cpp | 23 +++++++++++ src/server/wscript | 12 +++--- src/shared/LV2URIMap.cpp | 1 + src/shared/LV2URIMap.hpp | 1 + wscript | 4 ++ 14 files changed, 377 insertions(+), 18 deletions(-) create mode 100644 ingen.lv2/manifest.ttl create mode 100644 ingen.lv2/mono_effect.ttl create mode 100644 ingen.lv2/mono_synth.ttl create mode 100644 ingen.lv2/stereo_effect.ttl create mode 100644 ingen.lv2/stereo_synth.ttl diff --git a/ingen.lv2/manifest.ttl b/ingen.lv2/manifest.ttl new file mode 100644 index 00000000..1789c078 --- /dev/null +++ b/ingen.lv2/manifest.ttl @@ -0,0 +1,28 @@ +@prefix ingen: . +@prefix lv2: . +@prefix rdfs: . +@prefix templates: . + + + a lv2:Plugin , + ingen:Patch ; + rdfs:seeAlso ; + lv2:binary . + + + a lv2:Plugin , + ingen:Patch ; + rdfs:seeAlso ; + lv2:binary . + + + a lv2:Plugin , + ingen:Patch ; + rdfs:seeAlso ; + lv2:binary . + + + a lv2:Plugin , + ingen:Patch ; + rdfs:seeAlso ; + lv2:binary . diff --git a/ingen.lv2/mono_effect.ttl b/ingen.lv2/mono_effect.ttl new file mode 100644 index 00000000..bef63789 --- /dev/null +++ b/ingen.lv2/mono_effect.ttl @@ -0,0 +1,71 @@ +@prefix rdf: . +@prefix dc: . +@prefix doap: . +@prefix ingen: . +@prefix ingenui: . +@prefix lv2: . +@prefix lv2ev: . +@prefix ctx: . +@prefix lv2midi: . +@prefix midi: . +@prefix owl: . +@prefix rdfs: . +@prefix xsd: . +@prefix atom: . + +<> + ingen:connection [ + ingen:destination ; + ingen:source + ] ; + ingen:polyphony 1 ; + lv2:port , + , + , + ; + lv2:symbol "mono_effect" ; + doap:name "Ingen Mono Effect" ; + a ingen:Patch , + lv2:Plugin . + + + ingen:polyphonic false ; + ingenui:canvas-x 12.50000000 ; + ingenui:canvas-y 95.00000000 ; + lv2:index 2 ; + lv2:name "Audio In 1" ; + lv2:symbol "audio_in_1" ; + a lv2:AudioPort , + lv2:InputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 154.25000000 ; + ingenui:canvas-y 52.50000000 ; + lv2:index 3 ; + lv2:name "Audio Out 1" ; + lv2:symbol "audio_out_1" ; + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 23.50000000 ; + ingenui:canvas-y 180.00000000 ; + lv2:index 0 ; + lv2:name "Control" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_in" ; + a lv2ev:EventPort , + lv2:InputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 23.50000000 ; + ingenui:canvas-y 137.50000000 ; + lv2:index 1 ; + lv2:name "Control" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_out" ; + a lv2ev:EventPort , + lv2:OutputPort . diff --git a/ingen.lv2/mono_synth.ttl b/ingen.lv2/mono_synth.ttl new file mode 100644 index 00000000..0ad68611 --- /dev/null +++ b/ingen.lv2/mono_synth.ttl @@ -0,0 +1,56 @@ +@prefix rdf: . +@prefix dc: . +@prefix doap: . +@prefix ingen: . +@prefix ingenui: . +@prefix lv2: . +@prefix lv2ev: . +@prefix ctx: . +@prefix lv2midi: . +@prefix midi: . +@prefix owl: . +@prefix rdfs: . +@prefix xsd: . +@prefix atom: . + +<> + ingen:polyphony 1 ; + lv2:port , + , + ; + lv2:symbol "mono_synth" ; + doap:name "Ingen Mono Synth" ; + a ingen:Patch , + lv2:Plugin . + + + ingen:polyphonic false ; + ingenui:canvas-x 154.25000000 ; + ingenui:canvas-y 52.50000000 ; + lv2:index 3 ; + lv2:name "Audio Out 1" ; + lv2:symbol "audio_out_1" ; + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 23.50000000 ; + ingenui:canvas-y 180.00000000 ; + lv2:index 0 ; + lv2:name "Control" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_in" ; + a lv2ev:EventPort , + lv2:InputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 23.50000000 ; + ingenui:canvas-y 137.50000000 ; + lv2:index 1 ; + lv2:name "Control" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_out" ; + a lv2ev:EventPort , + lv2:OutputPort . diff --git a/ingen.lv2/stereo_effect.ttl b/ingen.lv2/stereo_effect.ttl new file mode 100644 index 00000000..bc73483f --- /dev/null +++ b/ingen.lv2/stereo_effect.ttl @@ -0,0 +1,96 @@ +@prefix rdf: . +@prefix dc: . +@prefix doap: . +@prefix ingen: . +@prefix ingenui: . +@prefix lv2: . +@prefix lv2ev: . +@prefix ctx: . +@prefix lv2midi: . +@prefix midi: . +@prefix owl: . +@prefix rdfs: . +@prefix xsd: . +@prefix atom: . + +<> + ingen:connection [ + ingen:destination ; + ingen:source + ] , [ + ingen:destination ; + ingen:source + ] ; + ingen:polyphony 1 ; + lv2:port , + , + , + , + , + ; + lv2:symbol "stereo_effect" ; + doap:name "Ingen Stereo Effect" ; + a ingen:Patch , + lv2:Plugin . + + + ingen:polyphonic false ; + ingenui:canvas-x 12.50000000 ; + ingenui:canvas-y 95.00000000 ; + lv2:index 2 ; + lv2:name "Audio In 1" ; + lv2:symbol "audio_in_1" ; + a lv2:AudioPort , + lv2:InputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 12.50000000 ; + ingenui:canvas-y 52.50000000 ; + lv2:index 4 ; + lv2:name "Audio In 2" ; + lv2:symbol "audio_in_2" ; + a lv2:AudioPort , + lv2:InputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 154.25000000 ; + ingenui:canvas-y 52.50000000 ; + lv2:index 3 ; + lv2:name "Audio Out 1" ; + lv2:symbol "audio_out_1" ; + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 154.25000000 ; + ingenui:canvas-y 52.50000000 ; + lv2:index 5 ; + lv2:name "Audio Out 2" ; + lv2:symbol "audio_out_2" ; + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 23.50000000 ; + ingenui:canvas-y 180.00000000 ; + lv2:index 0 ; + lv2:name "Control" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_in" ; + a lv2ev:EventPort , + lv2:InputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 23.50000000 ; + ingenui:canvas-y 137.50000000 ; + lv2:index 1 ; + lv2:name "Control" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_out" ; + a lv2ev:EventPort , + lv2:OutputPort . diff --git a/ingen.lv2/stereo_synth.ttl b/ingen.lv2/stereo_synth.ttl new file mode 100644 index 00000000..1ebac299 --- /dev/null +++ b/ingen.lv2/stereo_synth.ttl @@ -0,0 +1,67 @@ +@prefix rdf: . +@prefix dc: . +@prefix doap: . +@prefix ingen: . +@prefix ingenui: . +@prefix lv2: . +@prefix lv2ev: . +@prefix ctx: . +@prefix lv2midi: . +@prefix midi: . +@prefix owl: . +@prefix rdfs: . +@prefix xsd: . +@prefix atom: . + +<> + ingen:polyphony 1 ; + lv2:port , + , + , + ; + lv2:symbol "stereo_synth" ; + doap:name "Ingen Stereo Synth" ; + a ingen:Patch , + lv2:Plugin . + + + ingen:polyphonic false ; + ingenui:canvas-x 154.25000000 ; + ingenui:canvas-y 52.50000000 ; + lv2:index 3 ; + lv2:name "Audio Out 1" ; + lv2:symbol "audio_out_1" ; + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 154.25000000 ; + ingenui:canvas-y 52.50000000 ; + lv2:index 5 ; + lv2:name "Audio Out 2" ; + lv2:symbol "audio_out_2" ; + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 23.50000000 ; + ingenui:canvas-y 180.00000000 ; + lv2:index 0 ; + lv2:name "Control" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_in" ; + a lv2ev:EventPort , + lv2:InputPort . + + + ingen:polyphonic false ; + ingenui:canvas-x 23.50000000 ; + ingenui:canvas-y 137.50000000 ; + lv2:index 1 ; + lv2:name "Control" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_out" ; + a lv2ev:EventPort , + lv2:OutputPort . diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp index 27110c9d..92577294 100644 --- a/src/serialisation/Parser.cpp +++ b/src/serialisation/Parser.cpp @@ -564,10 +564,15 @@ Parser::find_patches(Ingen::Shared::World* world, std::list records; for (Sord::Iter i = model.find(nil, rdf_type, ingen_Patch); !i.end(); ++i) { - const Sord::Node patch = i.get_subject(); - Sord::Iter f = model.find(patch, rdfs_seeAlso, nil); + const Sord::Node patch = i.get_subject(); + Sord::Iter f = model.find(patch, rdfs_seeAlso, nil); + std::string patch_uri_str = patch.to_c_string(); + if (patch_uri_str[0] == '/') { + // FIXME: Kludge path to be a proper URI (not sure why this is happening) + patch_uri_str = string("file://") + patch_uri_str; + } if (!f.end()) { - records.push_back(PatchRecord(patch.to_c_string(), + records.push_back(PatchRecord(patch_uri_str, f.get_object().to_c_string())); } else { LOG(error) << "Patch has no rdfs:seeAlso" << endl; diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp index 5d27ae2e..9ba52c88 100644 --- a/src/server/Engine.cpp +++ b/src/server/Engine.cpp @@ -179,6 +179,8 @@ Engine::activate() in_properties.insert(make_pair(uris.rdf_type, uris.lv2_InputPort)); in_properties.insert(make_pair(uris.rdf_type, uris.ev_EventPort)); in_properties.insert(make_pair(uris.lv2_index, 0)); + in_properties.insert(make_pair(uris.lv2_portProperty, + uris.lv2_connectionOptional)); in_properties.insert(make_pair(uris.ingenui_canvas_x, Resource::Property(32.0f, Resource::EXTERNAL))); in_properties.insert(make_pair(uris.ingenui_canvas_y, @@ -193,6 +195,8 @@ Engine::activate() out_properties.insert(make_pair(uris.rdf_type, uris.lv2_OutputPort)); out_properties.insert(make_pair(uris.rdf_type, uris.ev_EventPort)); out_properties.insert(make_pair(uris.lv2_index, 1)); + in_properties.insert(make_pair(uris.lv2_portProperty, + uris.lv2_connectionOptional)); out_properties.insert(make_pair(uris.ingenui_canvas_x, Resource::Property(128.0f, Resource::EXTERNAL))); out_properties.insert(make_pair(uris.ingenui_canvas_y, diff --git a/src/server/Engine.hpp b/src/server/Engine.hpp index b3cf6688..d4f39bd8 100644 --- a/src/server/Engine.hpp +++ b/src/server/Engine.hpp @@ -70,11 +70,11 @@ public: virtual bool main_iteration(); - void set_driver(SharedPtr driver); + virtual void set_driver(SharedPtr driver); - void add_event_source(SharedPtr source); + virtual void add_event_source(SharedPtr source); - void process_events(ProcessContext& context); + virtual void process_events(ProcessContext& context); Ingen::Shared::World* world() const { return _world; } diff --git a/src/server/events/Get.cpp b/src/server/events/Get.cpp index 27bdef92..ae649e1f 100644 --- a/src/server/events/Get.cpp +++ b/src/server/events/Get.cpp @@ -64,15 +64,20 @@ Get::post_process() { if (_uri == "ingen:plugins") { _request->respond_ok(); - _engine.broadcaster()->send_plugins_to(_request->client(), _plugins); + if (_request->client()) { + _engine.broadcaster()->send_plugins_to(_request->client(), _plugins); + } } else if (!_object && !_plugin) { _request->respond_error("Unable to find object requested."); } else if (_request->client()) { _request->respond_ok(); - if (_object) - ObjectSender::send_object(_request->client(), _object, true); - else if (_plugin) - _request->client()->put(_uri, _plugin->properties()); + if (_request->client()) { + if (_object) { + ObjectSender::send_object(_request->client(), _object, true); + } else if (_plugin) { + _request->client()->put(_uri, _plugin->properties()); + } + } } else { _request->respond_error("Unable to find client to send object."); } diff --git a/src/server/ingen_lv2.cpp b/src/server/ingen_lv2.cpp index c8ea9fbe..02eed484 100644 --- a/src/server/ingen_lv2.cpp +++ b/src/server/ingen_lv2.cpp @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -230,8 +231,25 @@ lv2_descriptor(uint32_t index) return index < lib.patches.size() ? &lib.patches[index]->descriptor : NULL; } +class MainThread : public Raul::Thread +{ +public: + MainThread(SharedPtr engine) : _engine(engine) {} + +private: + virtual void _run() { + static const timespec main_rate = { 0, 125000000 }; // 1/8 second + while (_engine->main_iteration()) { + nanosleep(&main_rate, NULL); + } + } + + SharedPtr _engine; +}; + struct IngenPlugin { Ingen::Shared::World* world; + MainThread* main; }; static LV2_Handle @@ -264,6 +282,8 @@ ingen_instantiate(const LV2_Descriptor* descriptor, SharedPtr engine(new Server::Engine(plugin->world)); plugin->world->set_local_engine(engine); + plugin->main = new MainThread(engine); + plugin->main->set_name("Main"); SharedPtr interface( new Server::QueuedEngineInterface(*engine.get())); @@ -302,6 +322,8 @@ ingen_instantiate(const LV2_Descriptor* descriptor, engine->deactivate(); + plugin->world->load_module("osc"); + return (LV2_Handle)plugin; } @@ -326,6 +348,7 @@ ingen_activate(LV2_Handle instance) { IngenPlugin* me = (IngenPlugin*)instance; me->world->local_engine()->activate(); + me->main->start(); } static void diff --git a/src/server/wscript b/src/server/wscript index dd0dfa8f..e0c7a7d1 100644 --- a/src/server/wscript +++ b/src/server/wscript @@ -69,8 +69,6 @@ def build(bld): if bld.is_defined('HAVE_SOUP'): obj = bld(features = 'cxx cxxshlib') obj.source = ''' - EventSource.cpp - QueuedEngineInterface.cpp HTTPClientSender.cpp HTTPEngineReceiver.cpp ingen_http.cpp @@ -79,13 +77,12 @@ def build(bld): obj.name = 'libingen_http' obj.target = 'ingen_http' obj.install_path = '${LIBDIR}' + obj.use = 'libingen_server' autowaf.use_lib(bld, obj, core_libs + ' SOUP') if bld.is_defined('HAVE_LIBLO'): obj = bld(features = 'cxx cxxshlib') obj.source = ''' - EventSource.cpp - QueuedEngineInterface.cpp OSCClientSender.cpp OSCEngineReceiver.cpp ingen_osc.cpp @@ -95,6 +92,7 @@ def build(bld): obj.name = 'libingen_osc' obj.target = 'ingen_osc' obj.install_path = '${LIBDIR}' + obj.use = 'libingen_server' autowaf.use_lib(bld, obj, core_libs + ' LIBLO') if bld.is_defined('HAVE_JACK'): @@ -115,7 +113,7 @@ def build(bld): obj.includes = ['.', '..', '../..', '../../include'] obj.name = 'libingen_lv2' obj.target = 'ingen_lv2' - obj.install_path = '${LIBDIR}' - obj.use = 'libingen_shared' - obj.add_objects = 'libingen_server' + #obj.install_path = '${LIBDIR}' + obj.install_path = '${LV2DIR}/ingen.lv2/' + obj.use = 'libingen_server libingen_shared' autowaf.use_lib(bld, obj, core_libs) diff --git a/src/shared/LV2URIMap.cpp b/src/shared/LV2URIMap.cpp index 4ca5a033..a65b9644 100644 --- a/src/shared/LV2URIMap.cpp +++ b/src/shared/LV2URIMap.cpp @@ -96,6 +96,7 @@ LV2URIMap::LV2URIMap() , lv2_InputPort (NS_LV2 "InputPort") , lv2_OutputPort (NS_LV2 "OutputPort") , lv2_Plugin (NS_LV2 "Plugin") + , lv2_connectionOptional(NS_LV2 "connectionOptional") , lv2_default (NS_LV2 "default") , lv2_index (NS_LV2 "index") , lv2_integer (NS_LV2 "integer") diff --git a/src/shared/LV2URIMap.hpp b/src/shared/LV2URIMap.hpp index 75f6748e..8363d341 100644 --- a/src/shared/LV2URIMap.hpp +++ b/src/shared/LV2URIMap.hpp @@ -128,6 +128,7 @@ public: const Quark lv2_InputPort; const Quark lv2_OutputPort; const Quark lv2_Plugin; + const Quark lv2_connectionOptional; const Quark lv2_default; const Quark lv2_index; const Quark lv2_integer; diff --git a/wscript b/wscript index 16628539..bb8c8788 100644 --- a/wscript +++ b/wscript @@ -169,4 +169,8 @@ def build(bld): os.path.join(bld.env['DATADIR'], 'icons', 'hicolor', s, 'apps', 'ingen.png'), 'icons/' + s + '/ingen.png') + # Template patches/plugins bundle + bld.install_files('${LV2DIR}/ingen.lv2/', + bld.path.ant_glob('ingen.lv2/*')) + bld.add_post_fun(autowaf.run_ldconfig) -- cgit v1.2.1