summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-05-09 03:58:59 +0000
committerDavid Robillard <d@drobilla.net>2012-05-09 03:58:59 +0000
commitba2e3fac36f4db4ec4c27775f1a2246c111ce403 (patch)
treefc21cb90726b555f2c7fe3be796cd51cdd3fd88a /src
parentc0e6f7ecbf77ef59e7e4948dd96109417a4994d5 (diff)
downloadingen-ba2e3fac36f4db4ec4c27775f1a2246c111ce403.tar.gz
ingen-ba2e3fac36f4db4ec4c27775f1a2246c111ce403.tar.bz2
ingen-ba2e3fac36f4db4ec4c27775f1a2246c111ce403.zip
Factor audio thread execution stuff out of JackDriver into Engine::run().
Towards an Ingen library interface usable on user-provided buffers. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4326 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/server/Context.hpp5
-rw-r--r--src/server/Driver.hpp5
-rw-r--r--src/server/Engine.cpp61
-rw-r--r--src/server/Engine.hpp9
-rw-r--r--src/server/InputPort.cpp1
-rw-r--r--src/server/JackDriver.cpp71
-rw-r--r--src/server/JackDriver.hpp8
-rw-r--r--src/server/LV2Node.cpp1
-rw-r--r--src/server/MessageContext.cpp10
-rw-r--r--src/server/MessageContext.hpp10
-rw-r--r--src/server/Notification.cpp1
-rw-r--r--src/server/PostProcessor.cpp15
-rw-r--r--src/server/ProcessContext.cpp4
-rw-r--r--src/server/ProcessContext.hpp2
-rw-r--r--src/server/ProcessSlave.cpp2
-rw-r--r--src/server/ProcessSlave.hpp7
-rw-r--r--src/server/events/CreatePatch.cpp15
-rw-r--r--src/server/events/SetMetadata.cpp2
-rw-r--r--src/server/internals/Controller.cpp1
19 files changed, 105 insertions, 125 deletions
diff --git a/src/server/Context.hpp b/src/server/Context.hpp
index 23547059..fa2a2c7e 100644
--- a/src/server/Context.hpp
+++ b/src/server/Context.hpp
@@ -21,7 +21,6 @@
#include "ingen/shared/World.hpp"
-#include "Engine.hpp"
#include "types.hpp"
namespace Ingen {
@@ -49,10 +48,10 @@ public:
MESSAGE
};
- Context(Engine& engine, ID id)
+ Context(Engine& engine, size_t event_sink_size, ID id)
: _engine(engine)
, _id(id)
- , _event_sink(engine.event_queue_size())
+ , _event_sink(event_sink_size)
, _start(0)
, _end(0)
, _nframes(0)
diff --git a/src/server/Driver.hpp b/src/server/Driver.hpp
index bd2202ad..cce1be7e 100644
--- a/src/server/Driver.hpp
+++ b/src/server/Driver.hpp
@@ -96,9 +96,6 @@ public:
virtual Raul::Deletable* remove_port(const Raul::Path& path,
DriverPort** port=NULL) = 0;
- virtual void set_root_patch(PatchImpl* patch) = 0;
- virtual PatchImpl* root_patch() = 0;
-
/** Return the audio buffer size in frames */
virtual SampleCount block_length() const = 0;
@@ -109,8 +106,6 @@ public:
virtual SampleCount frame_time() const = 0;
virtual bool is_realtime() const = 0;
-
- virtual ProcessContext& context() = 0;
};
} // namespace Server
diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp
index c2cc7cab..f2f088f5 100644
--- a/src/server/Engine.cpp
+++ b/src/server/Engine.cpp
@@ -21,7 +21,6 @@
#include "raul/Deletable.hpp"
#include "raul/Maid.hpp"
#include "raul/SharedPtr.hpp"
-#include "events/CreatePatch.hpp"
#include "events/CreatePort.hpp"
#include "ingen/shared/World.hpp"
#include "ingen/shared/LV2Features.hpp"
@@ -63,6 +62,7 @@ Engine::Engine(Ingen::Shared::World* a_world)
, _pre_processor(new PreProcessor())
, _post_processor(new PostProcessor(*this))
, _event_writer(new EventWriter(*this))
+ , _process_context(*this)
, _quit_flag(false)
{
if (a_world->store()) {
@@ -101,7 +101,7 @@ Engine::~Engine()
SharedPtr<EngineStore>
Engine::engine_store() const
{
- return PtrCast<EngineStore>(_world->store());
+ return PtrCast<EngineStore>(_world->store());
}
size_t
@@ -153,18 +153,19 @@ Engine::activate()
Ingen::Forge& forge = world()->forge();
// Create root patch
- PatchImpl* root_patch = _driver->root_patch();
- if (!root_patch) {
- root_patch = new PatchImpl(*this, "root", 1, NULL, _driver->sample_rate(), 1);
- root_patch->set_property(uris.rdf_type,
- Resource::Property(uris.ingen_Patch, Resource::INTERNAL));
- root_patch->set_property(uris.ingen_polyphony,
- Resource::Property(_world->forge().make(int32_t(1)),
- Resource::INTERNAL));
- root_patch->activate(*_buffer_factory);
- _world->store()->add(root_patch);
- root_patch->compiled_patch(root_patch->compile());
- _driver->set_root_patch(root_patch);
+ if (!_root_patch) {
+ _root_patch = new PatchImpl(
+ *this, "root", 1, NULL, _driver->sample_rate(), 1);
+ _root_patch->set_property(
+ uris.rdf_type,
+ Resource::Property(uris.ingen_Patch, Resource::INTERNAL));
+ _root_patch->set_property(
+ uris.ingen_polyphony,
+ Resource::Property(_world->forge().make(int32_t(1)),
+ Resource::INTERNAL));
+ _root_patch->activate(*_buffer_factory);
+ _world->store()->add(_root_patch);
+ _root_patch->compiled_patch(_root_patch->compile());
ProcessContext context(*this);
@@ -212,7 +213,7 @@ Engine::activate()
}
_driver->activate();
- root_patch->enable();
+ _root_patch->enable();
ThreadManager::single_threaded = false;
@@ -223,11 +224,39 @@ void
Engine::deactivate()
{
_driver->deactivate();
- _driver->root_patch()->deactivate();
+ _root_patch->deactivate();
ThreadManager::single_threaded = true;
}
+void
+Engine::run(uint32_t sample_count)
+{
+ // Apply control bindings to input
+ control_bindings()->pre_process(
+ _process_context, _root_patch->port_impl(0)->buffer(0).get());
+
+ post_processor()->set_end_time(_process_context.end());
+
+ // Process events that came in during the last cycle
+ // (Aiming for jitter-free 1 block event latency, ideally)
+ process_events(_process_context);
+
+ // Run root patch
+ if (_root_patch) {
+ _root_patch->process(_process_context);
+ }
+
+ // Emit control binding feedback
+ control_bindings()->post_process(
+ _process_context, _root_patch->port_impl(1)->buffer(0).get());
+
+ // Signal message context to run if necessary
+ if (message_context()->has_requests()) {
+ message_context()->signal(_process_context);
+ }
+}
+
bool
Engine::pending_events()
{
diff --git a/src/server/Engine.hpp b/src/server/Engine.hpp
index 042264e4..5111f52c 100644
--- a/src/server/Engine.hpp
+++ b/src/server/Engine.hpp
@@ -23,6 +23,8 @@
#include "ingen/Interface.hpp"
#include "raul/SharedPtr.hpp"
+#include "ProcessContext.hpp"
+
namespace Raul { class Maid; }
namespace Ingen {
@@ -43,6 +45,7 @@ class NodeFactory;
class PostProcessor;
class PreProcessor;
class ProcessContext;
+class PatchImpl;
/**
The engine which executes the process graph.
@@ -63,6 +66,7 @@ public:
// EngineBase methods
virtual bool activate();
virtual void deactivate();
+ virtual void run(uint32_t sample_count);
virtual void quit();
virtual bool main_iteration();
virtual void register_client(const Raul::URI& uri, Interface* client);
@@ -85,6 +89,8 @@ public:
MessageContext* message_context() const { return _message_context; }
NodeFactory* node_factory() const { return _node_factory; }
PostProcessor* post_processor() const { return _post_processor; }
+ PatchImpl* root_patch() const { return _root_patch; }
+ ProcessContext& process_context() { return _process_context; }
SharedPtr<EngineStore> engine_store() const;
@@ -104,6 +110,9 @@ private:
PostProcessor* _post_processor;
EventWriter* _event_writer;
+ PatchImpl* _root_patch;
+ ProcessContext _process_context;
+
bool _quit_flag;
};
diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp
index fa76c9b0..a6b377c7 100644
--- a/src/server/InputPort.cpp
+++ b/src/server/InputPort.cpp
@@ -22,6 +22,7 @@
#include "AudioBuffer.hpp"
#include "BufferFactory.hpp"
#include "ConnectionImpl.hpp"
+#include "Engine.hpp"
#include "InputPort.hpp"
#include "NodeImpl.hpp"
#include "Notification.hpp"
diff --git a/src/server/JackDriver.cpp b/src/server/JackDriver.cpp
index cccaadf1..46b80a40 100644
--- a/src/server/JackDriver.cpp
+++ b/src/server/JackDriver.cpp
@@ -184,8 +184,6 @@ JackDriver::JackDriver(Engine& engine)
, _block_length(0)
, _sample_rate(0)
, _is_activated(false)
- , _process_context(engine)
- , _root_patch(NULL)
{
_midi_event_type = _engine.world()->uris()->midi_MidiEvent;
}
@@ -277,8 +275,9 @@ JackDriver::activate()
_is_activated = true;
- _process_context.activate(world->conf()->option("parallelism").get_int(),
- is_realtime());
+ _engine.process_context().activate(
+ world->conf()->option("parallelism").get_int(),
+ is_realtime());
if (jack_activate(_client)) {
LOG(error) << "Could not activate Jack client, aborting" << endl;
@@ -400,68 +399,29 @@ int
JackDriver::_process_cb(jack_nframes_t nframes)
{
if (nframes == 0 || ! _is_activated) {
- if (_flag == 1)
+ if (_flag == 1) {
_sem.post();
+ }
return 0;
}
- // FIXME: all of this time stuff is screwy
-
- // FIXME: support nframes != buffer_size, even though that never damn well happens
- //assert(nframes == _block_length);
-
- // Note that Jack can not call this function for a cycle, if overloaded
+ /* Note that Jack can not call this function for a cycle, if overloaded,
+ so a rolling counter here would not always be correct. */
const jack_nframes_t start_of_current_cycle = jack_last_frame_time(_client);
_transport_state = jack_transport_query(_client, &_position);
- _process_context.locate(start_of_current_cycle, nframes, 0);
-
- for (ProcessContext::Slaves::iterator i = _process_context.slaves().begin();
- i != _process_context.slaves().end(); ++i) {
- (*i)->context().locate(start_of_current_cycle, nframes, 0);
- }
+ _engine.process_context().locate(start_of_current_cycle, nframes, 0);
// Read input
for (Raul::List<JackPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i)
- (*i)->pre_process(_process_context);
-
- // Apply control bindings to input
- _engine.control_bindings()->pre_process(
- _process_context, _root_patch->port_impl(0)->buffer(0).get());
-
- _engine.post_processor()->set_end_time(_process_context.end());
-
- // Process events that came in during the last cycle
- // (Aiming for jitter-free 1 block event latency, ideally)
- _engine.process_events(_process_context);
-
- // Run root patch
- if (_root_patch) {
- _root_patch->process(_process_context);
-#if 0
- static const SampleCount control_block_size = nframes / 2;
- for (jack_nframes_t i = 0; i < nframes; i += control_block_size) {
- const SampleCount block_size = (i + control_block_size < nframes)
- ? control_block_size
- : nframes - i;
- _process_context.locate(start_of_current_cycle + i, block_size, i);
- _root_patch->process(_process_context);
- }
-#endif
- }
-
- // Emit control binding feedback
- _engine.control_bindings()->post_process(
- _process_context, _root_patch->port_impl(1)->buffer(0).get());
+ (*i)->pre_process(_engine.process_context());
- // Signal message context to run if necessary
- if (_engine.message_context()->has_requests())
- _engine.message_context()->signal(_process_context);
+ _engine.run(nframes);
// Write output
for (Raul::List<JackPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i)
- (*i)->post_process(_process_context);
+ (*i)->post_process(_engine.process_context());
return 0;
}
@@ -499,10 +459,11 @@ JackDriver::_sample_rate_cb(jack_nframes_t nframes)
int
JackDriver::_block_length_cb(jack_nframes_t nframes)
{
- if (_root_patch) {
+ if (_engine.root_patch()) {
_block_length = nframes;
- _root_patch->set_buffer_size(context(), *_engine.buffer_factory(), PortType::AUDIO,
- _engine.buffer_factory()->audio_buffer_size(nframes));
+ _engine.root_patch()->set_buffer_size(
+ _engine.process_context(), *_engine.buffer_factory(), PortType::AUDIO,
+ _engine.buffer_factory()->audio_buffer_size(nframes));
}
return 0;
}
@@ -519,7 +480,7 @@ JackDriver::_session_cb(jack_session_event_t* event)
SharedPtr<Serialisation::Serialiser> serialiser = _engine.world()->serialiser();
if (serialiser) {
- SharedPtr<Patch> root(_engine.driver()->root_patch(), NullDeleter<Patch>);
+ SharedPtr<Patch> root(_engine.root_patch(), NullDeleter<Patch>);
serialiser->write_bundle(root, string("file://") + event->session_dir);
}
diff --git a/src/server/JackDriver.hpp b/src/server/JackDriver.hpp
index 1e6202f9..24a2dab8 100644
--- a/src/server/JackDriver.hpp
+++ b/src/server/JackDriver.hpp
@@ -35,7 +35,6 @@
#include "Buffer.hpp"
#include "Driver.hpp"
-#include "ProcessContext.hpp"
namespace Raul { class Path; }
@@ -104,11 +103,6 @@ public:
Raul::Deletable* remove_port(const Raul::Path& path, DriverPort** port=NULL);
- PatchImpl* root_patch() { return _root_patch; }
- void set_root_patch(PatchImpl* patch) { _root_patch = patch; }
-
- ProcessContext& context() { return _process_context; }
-
/** Transport state for this frame.
* Intended to only be called from the audio thread. */
inline const jack_position_t* position() { return &_position; }
@@ -171,8 +165,6 @@ private:
jack_position_t _position;
jack_transport_state_t _transport_state;
Raul::List<JackPort*> _ports;
- ProcessContext _process_context;
- PatchImpl* _root_patch;
};
} // namespace Server
diff --git a/src/server/LV2Node.cpp b/src/server/LV2Node.cpp
index bdbb858c..dfba7177 100644
--- a/src/server/LV2Node.cpp
+++ b/src/server/LV2Node.cpp
@@ -31,6 +31,7 @@
#include "ingen/shared/URIs.hpp"
#include "AudioBuffer.hpp"
+#include "Engine.hpp"
#include "InputPort.hpp"
#include "LV2Node.hpp"
#include "LV2Plugin.hpp"
diff --git a/src/server/MessageContext.cpp b/src/server/MessageContext.cpp
index 1d42576c..ed2c8543 100644
--- a/src/server/MessageContext.cpp
+++ b/src/server/MessageContext.cpp
@@ -32,6 +32,16 @@ using namespace Raul;
namespace Ingen {
namespace Server {
+MessageContext::MessageContext(Engine& engine)
+ : Context(engine, engine.event_queue_size(), MESSAGE)
+ , Raul::Thread("MessageContext")
+ , _sem(0)
+ , _requests(engine.event_queue_size())
+ , _end_time(0)
+{
+ Thread::set_context(THREAD_MESSAGE);
+}
+
void
MessageContext::run(NodeImpl* node, FrameTime time)
{
diff --git a/src/server/MessageContext.hpp b/src/server/MessageContext.hpp
index 604810bd..0bc8ecf5 100644
--- a/src/server/MessageContext.hpp
+++ b/src/server/MessageContext.hpp
@@ -43,15 +43,7 @@ class NodeImpl;
class MessageContext : public Context, public Raul::Thread
{
public:
- explicit MessageContext(Engine& engine)
- : Context(engine, MESSAGE)
- , Raul::Thread("MessageContext")
- , _sem(0)
- , _requests(engine.event_queue_size())
- , _end_time(0)
- {
- Thread::set_context(THREAD_MESSAGE);
- }
+ explicit MessageContext(Engine& engine);
/** Schedule a message context run at a certain time.
* Safe to call from either process thread or pre-process thread.
diff --git a/src/server/Notification.cpp b/src/server/Notification.cpp
index 7cbea267..3d7efe23 100644
--- a/src/server/Notification.cpp
+++ b/src/server/Notification.cpp
@@ -18,6 +18,7 @@
#include "ingen/shared/URIs.hpp"
#include "ClientBroadcaster.hpp"
+#include "Engine.hpp"
#include "Notification.hpp"
#include "PortImpl.hpp"
diff --git a/src/server/PostProcessor.cpp b/src/server/PostProcessor.cpp
index 3a8ee612..2ad23254 100644
--- a/src/server/PostProcessor.cpp
+++ b/src/server/PostProcessor.cpp
@@ -72,15 +72,12 @@ PostProcessor::process()
/* FIXME: process events from all threads if parallel */
/* Process audio thread generated events */
- Driver* driver = _engine.driver();
- if (driver) {
- Raul::RingBuffer& event_sink = driver->context().event_sink();
- const uint32_t read_space = event_sink.read_space();
- Notification note;
- for (uint32_t i = 0; i < read_space; i += sizeof(note)) {
- if (event_sink.read(sizeof(note), &note) == sizeof(note)) {
- Notification::post_process(note, _engine);
- }
+ Raul::RingBuffer& event_sink = _engine.process_context().event_sink();
+ const uint32_t read_space = event_sink.read_space();
+ Notification note;
+ for (uint32_t i = 0; i < read_space; i += sizeof(note)) {
+ if (event_sink.read(sizeof(note), &note) == sizeof(note)) {
+ Notification::post_process(note, _engine);
}
}
diff --git a/src/server/ProcessContext.cpp b/src/server/ProcessContext.cpp
index c13d53eb..78f6d50e 100644
--- a/src/server/ProcessContext.cpp
+++ b/src/server/ProcessContext.cpp
@@ -20,6 +20,10 @@
namespace Ingen {
namespace Server {
+ProcessContext::ProcessContext(Engine& engine)
+ : Context(engine, engine.event_queue_size(), AUDIO)
+{}
+
void
ProcessContext::activate(uint32_t parallelism, bool sched_rt)
{
diff --git a/src/server/ProcessContext.hpp b/src/server/ProcessContext.hpp
index 43b6f8b9..1af480be 100644
--- a/src/server/ProcessContext.hpp
+++ b/src/server/ProcessContext.hpp
@@ -33,7 +33,7 @@ class ProcessSlave;
class ProcessContext : public Context
{
public:
- explicit ProcessContext(Engine& engine) : Context(engine, AUDIO) {}
+ explicit ProcessContext(Engine& engine);
typedef std::vector<ProcessSlave*> Slaves;
diff --git a/src/server/ProcessSlave.cpp b/src/server/ProcessSlave.cpp
index 8d74224a..6960b5e4 100644
--- a/src/server/ProcessSlave.cpp
+++ b/src/server/ProcessSlave.cpp
@@ -46,7 +46,7 @@ ProcessSlave::_whipped()
n.node()->wait_for_input(n.n_providers());
- n.node()->process(*_context);
+ n.node()->process(_engine.process_context());
/* Signal dependants their input is ready */
for (size_t i=0; i < n.dependants().size(); ++i)
diff --git a/src/server/ProcessSlave.hpp b/src/server/ProcessSlave.hpp
index 99ff116f..4bafb1c7 100644
--- a/src/server/ProcessSlave.hpp
+++ b/src/server/ProcessSlave.hpp
@@ -42,7 +42,6 @@ public:
, _index(0)
, _state(STATE_FINISHED)
, _compiled_patch(NULL)
- , _context(NULL)
{
std::stringstream ss;
ss << "Process Slave ";
@@ -69,7 +68,6 @@ public:
_index = start_index;
_state = STATE_RUNNING;
_compiled_patch = compiled_patch;
- _context = &context;
Raul::Slave::whip();
}
@@ -79,9 +77,7 @@ public:
_state.compare_and_exchange(STATE_RUNNING, STATE_FINISH_SIGNALLED);
}
- inline uint32_t id() const { return _id; }
- inline const ProcessContext& context() const { return _engine.driver()->context(); }
- inline ProcessContext& context() { return _engine.driver()->context(); }
+ inline uint32_t id() const { return _id; }
private:
void _whipped();
@@ -97,7 +93,6 @@ private:
uint32_t _index;
Raul::AtomicInt _state;
CompiledPatch* _compiled_patch;
- ProcessContext* _context;
};
} // namespace Server
diff --git a/src/server/events/CreatePatch.cpp b/src/server/events/CreatePatch.cpp
index 5463cb99..794ff7d6 100644
--- a/src/server/events/CreatePatch.cpp
+++ b/src/server/events/CreatePatch.cpp
@@ -99,7 +99,6 @@ CreatePatch::pre_process()
_patch->activate(*_engine.buffer_factory());
// Insert into EngineStore
- //_patch->add_to_store(_engine.engine_store());
_engine.engine_store()->add(_patch);
Event::pre_process();
@@ -111,16 +110,10 @@ CreatePatch::execute(ProcessContext& context)
Event::execute(context);
if (_patch) {
- if (!_parent) {
- assert(_path.is_root());
- assert(_patch->parent_patch() == NULL);
- _engine.driver()->set_root_patch(_patch);
- } else {
- assert(_parent);
- assert(!_path.is_root());
- _engine.maid()->push(_parent->compiled_patch());
- _parent->compiled_patch(_compiled_patch);
- }
+ assert(_parent);
+ assert(!_path.is_root());
+ _engine.maid()->push(_parent->compiled_patch());
+ _parent->compiled_patch(_compiled_patch);
}
}
diff --git a/src/server/events/SetMetadata.cpp b/src/server/events/SetMetadata.cpp
index 7d88c83c..68cdbbbd 100644
--- a/src/server/events/SetMetadata.cpp
+++ b/src/server/events/SetMetadata.cpp
@@ -319,7 +319,7 @@ SetMetadata::execute(ProcessContext& context)
break;
case POLYPHONY:
if (_patch->internal_poly() != static_cast<uint32_t>(value.get_int32()) &&
- !_patch->apply_internal_poly(_engine.driver()->context(),
+ !_patch->apply_internal_poly(_engine.process_context(),
*_engine.buffer_factory(),
*_engine.maid(), value.get_int32())) {
_status = INTERNAL_ERROR;
diff --git a/src/server/internals/Controller.cpp b/src/server/internals/Controller.cpp
index 6a9139b5..25561535 100644
--- a/src/server/internals/Controller.cpp
+++ b/src/server/internals/Controller.cpp
@@ -23,6 +23,7 @@
#include "raul/midi_events.h"
#include "AudioBuffer.hpp"
+#include "Engine.hpp"
#include "InputPort.hpp"
#include "InternalPlugin.hpp"
#include "Notification.hpp"