summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/server/DirectDriver.hpp9
-rw-r--r--src/server/Driver.hpp31
-rw-r--r--src/server/EnginePort.hpp40
-rw-r--r--src/server/JackDriver.cpp308
-rw-r--r--src/server/JackDriver.hpp44
-rw-r--r--src/server/events/Delete.cpp10
-rw-r--r--src/server/events/Delete.hpp1
-rw-r--r--src/server/events/Disconnect.hpp1
-rw-r--r--src/server/events/Move.cpp2
-rw-r--r--src/server/ingen_lv2.cpp167
10 files changed, 262 insertions, 351 deletions
diff --git a/src/server/DirectDriver.hpp b/src/server/DirectDriver.hpp
index ccf65fee..76cd3cbc 100644
--- a/src/server/DirectDriver.hpp
+++ b/src/server/DirectDriver.hpp
@@ -42,17 +42,16 @@ public:
return NULL;
}
- virtual EnginePort* port(const Raul::Path& path) { return NULL; }
+ virtual EnginePort* get_port(const Raul::Path& path) { return NULL; }
virtual void add_port(ProcessContext& context, EnginePort* port) {}
+ virtual void remove_port(ProcessContext& context, EnginePort* port) {}
virtual void rename_port(const Raul::Path& old_path,
const Raul::Path& new_path) {}
- virtual Raul::Deletable* remove_port(ProcessContext& context,
- EnginePort* port) {
- return NULL;
- }
+ virtual void register_port(EnginePort& port) {}
+ virtual void unregister_port(EnginePort& port) {}
virtual SampleCount block_length() const { return _block_length; }
diff --git a/src/server/Driver.hpp b/src/server/Driver.hpp
index e551f636..1d6e7ef0 100644
--- a/src/server/Driver.hpp
+++ b/src/server/Driver.hpp
@@ -17,13 +17,12 @@
#ifndef INGEN_ENGINE_DRIVER_HPP
#define INGEN_ENGINE_DRIVER_HPP
-#include <string>
+#include <boost/intrusive/list.hpp>
-#include <boost/utility.hpp>
-
-#include "raul/Deletable.hpp"
+#include "raul/Noncopyable.hpp"
#include "DuplexPort.hpp"
+#include "EnginePort.hpp"
namespace Raul { class Path; }
@@ -33,15 +32,15 @@ namespace Server {
class DuplexPort;
class EnginePort;
-/** Driver abstract base class.
+/** Engine driver base class.
*
* A Driver is, from the perspective of GraphObjects (nodes, patches, ports) an
* interface for managing system ports. An implementation of Driver basically
- * needs to manage DriverPorts, and handle writing/reading data to/from them.
+ * needs to manage EnginePorts, and handle writing/reading data to/from them.
*
* \ingroup engine
*/
-class Driver : boost::noncopyable {
+class Driver : public Raul::Noncopyable {
public:
virtual ~Driver() {}
@@ -57,14 +56,24 @@ public:
virtual EnginePort* create_port(DuplexPort* patch_port) = 0;
/** Find a system port by path. */
- virtual EnginePort* port(const Raul::Path& path) = 0;
+ virtual EnginePort* get_port(const Raul::Path& path) = 0;
/** Add a system visible port (e.g. a port on the root patch). */
virtual void add_port(ProcessContext& context, EnginePort* port) = 0;
- /** Remove a system visible port. */
- virtual Raul::Deletable* remove_port(ProcessContext& context,
- EnginePort* port) = 0;
+ /** Remove a system visible port.
+ *
+ * This removes the port from the driver in the process thread but does not
+ * destroy the port. To actually remove the system port, unregister_port()
+ * must be called later in another thread.
+ */
+ virtual void remove_port(ProcessContext& context, EnginePort* port) = 0;
+
+ /** Register a system visible port. */
+ virtual void register_port(EnginePort& port) = 0;
+
+ /** Register a system visible port. */
+ virtual void unregister_port(EnginePort& port) = 0;
/** Rename a system visible port. */
virtual void rename_port(const Raul::Path& old_path,
diff --git a/src/server/EnginePort.hpp b/src/server/EnginePort.hpp
index c911c118..3bda2998 100644
--- a/src/server/EnginePort.hpp
+++ b/src/server/EnginePort.hpp
@@ -17,53 +17,43 @@
#ifndef INGEN_ENGINE_ENGINE_PORT_HPP
#define INGEN_ENGINE_ENGINE_PORT_HPP
-#include <string>
-
#include "raul/Deletable.hpp"
#include "raul/Noncopyable.hpp"
-#include "DuplexPort.hpp"
+#include <boost/intrusive/list.hpp>
-namespace Raul { class Path; }
+#include "DuplexPort.hpp"
namespace Ingen {
namespace Server {
-class DuplexPort;
-class ProcessContext;
-
-/** Representation of a "system" port (e.g. a Jack port).
- *
- * This is the class through which the rest of the engine manages everything
- * related to driver ports. Derived classes are expected to have a pointer to
- * their driver (to be able to perform the operation necessary).
+/** A "system" port (e.g. a Jack port, an external port on Ingen).
*
- * \ingroup engine
+ * @ingroup engine
*/
-class EnginePort : public Raul::Noncopyable, public Raul::Deletable {
+class EnginePort : public Raul::Noncopyable
+ , public Raul::Deletable
+ , public boost::intrusive::list_base_hook<>
+{
public:
explicit EnginePort(DuplexPort* port)
: _patch_port(port)
, _buffer(NULL)
+ , _handle(NULL)
{}
- virtual ~EnginePort() {}
+ void set_buffer(void* buf) { _buffer = buf; }
+ void set_handle(void* buf) { _handle = buf; }
- /** Create system port */
- virtual void create() {}
-
- /** Destroy system port */
- virtual void destroy() {}
-
- void* buffer() const { return _buffer; }
- void set_buffer(void* buf) { _buffer = buf; }
-
- bool is_input() const { return _patch_port->is_input(); }
+ void* buffer() const { return _buffer; }
+ void* handle() const { return _handle; }
DuplexPort* patch_port() const { return _patch_port; }
+ bool is_input() const { return _patch_port->is_input(); }
protected:
DuplexPort* _patch_port;
void* _buffer;
+ void* _handle;
};
} // namespace Server
diff --git a/src/server/JackDriver.cpp b/src/server/JackDriver.cpp
index 65566472..31f19032 100644
--- a/src/server/JackDriver.cpp
+++ b/src/server/JackDriver.cpp
@@ -30,7 +30,6 @@
#include "ingen/LV2Features.hpp"
#include "ingen/World.hpp"
#include "lv2/lv2plug.in/ns/ext/atom/util.h"
-#include "raul/List.hpp"
#include "raul/log.hpp"
#include "Buffer.hpp"
@@ -51,123 +50,6 @@ typedef jack_default_audio_sample_t jack_sample_t;
namespace Ingen {
namespace Server {
-//// JackPort ////
-
-JackPort::JackPort(JackDriver* driver, DuplexPort* patch_port)
- : EnginePort(patch_port)
- , Raul::List<JackPort*>::Node(this)
- , _driver(driver)
- , _jack_port(NULL)
-{
- patch_port->setup_buffers(*driver->_engine.buffer_factory(),
- patch_port->poly(),
- false);
- create();
-}
-
-JackPort::~JackPort()
-{
- assert(_jack_port == NULL);
-}
-
-void
-JackPort::create()
-{
- _jack_port = jack_port_register(
- _driver->jack_client(),
- _patch_port->path().substr(1).c_str(),
- (_patch_port->is_a(PortType::AUDIO))
- ? JACK_DEFAULT_AUDIO_TYPE : JACK_DEFAULT_MIDI_TYPE,
- (_patch_port->is_input())
- ? JackPortIsInput : JackPortIsOutput,
- 0);
-
- if (_jack_port == NULL) {
- LOG(Raul::error)(Raul::fmt("Failed to register port %1%\n")
- % _patch_port->path().c_str());
- throw JackDriver::PortRegistrationFailedException();
- }
-}
-
-void
-JackPort::destroy()
-{
- assert(_jack_port);
- if (jack_port_unregister(_driver->jack_client(), _jack_port))
- LOG(Raul::error)("Unable to unregister port\n");
- _jack_port = NULL;
-}
-
-void
-JackPort::pre_process(ProcessContext& context)
-{
- const SampleCount nframes = context.nframes();
- _buffer = jack_port_get_buffer(_jack_port, nframes);
-
- if (!is_input()) {
- _patch_port->buffer(0)->clear();
- return;
- }
-
- if (_patch_port->is_a(PortType::AUDIO)) {
- Buffer* patch_buf = _patch_port->buffer(0).get();
- memcpy(patch_buf->samples(), _buffer, nframes * sizeof(float));
-
- } else if (_patch_port->buffer_type() == _patch_port->bufs().uris().atom_Sequence) {
- Buffer* patch_buf = (Buffer*)_patch_port->buffer(0).get();
-
- const jack_nframes_t event_count = jack_midi_get_event_count(_buffer);
-
- patch_buf->prepare_write(context);
-
- // Copy events from Jack port buffer into patch port buffer
- for (jack_nframes_t i = 0; i < event_count; ++i) {
- jack_midi_event_t ev;
- jack_midi_event_get(&ev, _buffer, i);
-
- if (!patch_buf->append_event(
- ev.time, ev.size, _driver->_midi_event_type, ev.buffer)) {
- LOG(Raul::warn)("Failed to write to MIDI buffer, events lost!\n");
- }
- }
- }
-}
-
-void
-JackPort::post_process(ProcessContext& context)
-{
- const SampleCount nframes = context.nframes();
- if (is_input()) {
- return;
- }
-
- if (!_buffer) {
- // First cycle for a new output, so pre_process wasn't called
- _buffer = jack_port_get_buffer(_jack_port, nframes);
- }
-
- _patch_port->post_process(context);
- if (_patch_port->is_a(PortType::AUDIO)) {
- Buffer* patch_buf = _patch_port->buffer(0).get();
- memcpy(_buffer, patch_buf->samples(), nframes * sizeof(Sample));
-
- } else if (_patch_port->buffer_type() == _patch_port->bufs().uris().atom_Sequence) {
- Buffer* patch_buf = _patch_port->buffer(0).get();
-
- jack_midi_clear_buffer(_buffer);
-
- LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)patch_buf->atom();
- LV2_ATOM_SEQUENCE_FOREACH(seq, ev) {
- const uint8_t* buf = (const uint8_t*)LV2_ATOM_BODY(&ev->body);
- if (ev->body.type == _patch_port->bufs().uris().midi_MidiEvent) {
- jack_midi_event_write(_buffer, ev->time.frames, buf, ev->body.size);
- }
- }
- }
-}
-
-//// JackDriver ////
-
JackDriver::JackDriver(Engine& engine)
: _engine(engine)
, _sem(0)
@@ -243,8 +125,9 @@ JackDriver::attach(const std::string& server_name,
jack_set_session_callback(_client, session_cb, this);
#endif
- for (Raul::List<JackPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i)
- (*i)->create();
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ register_port(*i);
+ }
return true;
}
@@ -283,8 +166,9 @@ JackDriver::deactivate()
_is_activated = false;
_sem.wait();
- for (Raul::List<JackPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i)
- (*i)->destroy();
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ unregister_port(*i);
+ }
if (_client) {
jack_deactivate(_client);
@@ -298,74 +182,156 @@ JackDriver::deactivate()
}
}
-/** Add a Jack port.
- *
- * Realtime safe, this is to be called at the beginning of a process cycle to
- * insert (and actually begin using) a new port.
- *
- * See create_port() and remove_port().
- */
+EnginePort*
+JackDriver::get_port(const Raul::Path& path)
+{
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ if (i->patch_port()->path() == path) {
+ return &*i;
+ }
+ }
+
+ return NULL;
+}
+
void
JackDriver::add_port(ProcessContext& context, EnginePort* port)
{
- assert(dynamic_cast<JackPort*>(port));
- _ports.push_back((JackPort*)port);
+ _ports.push_back(*port);
}
-/** Remove a Jack port.
- *
- * Realtime safe. This is to be called at the beginning of a process cycle to
- * remove the port from the lists read by the audio thread, so the port
- * will no longer be used and can be removed afterwards.
- *
- * It is the callers responsibility to delete the returned port.
- */
-Raul::Deletable*
-JackDriver::remove_port(ProcessContext& context,
- EnginePort* port)
+void
+JackDriver::remove_port(ProcessContext& context, EnginePort* port)
{
- for (Raul::List<JackPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) {
- if (*i == port) {
- return _ports.erase(i);
- }
+ _ports.erase(_ports.iterator_to(*port));
+}
+
+void
+JackDriver::register_port(EnginePort& port)
+{
+ jack_port_t* jack_port = jack_port_register(
+ _client,
+ port.patch_port()->path().substr(1).c_str(),
+ (port.patch_port()->is_a(PortType::AUDIO)
+ ? JACK_DEFAULT_AUDIO_TYPE : JACK_DEFAULT_MIDI_TYPE),
+ (port.patch_port()->is_input()
+ ? JackPortIsInput : JackPortIsOutput),
+ 0);
+
+ if (!jack_port) {
+ throw JackDriver::PortRegistrationFailedException();
}
- return NULL;
+ port.set_handle(jack_port);
+}
+
+void
+JackDriver::unregister_port(EnginePort& port)
+{
+ if (jack_port_unregister(_client, (jack_port_t*)port.handle())) {
+ LOG(Raul::error)("Failed to unregister Jack port\n");
+ }
}
void
JackDriver::rename_port(const Raul::Path& old_path,
const Raul::Path& new_path)
{
- JackPort* jport = dynamic_cast<JackPort*>(port(old_path));
- if (jport) {
- jack_port_set_name(jport->jack_port(), new_path.substr(1).c_str());
+ EnginePort* eport = get_port(old_path);
+ if (eport) {
+ jack_port_set_name((jack_port_t*)eport->handle(),
+ new_path.substr(1).c_str());
}
}
EnginePort*
-JackDriver::port(const Raul::Path& path)
+JackDriver::create_port(DuplexPort* patch_port)
{
- for (Raul::List<JackPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i)
- if ((*i)->patch_port()->path() == path)
- return (*i);
+ if (patch_port &&
+ (patch_port->is_a(PortType::AUDIO) ||
+ (patch_port->is_a(PortType::ATOM) &&
+ patch_port->buffer_type() == _engine.world()->uris().atom_Sequence))) {
+ EnginePort* eport = new EnginePort(patch_port);
+ register_port(*eport);
+ patch_port->setup_buffers(*_engine.buffer_factory(),
+ patch_port->poly(),
+ false);
+ return eport;
+ } else {
+ return NULL;
+ }
+}
- return NULL;
+void
+JackDriver::pre_process_port(ProcessContext& context, EnginePort* port)
+{
+ const SampleCount nframes = context.nframes();
+ jack_port_t* jack_port = (jack_port_t*)port->handle();
+ PortImpl* patch_port = port->patch_port();
+ void* buffer = jack_port_get_buffer(jack_port, nframes);
+
+ port->set_buffer(buffer);
+
+ if (!patch_port->is_input()) {
+ patch_port->buffer(0)->clear();
+ return;
+ }
+
+ if (patch_port->is_a(PortType::AUDIO)) {
+ Buffer* patch_buf = patch_port->buffer(0).get();
+ memcpy(patch_buf->samples(), buffer, nframes * sizeof(float));
+
+ } else if (patch_port->buffer_type() == patch_port->bufs().uris().atom_Sequence) {
+ Buffer* patch_buf = (Buffer*)patch_port->buffer(0).get();
+
+ const jack_nframes_t event_count = jack_midi_get_event_count(buffer);
+
+ patch_buf->prepare_write(context);
+
+ // Copy events from Jack port buffer into patch port buffer
+ for (jack_nframes_t i = 0; i < event_count; ++i) {
+ jack_midi_event_t ev;
+ jack_midi_event_get(&ev, buffer, i);
+
+ if (!patch_buf->append_event(
+ ev.time, ev.size, _midi_event_type, ev.buffer)) {
+ LOG(Raul::warn)("Failed to write to MIDI buffer, events lost!\n");
+ }
+ }
+ }
}
-EnginePort*
-JackDriver::create_port(DuplexPort* patch_port)
+void
+JackDriver::post_process_port(ProcessContext& context, EnginePort* port)
{
- try {
- if (patch_port->is_a(PortType::AUDIO)
- || (patch_port->is_a(PortType::ATOM) &&
- patch_port->buffer_type() == patch_port->bufs().uris().atom_Sequence)) {
- return new JackPort(this, patch_port);
- } else {
- return NULL;
+ const SampleCount nframes = context.nframes();
+ jack_port_t* jack_port = (jack_port_t*)port->handle();
+ PortImpl* patch_port = port->patch_port();
+ void* buffer = port->buffer();
+
+ if (patch_port->is_input()) {
+ return;
+ }
+
+ if (!buffer) {
+ // First cycle for a new output, so pre_process wasn't called
+ buffer = jack_port_get_buffer(jack_port, nframes);
+ port->set_buffer(buffer);
+ }
+
+ patch_port->post_process(context);
+ Buffer* const patch_buf = patch_port->buffer(0).get();
+ if (patch_port->is_a(PortType::AUDIO)) {
+ memcpy(buffer, patch_buf->samples(), nframes * sizeof(Sample));
+ } else if (patch_port->buffer_type() == patch_port->bufs().uris().atom_Sequence) {
+ jack_midi_clear_buffer(buffer);
+ LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)patch_buf->atom();
+ LV2_ATOM_SEQUENCE_FOREACH(seq, ev) {
+ const uint8_t* buf = (const uint8_t*)LV2_ATOM_BODY(&ev->body);
+ if (ev->body.type == patch_port->bufs().uris().midi_MidiEvent) {
+ jack_midi_event_write(buffer, ev->time.frames, buf, ev->body.size);
+ }
}
- } catch (...) {
- return NULL;
}
}
@@ -394,14 +360,16 @@ JackDriver::_process_cb(jack_nframes_t nframes)
_engine.process_context().locate(start_of_current_cycle, nframes);
// Read input
- for (Raul::List<JackPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i)
- (*i)->pre_process(_engine.process_context());
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ pre_process_port(_engine.process_context(), &*i);
+ }
_engine.run(nframes);
// Write output
- for (Raul::List<JackPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i)
- (*i)->post_process(_engine.process_context());
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ post_process_port(_engine.process_context(), &*i);
+ }
return 0;
}
diff --git a/src/server/JackDriver.hpp b/src/server/JackDriver.hpp
index 5724afa7..93f24ece 100644
--- a/src/server/JackDriver.hpp
+++ b/src/server/JackDriver.hpp
@@ -29,7 +29,6 @@
#endif
#include "raul/AtomicInt.hpp"
-#include "raul/List.hpp"
#include "raul/Semaphore.hpp"
#include "raul/Thread.hpp"
@@ -47,29 +46,6 @@ class PortImpl;
class DuplexPort;
class JackDriver;
-/** Used internally by JackDriver to represent a Jack port.
- *
- * A Jack port always has a one-to-one association with a Patch port.
- */
-class JackPort : public EnginePort, public Raul::List<JackPort*>::Node
-{
-public:
- JackPort(JackDriver* driver, DuplexPort* patch_port);
- ~JackPort();
-
- void create();
- void destroy();
-
- void pre_process(ProcessContext& context);
- void post_process(ProcessContext& context);
-
- jack_port_t* jack_port() const { return _jack_port; }
-
-private:
- JackDriver* _driver;
- jack_port_t* _jack_port;
-};
-
/** The Jack Driver.
*
* The process callback here drives the entire audio thread by "pulling"
@@ -93,16 +69,14 @@ public:
void enable();
void disable();
- EnginePort* port(const Raul::Path& path);
EnginePort* create_port(DuplexPort* patch_port);
+ EnginePort* get_port(const Raul::Path& path);
+ void rename_port(const Raul::Path& old_path, const Raul::Path& new_path);
void add_port(ProcessContext& context, EnginePort* port);
-
- void rename_port(const Raul::Path& old_path,
- const Raul::Path& new_path);
-
- Raul::Deletable* remove_port(ProcessContext& context,
- EnginePort* port);
+ void remove_port(ProcessContext& context, EnginePort* port);
+ void register_port(EnginePort& port);
+ void unregister_port(EnginePort& port);
/** Transport state for this frame.
* Intended to only be called from the audio thread. */
@@ -141,6 +115,9 @@ private:
}
#endif
+ void pre_process_port(ProcessContext& context, EnginePort* port);
+ void post_process_port(ProcessContext& context, EnginePort* port);
+
// Non static callbacks (methods)
void _thread_init_cb();
void _shutdown_cb();
@@ -150,7 +127,11 @@ private:
void _session_cb(jack_session_event_t* event);
#endif
+protected:
+ typedef boost::intrusive::list<EnginePort> Ports;
+
Engine& _engine;
+ Ports _ports;
std::list< SharedPtr<Raul::Thread> > _jack_threads;
Raul::Semaphore _sem;
Raul::AtomicInt _flag;
@@ -161,7 +142,6 @@ private:
bool _is_activated;
jack_position_t _position;
jack_transport_state_t _transport_state;
- Raul::List<JackPort*> _ports;
};
} // namespace Server
diff --git a/src/server/events/Delete.cpp b/src/server/events/Delete.cpp
index 97f1161f..84b29a6f 100644
--- a/src/server/events/Delete.cpp
+++ b/src/server/events/Delete.cpp
@@ -41,7 +41,6 @@ Delete::Delete(Engine& engine,
const Raul::URI& uri)
: Event(engine, client, id, time)
, _uri(uri)
- , _garbage(NULL)
, _engine_port(NULL)
, _patch_node_listnode(NULL)
, _patch_port_listnode(NULL)
@@ -111,7 +110,7 @@ Delete::pre_process()
}
if (!_port->parent_patch()->parent()) {
- _engine_port = _engine.driver()->port(_port->path());
+ _engine_port = _engine.driver()->get_port(_port->path());
}
}
@@ -145,7 +144,7 @@ Delete::execute(ProcessContext& context)
_port->parent_patch()->external_ports(_ports_array);
if (_engine_port) {
- _garbage = _engine.driver()->remove_port(context, _engine_port);
+ _engine.driver()->remove_port(context, _engine_port);
}
}
@@ -177,10 +176,9 @@ Delete::post_process()
}
if (_engine_port) {
- _engine_port->destroy();
+ _engine.driver()->unregister_port(*_engine_port);
+ delete _engine_port;
}
-
- delete _garbage;
}
} // namespace Events
diff --git a/src/server/events/Delete.hpp b/src/server/events/Delete.hpp
index 53671846..a493fcf7 100644
--- a/src/server/events/Delete.hpp
+++ b/src/server/events/Delete.hpp
@@ -73,7 +73,6 @@ private:
Raul::Path _path;
SharedPtr<NodeImpl> _node; ///< Non-NULL iff a node
SharedPtr<PortImpl> _port; ///< Non-NULL iff a port
- Raul::Deletable* _garbage;
EnginePort* _engine_port;
PatchImpl::Nodes::Node* _patch_node_listnode;
Raul::List<PortImpl*>::Node* _patch_port_listnode;
diff --git a/src/server/events/Disconnect.hpp b/src/server/events/Disconnect.hpp
index bcd8f1bc..b008025a 100644
--- a/src/server/events/Disconnect.hpp
+++ b/src/server/events/Disconnect.hpp
@@ -24,7 +24,6 @@
#include "BufferFactory.hpp"
namespace Raul {
-template <typename T> class ListNode;
template <typename T> class Array;
}
diff --git a/src/server/events/Move.cpp b/src/server/events/Move.cpp
index 4d72e9ba..5fa58825 100644
--- a/src/server/events/Move.cpp
+++ b/src/server/events/Move.cpp
@@ -65,7 +65,7 @@ Move::pre_process()
return Event::pre_process_done(EXISTS, _new_path);
}
- EnginePort* eport = _engine.driver()->port(_old_path);
+ EnginePort* eport = _engine.driver()->get_port(_old_path);
if (eport) {
_engine.driver()->rename_port(_old_path, _new_path);
}
diff --git a/src/server/ingen_lv2.cpp b/src/server/ingen_lv2.cpp
index a28eb5fc..af0983fb 100644
--- a/src/server/ingen_lv2.cpp
+++ b/src/server/ingen_lv2.cpp
@@ -81,36 +81,52 @@ namespace Server {
class LV2Driver;
-void enqueue_message(
- ProcessContext& context, LV2Driver* driver, const LV2_Atom* msg);
-
void signal_main(ProcessContext& context, LV2Driver* driver);
-class LV2Port : public EnginePort
+class LV2Driver : public Ingen::Server::Driver
+ , public Ingen::AtomSink
{
public:
- LV2Port(LV2Driver* driver, DuplexPort* patch_port)
- : EnginePort(patch_port)
- , _driver(driver)
+ LV2Driver(Engine& engine, SampleCount block_length, SampleCount sample_rate)
+ : _engine(engine)
+ , _main_sem(0)
+ , _reader(engine.world()->uri_map(),
+ engine.world()->uris(),
+ engine.world()->forge(),
+ *engine.world()->interface().get())
+ , _writer(engine.world()->uri_map(),
+ engine.world()->uris(),
+ *this)
+ , _from_ui(block_length * sizeof(float)) // FIXME: size
+ , _to_ui(block_length * sizeof(float)) // FIXME: size
+ , _root_patch(NULL)
+ , _block_length(block_length)
+ , _sample_rate(sample_rate)
+ , _frame_time(0)
+ , _to_ui_overflow_sem(0)
+ , _to_ui_overflow(false)
{}
- void pre_process(ProcessContext& context) {
- if (!is_input() || !_buffer) {
+ void pre_process_port(ProcessContext& context, EnginePort* port) {
+ PortImpl* patch_port = port->patch_port();
+ void* buffer = port->buffer();
+
+ if (!patch_port->is_input() || !buffer) {
return;
}
- Buffer* const patch_buf = _patch_port->buffer(0).get();
- if (_patch_port->is_a(PortType::AUDIO) ||
- _patch_port->is_a(PortType::CV)) {
+ Buffer* const patch_buf = patch_port->buffer(0).get();
+ if (patch_port->is_a(PortType::AUDIO) ||
+ patch_port->is_a(PortType::CV)) {
memcpy(patch_buf->samples(),
- _buffer,
+ buffer,
context.nframes() * sizeof(float));
- } else if (_patch_port->is_a(PortType::CONTROL)) {
- patch_buf->samples()[0] = ((float*)_buffer)[0];
+ } else if (patch_port->is_a(PortType::CONTROL)) {
+ patch_buf->samples()[0] = ((float*)buffer)[0];
} else {
- LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)_buffer;
+ LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)buffer;
bool enqueued = false;
- URIs& uris = _patch_port->bufs().uris();
+ URIs& uris = patch_port->bufs().uris();
patch_buf->prepare_write(context);
LV2_ATOM_SEQUENCE_FOREACH(seq, ev) {
if (!patch_buf->append_event(
@@ -120,73 +136,46 @@ public:
}
if (AtomReader::is_message(uris, &ev->body)) {
- enqueue_message(context, _driver, &ev->body);
+ enqueue_message(&ev->body);
enqueued = true;
}
}
if (enqueued) {
- signal_main(context, _driver);
+ _main_sem.post();
}
}
}
- void post_process(ProcessContext& context) {
- if (is_input() || !_buffer) {
+ void post_process_port(ProcessContext& context, EnginePort* port) {
+ PortImpl* patch_port = port->patch_port();
+ void* buffer = port->buffer();
+
+ if (patch_port->is_input() || !buffer) {
return;
}
- Buffer* patch_buf = _patch_port->buffer(0).get();
- if (_patch_port->is_a(PortType::AUDIO) ||
- _patch_port->is_a(PortType::CV)) {
- memcpy(_buffer,
+ Buffer* patch_buf = patch_port->buffer(0).get();
+ if (patch_port->is_a(PortType::AUDIO) ||
+ patch_port->is_a(PortType::CV)) {
+ memcpy(buffer,
patch_buf->samples(),
context.nframes() * sizeof(float));
- } else if (_patch_port->is_a(PortType::CONTROL)) {
- ((float*)_buffer)[0] = patch_buf->samples()[0];
+ } else if (patch_port->is_a(PortType::CONTROL)) {
+ ((float*)buffer)[0] = patch_buf->samples()[0];
} else {
- memcpy(_buffer,
+ memcpy(buffer,
patch_buf->atom(),
sizeof(LV2_Atom) + patch_buf->atom()->size);
}
}
-private:
- LV2Driver* _driver;
-};
-
-class LV2Driver : public Ingen::Server::Driver
- , public Ingen::AtomSink
-{
-private:
- typedef std::vector<LV2Port*> Ports;
-
-public:
- LV2Driver(Engine& engine, SampleCount block_length, SampleCount sample_rate)
- : _engine(engine)
- , _main_sem(0)
- , _reader(engine.world()->uri_map(),
- engine.world()->uris(),
- engine.world()->forge(),
- *engine.world()->interface().get())
- , _writer(engine.world()->uri_map(),
- engine.world()->uris(),
- *this)
- , _from_ui(block_length * sizeof(float)) // FIXME: size
- , _to_ui(block_length * sizeof(float)) // FIXME: size
- , _root_patch(NULL)
- , _block_length(block_length)
- , _sample_rate(sample_rate)
- , _frame_time(0)
- , _to_ui_overflow_sem(0)
- , _to_ui_overflow(false)
- {}
-
void run(uint32_t nframes) {
_engine.process_context().locate(_frame_time, nframes);
- for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i)
- (*i)->pre_process(_engine.process_context());
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ pre_process_port(_engine.process_context(), *i);
+ }
_engine.run(nframes);
if (_engine.post_processor()->pending()) {
@@ -195,8 +184,9 @@ public:
flush_to_ui();
- for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i)
- (*i)->post_process(_engine.process_context());
+ for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ post_process_port(_engine.process_context(), *i);
+ }
_frame_time += nframes;
}
@@ -209,45 +199,34 @@ public:
virtual void set_root_patch(PatchImpl* patch) { _root_patch = patch; }
virtual PatchImpl* root_patch() { return _root_patch; }
- virtual EnginePort* engine_port(ProcessContext& context,
- const Raul::Path& path) {
+ virtual EnginePort* get_port(const Raul::Path& path) {
for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
if ((*i)->patch_port()->path() == path) {
- return (*i);
+ return *i;
}
}
return NULL;
}
- EnginePort* port(const Raul::Path& path) { return NULL; }
+ /** Unused since LV2 has no dynamic ports. */
+ virtual void add_port(ProcessContext& context, EnginePort* port) {}
- /** Doesn't have to be real-time safe since LV2 has no dynamic ports. */
- virtual void add_port(ProcessContext& context, EnginePort* port) {
- assert(dynamic_cast<LV2Port*>(port));
- assert(port->patch_port()->index() == _ports.size());
- _ports.push_back((LV2Port*)port);
- }
+ /** Unused since LV2 has no dynamic ports. */
+ virtual void remove_port(ProcessContext& context, EnginePort* port) {}
- /** Doesn't have to be real-time safe since LV2 has no dynamic ports. */
- virtual Raul::Deletable* remove_port(ProcessContext& context,
- EnginePort* port) {
- for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) {
- if (*i == port) {
- _ports.erase(i);
- return NULL;
- }
- }
+ /** Unused since LV2 has no dynamic ports. */
+ virtual void register_port(EnginePort& port) {}
- return NULL;
- }
+ /** Unused since LV2 has no dynamic ports. */
+ virtual void unregister_port(EnginePort& port) {}
- /** UNused since LV2 has no dynamic ports. */
+ /** Unused since LV2 has no dynamic ports. */
virtual void rename_port(const Raul::Path& old_path,
const Raul::Path& new_path) {}
virtual EnginePort* create_port(DuplexPort* patch_port) {
- return new LV2Port(this, patch_port);
+ return new EnginePort(patch_port);
}
/** Called in run thread for events received at control input port. */
@@ -354,10 +333,13 @@ public:
AtomReader& reader() { return _reader; }
AtomWriter& writer() { return _writer; }
+ typedef std::vector<EnginePort*> Ports;
+
Ports& ports() { return _ports; }
private:
Engine& _engine;
+ Ports _ports;
Raul::Semaphore _main_sem;
AtomReader _reader;
AtomWriter _writer;
@@ -367,23 +349,10 @@ private:
SampleCount _block_length;
SampleCount _sample_rate;
SampleCount _frame_time;
- Ports _ports;
Raul::Semaphore _to_ui_overflow_sem;
bool _to_ui_overflow;
};
-void
-enqueue_message(ProcessContext& context, LV2Driver* driver, const LV2_Atom* msg)
-{
- driver->enqueue_message(msg);
-}
-
-void
-signal_main(ProcessContext& context, LV2Driver* driver)
-{
- driver->main_sem().post();
-}
-
} // namespace Server
} // namespace Ingen