From d154ae5b114a6a04acd17a83f6d59caa9ec1005a Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 12 Oct 2008 06:47:11 +0000 Subject: Split OSC/HTTP/JACK dependencies from ingen into separate libraries so engine library doesn't have a link time dependence on liblo/soap/libjack. Preliminary Ingen LV2 code wrapper (not functional yet). git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@1653 a436a847-0d15-0410-975c-d299462d15a1 --- src/client/OSCEngineSender.hpp | 5 +- src/client/client.cpp | 12 +- src/client/wscript | 2 +- src/engine/AudioDriver.hpp | 4 +- src/engine/Engine.cpp | 96 ++++----------- src/engine/Engine.hpp | 13 +-- src/engine/HTTPEngineReceiver.cpp | 13 ++- src/engine/HTTPEngineReceiver.hpp | 6 + src/engine/JackAudioDriver.cpp | 13 +++ src/engine/JackAudioDriver.hpp | 8 ++ src/engine/OSCEngineReceiver.cpp | 11 ++ src/engine/OSCEngineReceiver.hpp | 6 + src/engine/QueuedEngineInterface.cpp | 11 ++ src/engine/QueuedEngineInterface.hpp | 5 + src/engine/events/SendPortValueEvent.hpp | 4 +- src/engine/ingen.lv2/ingen_lv2.cpp | 193 +++++++++++++++++++++++++++++++ src/engine/ingen_engine.cpp | 8 +- src/engine/wscript | 41 +++++-- src/gui/ConnectWindow.cpp | 27 ++++- src/gui/ConnectWindow.hpp | 1 + src/ingen/main.cpp | 62 ++++++++-- src/ingen/wscript | 2 +- 22 files changed, 426 insertions(+), 117 deletions(-) create mode 100644 src/engine/ingen.lv2/ingen_lv2.cpp diff --git a/src/client/OSCEngineSender.hpp b/src/client/OSCEngineSender.hpp index ef4a2fa3..ea156c34 100644 --- a/src/client/OSCEngineSender.hpp +++ b/src/client/OSCEngineSender.hpp @@ -41,9 +41,12 @@ namespace Client { class OSCEngineSender : public EngineInterface, public Shared::OSCSender { public: OSCEngineSender(const string& engine_url); - ~OSCEngineSender(); + static OSCEngineSender* create(const std::string& engine_url) { + return new OSCEngineSender(engine_url); + } + std::string uri() const { return _engine_url; } inline int32_t next_id() diff --git a/src/client/client.cpp b/src/client/client.cpp index 8e51fb23..88ff07aa 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -6,7 +6,7 @@ * Foundation; either version 2 of the License, or (at your option) any later * version. * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * Ingen is distributed in the hope that it will be useful, but HAVEOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. * @@ -19,10 +19,10 @@ #include #include "client.hpp" -#ifdef WITH_LIBLO +#ifdef HAVE_LIBLO #include "OSCEngineSender.hpp" #endif -#ifdef WITH_SOUP +#ifdef HAVE_SOUP #include "HTTPEngineSender.hpp" #endif @@ -37,15 +37,15 @@ new_remote_interface(const std::string& url) { const string scheme = url.substr(0, url.find(":")); -#ifdef WITH_LIBLO +#ifdef HAVE_LIBLO if (scheme == "osc.udp" || scheme == "osc.tcp") { - OSCEngineSender* oes = new OSCEngineSender(url); + OSCEngineSender* oes = OSCEngineSender::create(url); oes->attach(rand(), true); return SharedPtr(oes); } #endif -#ifdef WITH_SOUP +#ifdef HAVE_SOUP if (scheme == "http") { HTTPEngineSender* hes = new HTTPEngineSender(url); hes->attach(rand(), true); diff --git a/src/client/wscript b/src/client/wscript index b351e3c2..65597d0f 100644 --- a/src/client/wscript +++ b/src/client/wscript @@ -32,5 +32,5 @@ def build(bld): obj.name = 'libingen_client' obj.target = 'ingen_client' obj.inst_dir = 'lib/ingen' - autowaf.use_lib(bld, obj, 'GLIBMM LV2CORE SLV2 RAUL REDLANDMM SOUP XML2 SIGCPP') + autowaf.use_lib(bld, obj, 'GLIBMM LV2CORE SLV2 RAUL REDLANDMM SOUP XML2 SIGCPP LIBLO SOUP') diff --git a/src/engine/AudioDriver.hpp b/src/engine/AudioDriver.hpp index 6b5ea8dc..1a611846 100644 --- a/src/engine/AudioDriver.hpp +++ b/src/engine/AudioDriver.hpp @@ -42,9 +42,9 @@ public: AudioDriver() : Driver(DataType::AUDIO) {} virtual void set_root_patch(PatchImpl* patch) = 0; - virtual PatchImpl* root_patch() = 0; + virtual PatchImpl* root_patch() = 0; - virtual void add_port(DriverPort* port) = 0; + virtual void add_port(DriverPort* port) = 0; virtual DriverPort* remove_port(const Raul::Path& path) = 0; virtual SampleCount buffer_size() const = 0; diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index a7681156..bcc5a54c 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -28,7 +28,6 @@ #include "Event.hpp" #include "common/interface/EventType.hpp" #include "shared/Store.hpp" -#include "JackAudioDriver.hpp" #include "NodeFactory.hpp" #include "ClientBroadcaster.hpp" #include "PatchImpl.hpp" @@ -39,21 +38,12 @@ #include "PostProcessor.hpp" #include "events/CreatePatchEvent.hpp" #include "events/EnablePatchEvent.hpp" -#ifdef HAVE_LIBLO -#include "OSCEngineReceiver.hpp" -#endif -#ifdef HAVE_SOUP -#include "HTTPEngineReceiver.hpp" -#endif #include "PostProcessor.hpp" +#include "AudioDriver.hpp" #include "ProcessSlave.hpp" #include "ProcessContext.hpp" #include "MessageContext.hpp" #include "ThreadManager.hpp" -#include "QueuedEngineInterface.hpp" -#ifdef HAVE_JACK_MIDI -#include "JackMidiDriver.hpp" -#endif using namespace std; namespace Ingen { @@ -125,6 +115,17 @@ Engine::driver(DataType type, EventType event_type) } +void +Engine::set_driver(DataType type, SharedPtr driver) +{ + if (type == DataType::AUDIO) { + _audio_driver = PtrCast(driver); + } else { + cerr << "WARNING: Unable to set driver for type " << type.uri() << endl; + } +} + + int Engine::main() { @@ -164,67 +165,20 @@ Engine::main_iteration() void -Engine::start_jack_driver() -{ - if ( ! _audio_driver) - _audio_driver = SharedPtr(new JackAudioDriver(*this)); - else - cerr << "[Engine::start_jack_driver] Audio driver already running" << endl; -} - - -void -Engine::start_osc_driver(int port) +Engine::set_event_source(SharedPtr source) { -#ifdef HAVE_LIBLO - if (_event_source) { - cerr << "WARNING: Replacing event source" << endl; - _event_source.reset(); - } - - _event_source = SharedPtr(new OSCEngineReceiver( - *this, pre_processor_queue_size, port)); -#endif -} + if (_event_source) + cerr << "Warning: Dropped event source (engine interface)" << endl; - -void -Engine::start_http_driver(int port) -{ -#ifdef HAVE_SOUP - // FIXE: leak - HTTPEngineReceiver* server = new HTTPEngineReceiver(*this, port); - server->activate(); -#endif + _event_source = source; } - - -SharedPtr -Engine::new_queued_interface() -{ - if (_event_source) { - cerr << "WARNING: Replacing event source" << endl; - _event_source.reset(); - } - - SharedPtr result(new QueuedEngineInterface( - *this, Ingen::event_queue_size, Ingen::event_queue_size)); - - _event_source = result; - return result; -} -/* void -Engine::set_event_source(SharedPtr source) +Engine::set_midi_driver(MidiDriver* driver) { - if (_event_source) - cerr << "Warning: Dropped event source (engine interface)" << endl; - - _event_source = source; + _midi_driver = driver; } -*/ bool @@ -234,15 +188,12 @@ Engine::activate(size_t parallelism) return false; assert(_audio_driver); - assert(_event_source); -#ifdef HAVE_JACK_MIDI - _midi_driver = new JackMidiDriver(((JackAudioDriver*)_audio_driver.get())->jack_client()); -#else - _midi_driver = new DummyMidiDriver(); -#endif + if (!_midi_driver) + _midi_driver = new DummyMidiDriver(); - _event_source->activate(); + if (_event_source) + _event_source->activate(); // Create root patch @@ -278,7 +229,8 @@ Engine::deactivate() if (!_activated) return; - _event_source->deactivate(); + if (_event_source) + _event_source->deactivate(); /*for (Tree::iterator i = _engine_store->objects().begin(); i != _engine_store->objects().end(); ++i) diff --git a/src/engine/Engine.hpp b/src/engine/Engine.hpp index 9c824c9a..e2e5ea09 100644 --- a/src/engine/Engine.hpp +++ b/src/engine/Engine.hpp @@ -43,7 +43,6 @@ class EventSource; class PostProcessor; class Event; class QueuedEvent; -class QueuedEngineInterface; class Driver; class ProcessSlave; class ProcessContext; @@ -74,12 +73,6 @@ public: * Note that it will take some time. */ virtual void quit() { _quit_flag = true; } - virtual void start_jack_driver(); - virtual void start_osc_driver(int port); - virtual void start_http_driver(int port); - - virtual SharedPtr new_queued_interface(); - virtual bool activate(size_t parallelism); virtual void deactivate(); @@ -102,6 +95,12 @@ public: /** Return the active driver for the given type */ Driver* driver(DataType type, EventType event_type); + /** Set the driver for the given data type (replacing the old) */ + virtual void set_driver(DataType type, SharedPtr driver); + + virtual void set_event_source(SharedPtr source); + virtual void set_midi_driver(MidiDriver* driver); + Ingen::Shared::World* world() { return _world; } typedef std::vector ProcessSlaves; diff --git a/src/engine/HTTPEngineReceiver.cpp b/src/engine/HTTPEngineReceiver.cpp index 58b2bbe8..d7d246db 100644 --- a/src/engine/HTTPEngineReceiver.cpp +++ b/src/engine/HTTPEngineReceiver.cpp @@ -202,5 +202,16 @@ HTTPEngineReceiver::ReceiveThread::_run() soup_server_run(_receiver._server); } - } // namespace Ingen + + +extern "C" { + +Ingen::HTTPEngineReceiver* +new_http_receiver(Ingen::Engine& engine, uint16_t port) +{ + return new Ingen::HTTPEngineReceiver(engine, port); +} + +} // extern "C" + diff --git a/src/engine/HTTPEngineReceiver.hpp b/src/engine/HTTPEngineReceiver.hpp index f156d855..8d474bf5 100644 --- a/src/engine/HTTPEngineReceiver.hpp +++ b/src/engine/HTTPEngineReceiver.hpp @@ -56,4 +56,10 @@ private: } // namespace Ingen +extern "C" { + /// Module interface + extern Ingen::HTTPEngineReceiver* new_http_receiver( + Ingen::Engine& engine, uint16_t port); +} + #endif // HTTPENGINERECEIVER_H diff --git a/src/engine/JackAudioDriver.cpp b/src/engine/JackAudioDriver.cpp index fe5fa0b7..15c8f785 100644 --- a/src/engine/JackAudioDriver.cpp +++ b/src/engine/JackAudioDriver.cpp @@ -36,6 +36,7 @@ #include "EventSource.hpp" #include "AudioBuffer.hpp" #include "ProcessSlave.hpp" +#include "JackMidiDriver.hpp" using namespace std; @@ -173,6 +174,9 @@ JackAudioDriver::activate() _engine.lash_driver()->set_jack_client_name(jack_client_get_name(_client)); #endif*/ } + + if (!_engine.midi_driver()) + _engine.set_midi_driver(new JackMidiDriver(_client)); } @@ -382,3 +386,12 @@ JackAudioDriver::_buffer_size_cb(jack_nframes_t nframes) } // namespace Ingen +Ingen::JackAudioDriver* +new_jack_audio_driver( + Ingen::Engine& engine, + std::string server_name, + jack_client_t* jack_client) +{ + return new Ingen::JackAudioDriver(engine, server_name, jack_client); +} + diff --git a/src/engine/JackAudioDriver.hpp b/src/engine/JackAudioDriver.hpp index 3beb775a..8cf2e5d3 100644 --- a/src/engine/JackAudioDriver.hpp +++ b/src/engine/JackAudioDriver.hpp @@ -182,4 +182,12 @@ inline int JackAudioDriver::sample_rate_cb(jack_nframes_t nframes, void* jack_dr } // namespace Ingen +extern "C" { + /// Module interface + extern Ingen::JackAudioDriver* new_jack_audio_driver( + Ingen::Engine& engine, + std::string server_name = "", + jack_client_t* jack_client = 0); +} + #endif // JACKAUDIODRIVER_H diff --git a/src/engine/OSCEngineReceiver.cpp b/src/engine/OSCEngineReceiver.cpp index 87f4abd2..d9c8f7c2 100644 --- a/src/engine/OSCEngineReceiver.cpp +++ b/src/engine/OSCEngineReceiver.cpp @@ -882,3 +882,14 @@ OSCEngineReceiver::unknown_cb(const char* path, const char* types, lo_arg** argv } // namespace Ingen + + +extern "C" { + +Ingen::OSCEngineReceiver* +new_osc_receiver(Ingen::Engine& engine, size_t queue_size, uint16_t port) +{ + return new Ingen::OSCEngineReceiver(engine, queue_size, port); +} + +} // extern "C" diff --git a/src/engine/OSCEngineReceiver.hpp b/src/engine/OSCEngineReceiver.hpp index 361bd4bb..05eb0322 100644 --- a/src/engine/OSCEngineReceiver.hpp +++ b/src/engine/OSCEngineReceiver.hpp @@ -126,4 +126,10 @@ private: } // namespace Ingen +extern "C" { + /// Module interface + extern Ingen::OSCEngineReceiver* new_osc_receiver( + Ingen::Engine& engine, size_t queue_size, uint16_t port); +} + #endif // OSCENGINERECEIVER_H diff --git a/src/engine/QueuedEngineInterface.cpp b/src/engine/QueuedEngineInterface.cpp index 356a6980..4e0e82d1 100644 --- a/src/engine/QueuedEngineInterface.cpp +++ b/src/engine/QueuedEngineInterface.cpp @@ -18,6 +18,7 @@ #include #include "QueuedEngineInterface.hpp" #include "config.h" +#include "tuning.hpp" #include "QueuedEventSource.hpp" #include "events.hpp" #include "Engine.hpp" @@ -368,3 +369,13 @@ QueuedEngineInterface::request_all_objects() } // namespace Ingen +extern "C" { + +Ingen::QueuedEngineInterface* +new_queued_interface(Ingen::Engine& engine) +{ + return new Ingen::QueuedEngineInterface(engine, Ingen::event_queue_size, Ingen::event_queue_size); +} + +} // extern "C" + diff --git a/src/engine/QueuedEngineInterface.hpp b/src/engine/QueuedEngineInterface.hpp index 89810434..5665c2c7 100644 --- a/src/engine/QueuedEngineInterface.hpp +++ b/src/engine/QueuedEngineInterface.hpp @@ -22,6 +22,7 @@ #include #include #include +#include "tuning.hpp" #include "interface/EngineInterface.hpp" #include "interface/ClientInterface.hpp" #include "Responder.hpp" @@ -156,5 +157,9 @@ private: } // namespace Ingen +extern "C" { + extern Ingen::QueuedEngineInterface* new_queued_interface(Ingen::Engine& engine); +} + #endif // QUEUEDENGINEINTERFACE_H diff --git a/src/engine/events/SendPortValueEvent.hpp b/src/engine/events/SendPortValueEvent.hpp index e8505914..ad9ae5a1 100644 --- a/src/engine/events/SendPortValueEvent.hpp +++ b/src/engine/events/SendPortValueEvent.hpp @@ -19,8 +19,8 @@ #define SENDPORTVALUEEVENT_H #include -#include "Event.hpp" -#include "types.hpp" +#include "engine/Event.hpp" +#include "engine/types.hpp" using std::string; namespace Ingen { 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 + * + * 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 +#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 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(new Engine(plugin->world)); + plugin->world->local_engine = plugin->engine; + + // FIXME: fixed buffer size + plugin->engine->set_driver(DataType::AUDIO, + SharedPtr(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" + diff --git a/src/engine/ingen_engine.cpp b/src/engine/ingen_engine.cpp index 3c393a7f..137499ee 100644 --- a/src/engine/ingen_engine.cpp +++ b/src/engine/ingen_engine.cpp @@ -17,10 +17,10 @@ #include "config.h" +#include #include #include "ingen_engine.hpp" #include "Engine.hpp" -#include "QueuedEngineInterface.hpp" #include "tuning.hpp" #include "util.hpp" @@ -39,18 +39,16 @@ launch_osc_engine(int port) { char port_str[6]; snprintf(port_str, 6, "%u", port); - const string cmd = string("ingen -e --engine-port=").append(port_str); + const std::string cmd = std::string("ingen -e --engine-port=").append(port_str); if (Raul::Process::launch(cmd)) { return true; - //return SharedPtr(new OSCEngineSender( - // string("osc.udp://localhost:").append(port_str))); } else { std::cerr << "Failed to launch engine process." << std::endl; - //return SharedPtr(); return false; } } + } // namespace Ingen diff --git a/src/engine/wscript b/src/engine/wscript index 1f2ec1f3..ad5c3a96 100644 --- a/src/engine/wscript +++ b/src/engine/wscript @@ -18,8 +18,6 @@ def build(bld): GraphObjectImpl.cpp InputPort.cpp InternalPlugin.cpp - JackAudioDriver.cpp - JackMidiDriver.cpp LADSPAPlugin.cpp LV2Info.cpp LV2Plugin.cpp @@ -36,7 +34,6 @@ def build(bld): PortImpl.cpp PostProcessor.cpp ProcessSlave.cpp - QueuedEngineInterface.cpp QueuedEvent.cpp QueuedEventSource.cpp TransportNode.cpp @@ -75,13 +72,41 @@ def build(bld): obj.source += ' LADSPANode.cpp ' if bld.env()['HAVE_SLV2']: obj.source += ' LV2Node.cpp ' - if bld.env()['HAVE_SOUP']: - obj.source += ' HTTPEngineReceiver.cpp ' - if bld.env()['HAVE_LIBLO']: - obj.source += ' OSCEngineReceiver.cpp OSCClientSender.cpp ' obj.includes = ['.', '..', '../common', './events'] obj.name = 'libingen_engine' obj.target = 'ingen_engine' obj.inst_dir = 'lib/ingen' - autowaf.use_lib(bld, obj, 'GLIBMM GTHREAD LV2CORE SLV2 JACK LIBLO RAUL REDLANDMM SOUP') + core_libs = 'GLIBMM GTHREAD LV2CORE SLV2 RAUL REDLANDMM' + autowaf.use_lib(bld, obj, core_libs) + + if bld.env()['HAVE_SOUP'] or bld.env()['HAVE_LIBLO']: + obj.source += ' QueuedEngineInterface.cpp ' + + if bld.env()['HAVE_SOUP']: + obj = bld.create_obj('cpp', 'shlib') + obj.source = 'HTTPEngineReceiver.cpp' + obj.includes = ['.', '..', '../common', './events', '../engine'] + obj.name = 'libingen_engine_http' + obj.target = 'ingen_engine_http' + obj.inst_dir = 'lib/ingen' + autowaf.use_lib(bld, obj, core_libs + ' SOUP') + + if bld.env()['HAVE_LIBLO']: + obj = bld.create_obj('cpp', 'shlib') + obj.source = 'OSCClientSender.cpp OSCEngineReceiver.cpp' + obj.includes = ['.', '..', '../common', './events', '../engine'] + obj.name = 'libingen_engine_osc' + obj.target = 'ingen_engine_osc' + obj.inst_dir = 'lib/ingen' + autowaf.use_lib(bld, obj, core_libs + ' LIBLO') + + if bld.env()['HAVE_JACK']: + obj = bld.create_obj('cpp', 'shlib') + obj.source = 'JackAudioDriver.cpp JackMidiDriver.cpp' + obj.includes = ['.', '..', '../common', './events', '../engine'] + obj.name = 'libingen_engine_jack' + obj.target = 'ingen_engine_jack' + obj.inst_dir = 'lib/ingen' + autowaf.use_lib(bld, obj, core_libs + ' JACK') + diff --git a/src/gui/ConnectWindow.cpp b/src/gui/ConnectWindow.cpp index bf4d790b..906a16dc 100644 --- a/src/gui/ConnectWindow.cpp +++ b/src/gui/ConnectWindow.cpp @@ -28,6 +28,7 @@ #include "engine/tuning.hpp" #include "engine/Engine.hpp" #include "engine/QueuedEngineInterface.hpp" +#include "engine/Driver.hpp" #ifdef HAVE_SOUP #include "client/HTTPClientReceiver.hpp" #endif @@ -217,12 +218,30 @@ ConnectWindow::connect(bool existing) world->local_engine = SharedPtr(_new_engine(world)); } - if ( ! world->engine) - world->engine = world->local_engine->new_queued_interface(); + if ( ! world->engine) { + SharedPtr interface( + new QueuedEngineInterface(*world->local_engine, + Ingen::event_queue_size, Ingen::event_queue_size)); + world->engine = interface; + world->local_engine->set_event_source(interface); + } SharedPtr client(new SigClientInterface()); - world->local_engine->start_jack_driver(); + Ingen::Driver* (*new_driver)( + Ingen::Engine& engine, + std::string server_name, + jack_client_t* jack_client) = NULL; + + if (!world->local_engine->audio_driver()) { + bool found = _engine_jack_module->get_symbol( + "new_jack_audio_driver", (void*&)(new_driver)); + if (found) { + world->local_engine->set_driver(DataType::AUDIO, + SharedPtr(new_driver(*world->local_engine, "default", 0))); + } + } + world->local_engine->activate(1); // FIXME: parallelism App::instance().attach(client); @@ -302,6 +321,8 @@ ConnectWindow::load_widgets() cerr << "Unable to find module entry point, internal engine unavailable." << endl; _engine_module.reset(); } + + _engine_jack_module = Ingen::Shared::load_module("ingen_engine_jack"); server_toggled(); } diff --git a/src/gui/ConnectWindow.hpp b/src/gui/ConnectWindow.hpp index 73cc8c68..1635dbde 100644 --- a/src/gui/ConnectWindow.hpp +++ b/src/gui/ConnectWindow.hpp @@ -83,6 +83,7 @@ private: int _connect_stage; SharedPtr _engine_module; + SharedPtr _engine_jack_module; Ingen::Engine* (*_new_engine)(Ingen::Shared::World* world); Gtk::Image* _icon; diff --git a/src/ingen/main.cpp b/src/ingen/main.cpp index 9632894c..4c958606 100644 --- a/src/ingen/main.cpp +++ b/src/ingen/main.cpp @@ -31,11 +31,20 @@ #include "module/global.hpp" #include "module/Module.hpp" #include "module/World.hpp" +#include "engine/tuning.hpp" #include "engine/Engine.hpp" #include "engine/QueuedEngineInterface.hpp" +#include "engine/JackAudioDriver.hpp" #include "serialisation/Parser.hpp" #include "cmdline.h" +#ifdef HAVE_LIBLO +#include "engine/OSCEngineReceiver.hpp" +#endif +#ifdef HAVE_SOUP +#include "engine/HTTPEngineReceiver.hpp" +#endif + #ifdef WITH_BINDINGS #include "bindings/ingen_bindings.hpp" #endif @@ -78,6 +87,10 @@ main(int argc, char** argv) } SharedPtr engine_module; + SharedPtr engine_http_module; + SharedPtr engine_osc_module; + SharedPtr engine_queued_module; + SharedPtr engine_jack_module; SharedPtr client_module; SharedPtr gui_module; SharedPtr bindings_module; @@ -105,18 +118,47 @@ main(int argc, char** argv) /* Run engine */ if (args.engine_flag) { engine_module = Ingen::Shared::load_module("ingen_engine"); + engine_http_module = Ingen::Shared::load_module("ingen_engine_http"); + engine_osc_module = Ingen::Shared::load_module("ingen_engine_osc"); + engine_queued_module = Ingen::Shared::load_module("ingen_engine_queued"); + engine_jack_module = Ingen::Shared::load_module("ingen_engine_jack"); if (engine_module) { Engine* (*new_engine)(Ingen::Shared::World* world) = NULL; if (engine_module->get_symbol("new_engine", (void*&)new_engine)) { engine = SharedPtr(new_engine(world)); world->local_engine = engine; /* Load queued (direct in-process) engine interface */ - if (args.gui_given) { - engine_interface = engine->new_queued_interface(); - world->engine = engine_interface; + if (args.gui_given && engine_queued_module) { + Ingen::QueuedEngineInterface* (*new_interface)(Ingen::Engine& engine); + if (engine_osc_module->get_symbol("new_queued_interface", (void*&)new_interface)) { + SharedPtr interface(new_interface(*engine)); + world->local_engine->set_event_source(interface); + engine_interface = interface; + world->engine = engine_interface; + } } else { - engine->start_osc_driver(args.engine_port_arg); - engine->start_http_driver(args.engine_port_arg); + #ifdef HAVE_LIBLO + if (engine_osc_module) { + Ingen::OSCEngineReceiver* (*new_receiver)( + Ingen::Engine& engine, size_t queue_size, uint16_t port); + if (engine_osc_module->get_symbol("new_osc_receiver", (void*&)new_receiver)) { + SharedPtr source(new_receiver(*engine, + pre_processor_queue_size, args.engine_port_arg)); + world->local_engine->set_event_source(source); + } + } + #endif + #ifdef HAVE_SOUP + if (engine_http_module) { + // FIXE: leak + Ingen::HTTPEngineReceiver* (*new_receiver)(Ingen::Engine& engine, uint16_t port); + if (engine_http_module->get_symbol("new_http_receiver", (void*&)new_receiver)) { + HTTPEngineReceiver* receiver = new_receiver( + *world->local_engine, args.engine_port_arg); + receiver->activate(); + } + } + #endif } } else { engine_module.reset(); @@ -148,7 +190,13 @@ main(int argc, char** argv) /* Activate the engine, if we have one */ if (engine) { - engine->start_jack_driver(); + Ingen::JackAudioDriver* (*new_driver)( + Ingen::Engine& engine, + std::string server_name, + jack_client_t* jack_client) = NULL; + if (engine_jack_module->get_symbol("new_jack_audio_driver", (void*&)new_driver)) + engine->set_driver(DataType::AUDIO, SharedPtr(new_driver(*engine, "default", 0))); + engine->activate(args.parallelism_arg); } @@ -221,8 +269,6 @@ main(int argc, char** argv) bool found = bindings_module->get_symbol("run", (void*&)(run_script)); if (found) { - cerr << "WORLD: " << world << endl; - cerr << "ENGINE: " << world->engine << endl; setenv("PYTHONPATH", "../../bindings", 1); run_script(world, args.run_arg); } else { diff --git a/src/ingen/wscript b/src/ingen/wscript index 6c791008..0912c74a 100644 --- a/src/ingen/wscript +++ b/src/ingen/wscript @@ -8,5 +8,5 @@ def build(bld): obj.includes = ['../common', '../'] obj.defines = 'VERSION=\\\"' + bld.env()['INGEN_VERSION'] + '\\\"' obj.uselib_local = 'libingen_module libingen_shared' - autowaf.use_lib(bld, obj, 'GTHREAD GLIBMM REDLANDMM RAUL LV2CORE SLV2 INGEN LIBLO') + autowaf.use_lib(bld, obj, 'GTHREAD GLIBMM REDLANDMM RAUL LV2CORE SLV2 INGEN LIBLO SOUP') -- cgit v1.2.1