aboutsummaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2013-01-11 21:43:31 +0000
committerDavid Robillard <d@drobilla.net>2013-01-11 21:43:31 +0000
commitea7bc6c83e7e9131f6bfb799f4b8e5f864bd1d4f (patch)
tree5c877755717def8dcd92bac9915451551620f349 /src/engine
parent9dbc37d2c62bb79351f37de82fbfa4aac329c851 (diff)
downloadmachina-ea7bc6c83e7e9131f6bfb799f4b8e5f864bd1d4f.tar.gz
machina-ea7bc6c83e7e9131f6bfb799f4b8e5f864bd1d4f.tar.bz2
machina-ea7bc6c83e7e9131f6bfb799f4b8e5f864bd1d4f.zip
Move run context information to Context object and remove Machine::_forge.
git-svn-id: http://svn.drobilla.net/lad/trunk/machina@4923 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/JackDriver.cpp108
-rw-r--r--src/engine/JackDriver.hpp4
-rw-r--r--src/engine/Loader.cpp2
-rw-r--r--src/engine/Machine.cpp35
-rw-r--r--src/engine/Recorder.cpp2
-rw-r--r--src/engine/SMFDriver.cpp11
-rw-r--r--src/engine/machina/Context.hpp44
-rw-r--r--src/engine/machina/Machine.hpp10
8 files changed, 132 insertions, 84 deletions
diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp
index bcde9ef..bc1e38e 100644
--- a/src/engine/JackDriver.cpp
+++ b/src/engine/JackDriver.cpp
@@ -18,9 +18,10 @@
#include <iostream>
#include <iomanip>
-#include "machina_config.h"
+#include "machina/Context.hpp"
#include "machina/URIs.hpp"
#include "machina/Updates.hpp"
+#include "machina_config.h"
#include "JackDriver.hpp"
#include "LearnRequest.hpp"
@@ -38,9 +39,9 @@ JackDriver::JackDriver(Raul::Forge& forge, SharedPtr<Machine> machine)
, _machine_changed(0)
, _input_port(NULL)
, _output_port(NULL)
+ , _context(forge, 48000, MACHINA_PPQN, 120.0)
, _frames_unit(TimeUnit::FRAMES, 48000)
, _beats_unit(TimeUnit::BEATS, 19200)
- , _cycle_time(48000, MACHINA_PPQN, 120.0)
, _bpm(120.0)
, _quantization(0.0f)
, _stop(0)
@@ -77,28 +78,27 @@ JackDriver::attach(const std::string& client_name)
if (jack_client()) {
- //_cycle_time.set_tick_rate(1/(double)sample_rate());
+ _context.time().set_tick_rate(sample_rate());
_input_port = jack_port_register(jack_client(),
- "in",
- JACK_DEFAULT_MIDI_TYPE, JackPortIsInput,
- 0);
+ "in",
+ JACK_DEFAULT_MIDI_TYPE, JackPortIsInput,
+ 0);
if (!_input_port)
std:: cerr << "WARNING: Failed to create MIDI input port." << std::endl;
_output_port = jack_port_register(jack_client(),
- "out",
- JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput,
- 0);
+ "out",
+ JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput,
+ 0);
if (!_output_port)
std::cerr << "WARNING: Failed to create MIDI output port." << std::endl;
if (!_machine)
_machine = SharedPtr<Machine>(
- new Machine(_forge,
- TimeUnit::frames(jack_get_sample_rate(jack_client()))));
+ new Machine(TimeUnit::frames(jack_get_sample_rate(jack_client()))));
_machine->activate();
}
@@ -205,8 +205,8 @@ JackDriver::process_input(SharedPtr<Machine> machine, const Raul::TimeSlice& tim
if (learn) {
learn->enter_action()->set_event(ev.size, ev.buffer);
learn->start(_quantization.get(),
- TimeStamp(TimeUnit::frames(sample_rate()),
- jack_last_frame_time(_client) + ev.time, 0));
+ TimeStamp(TimeUnit::frames(sample_rate()),
+ jack_last_frame_time(_client) + ev.time, 0));
}
} else if (ev.buffer[0] == 0x80) {
@@ -218,7 +218,7 @@ JackDriver::process_input(SharedPtr<Machine> machine, const Raul::TimeSlice& tim
learn->exit_action()->set_event(ev.size, ev.buffer);
learn->finish(
TimeStamp(TimeUnit::frames(sample_rate()),
- jack_last_frame_time(_client) + ev.time, 0));
+ jack_last_frame_time(_client) + ev.time, 0));
const uint64_t id = Stateful::next_id();
write_set(_updates, id,
@@ -248,39 +248,41 @@ JackDriver::write_event(Raul::TimeStamp time,
if (!_output_port)
return;
- if (_cycle_time.beats_to_ticks(time) + _cycle_time.offset_ticks() < _cycle_time.start_ticks()) {
+ const Raul::TimeSlice& slice = _context.time();
+
+ if (slice.beats_to_ticks(time) + slice.offset_ticks() < slice.start_ticks()) {
std::cerr << "ERROR: Missed event by "
- << _cycle_time.start_ticks()
- - (_cycle_time.beats_to_ticks(time) + _cycle_time.offset_ticks())
- << " ticks"
- << "\n\tbpm: " << _cycle_time.bpm()
- << "\n\tev time: " << _cycle_time.beats_to_ticks(time)
- << "\n\tcycle_start: " << _cycle_time.start_ticks()
- << "\n\tcycle_end: " << _cycle_time.start_ticks() + _cycle_time.length_ticks()
- << "\n\tcycle_length: " << _cycle_time.length_ticks() << std::endl << std::endl;
+ << slice.start_ticks()
+ - (slice.beats_to_ticks(time) + slice.offset_ticks())
+ << " ticks"
+ << "\n\tbpm: " << slice.bpm()
+ << "\n\tev time: " << slice.beats_to_ticks(time)
+ << "\n\tcycle_start: " << slice.start_ticks()
+ << "\n\tcycle_end: " << slice.start_ticks() + slice.length_ticks()
+ << "\n\tcycle_length: " << slice.length_ticks() << std::endl << std::endl;
return;
}
- const TimeDuration nframes = _cycle_time.length_ticks();
- const TimeStamp offset = _cycle_time.beats_to_ticks(time)
- + _cycle_time.offset_ticks() - _cycle_time.start_ticks();
+ const TimeDuration nframes = slice.length_ticks();
+ const TimeStamp offset = slice.beats_to_ticks(time)
+ + slice.offset_ticks() - slice.start_ticks();
- if ( ! (offset < _cycle_time.offset_ticks() + nframes)) {
+ if ( ! (offset < slice.offset_ticks() + nframes)) {
std::cerr << "ERROR: Event offset " << offset << " outside cycle "
- << "\n\tbpm: " << _cycle_time.bpm()
- << "\n\tev time: " << _cycle_time.beats_to_ticks(time)
- << "\n\tcycle_start: " << _cycle_time.start_ticks()
- << "\n\tcycle_end: " << _cycle_time.start_ticks() + _cycle_time.length_ticks()
- << "\n\tcycle_length: " << _cycle_time.length_ticks() << std::endl;
+ << "\n\tbpm: " << slice.bpm()
+ << "\n\tev time: " << slice.beats_to_ticks(time)
+ << "\n\tcycle_start: " << slice.start_ticks()
+ << "\n\tcycle_end: " << slice.start_ticks() + slice.length_ticks()
+ << "\n\tcycle_length: " << slice.length_ticks() << std::endl;
} else {
#ifdef JACK_MIDI_NEEDS_NFRAMES
jack_midi_event_write(
- jack_port_get_buffer(_output_port, nframes), offset,
- event, size, nframes);
+ jack_port_get_buffer(_output_port, nframes), offset,
+ event, size, nframes);
#else
jack_midi_event_write(
- jack_port_get_buffer(_output_port, nframes.ticks()), offset.ticks(),
- event, size);
+ jack_port_get_buffer(_output_port, nframes.ticks()), offset.ticks(),
+ event, size);
#endif
}
}
@@ -288,7 +290,7 @@ JackDriver::write_event(Raul::TimeStamp time,
void
JackDriver::on_process(jack_nframes_t nframes)
{
- _cycle_time.set_bpm(_bpm.get());
+ _context.time().set_bpm(_bpm.get());
assert(_output_port);
#ifdef JACK_MIDI_NEEDS_NFRAMES
@@ -297,11 +299,11 @@ JackDriver::on_process(jack_nframes_t nframes)
jack_midi_clear_buffer(jack_port_get_buffer(_output_port, nframes));
#endif
- TimeStamp length_ticks(TimeStamp(_cycle_time.ticks_unit(), nframes));
- TimeStamp length_beats(_cycle_time.ticks_to_beats(length_ticks));
+ TimeStamp length_ticks(TimeStamp(_context.time().ticks_unit(), nframes));
+ TimeStamp length_beats(_context.time().ticks_to_beats(length_ticks));
- _cycle_time.set_length(length_ticks);
- _cycle_time.set_offset(TimeStamp(_cycle_time.ticks_unit(), 0, 0));
+ _context.time().set_length(length_ticks);
+ _context.time().set_offset(TimeStamp(_context.time().ticks_unit(), 0, 0));
/* Take a reference to machine here and use only it during the process
* cycle so _machine can be switched with set_machine during a cycle. */
@@ -326,35 +328,35 @@ JackDriver::on_process(jack_nframes_t nframes)
machine->set_sink(shared_from_this());
if (_stop_flag)
- machine->reset(_cycle_time.start_beats());
+ machine->reset(_context.time().start_beats());
- process_input(machine, _cycle_time);
+ process_input(machine, _context.time());
if (machine->is_empty() || !machine->is_activated())
goto end;
while (true) {
- const uint32_t run_dur_frames = machine->run(_cycle_time, _updates);
+ const uint32_t run_dur_frames = machine->run(_context, _updates);
if (run_dur_frames == 0) {
// Machine didn't run at all (machine has no initial states)
machine->reset(machine->time()); // Try again next cycle
- _cycle_time.set_slice(TimeStamp(_frames_unit, 0, 0),
- TimeStamp(_frames_unit, 0, 0));
+ _context.time().set_slice(TimeStamp(_frames_unit, 0, 0),
+ TimeStamp(_frames_unit, 0, 0));
break;
} else if (machine->is_finished()) {
// Machine ran for portion of cycle and is finished
machine->reset(machine->time());
- _cycle_time.set_slice(TimeStamp(_frames_unit, 0, 0),
- TimeStamp(_frames_unit, nframes - run_dur_frames, 0));
- _cycle_time.set_offset(TimeStamp(_frames_unit, run_dur_frames, 0));
+ _context.time().set_slice(TimeStamp(_frames_unit, 0, 0),
+ TimeStamp(_frames_unit, nframes - run_dur_frames, 0));
+ _context.time().set_offset(TimeStamp(_frames_unit, run_dur_frames, 0));
} else {
// Machine ran for entire cycle
- _cycle_time.set_slice(
- _cycle_time.start_ticks() + _cycle_time.length_ticks(),
+ _context.time().set_slice(
+ _context.time().start_ticks() + _context.time().length_ticks(),
TimeStamp(_frames_unit, 0, 0));
break;
}
@@ -366,8 +368,8 @@ end:
_last_machine = machine;
if (_stop_flag) {
- _cycle_time.set_slice(TimeStamp(_frames_unit, 0, 0),
- TimeStamp(_frames_unit, 0, 0));
+ _context.time().set_slice(TimeStamp(_frames_unit, 0, 0),
+ TimeStamp(_frames_unit, 0, 0));
_stop_flag = false;
}
}
diff --git a/src/engine/JackDriver.hpp b/src/engine/JackDriver.hpp
index 5e76f1a..f28e78d 100644
--- a/src/engine/JackDriver.hpp
+++ b/src/engine/JackDriver.hpp
@@ -29,6 +29,7 @@
#include "raul/Semaphore.hpp"
#include "raul/SharedPtr.hpp"
+#include "machina/Context.hpp"
#include "machina/Driver.hpp"
#include "machina/Machine.hpp"
@@ -107,9 +108,10 @@ private:
jack_port_t* _input_port;
jack_port_t* _output_port;
+ Context _context;
+
Raul::TimeUnit _frames_unit;
Raul::TimeUnit _beats_unit;
- Raul::TimeSlice _cycle_time;
Raul::DoubleBuffer<double> _bpm;
Raul::DoubleBuffer<double> _quantization;
diff --git a/src/engine/Loader.cpp b/src/engine/Loader.cpp
index 0ee4f11..3baa5a0 100644
--- a/src/engine/Loader.cpp
+++ b/src/engine/Loader.cpp
@@ -69,7 +69,7 @@ Loader::load(const Glib::ustring& uri)
cout << "[Loader] Loading " << document_uri << endl;
machine = SharedPtr<Machine>(
- new Machine(_forge, TimeUnit::beats(MACHINA_PPQN)));
+ new Machine(TimeUnit::beats(MACHINA_PPQN)));
typedef std::map<Sord::Node, SharedPtr<Node> > Created;
Created created;
diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp
index ce4d60f..24e6aaf 100644
--- a/src/engine/Machine.cpp
+++ b/src/engine/Machine.cpp
@@ -26,6 +26,7 @@
#include "machina/Machine.hpp"
#include "machina/Updates.hpp"
#include "machina/URIs.hpp"
+#include "machina/Context.hpp"
#include "Edge.hpp"
#include "Node.hpp"
@@ -37,9 +38,8 @@ using namespace Raul;
namespace Machina {
-Machine::Machine(Raul::Forge& forge, TimeUnit unit)
+Machine::Machine(TimeUnit unit)
: _active_nodes(MAX_ACTIVE_NODES, SharedPtr<Node>())
- , _forge(forge)
, _is_activated(false)
, _is_finished(false)
, _time(unit, 0, 0)
@@ -54,7 +54,6 @@ Machine::Machine(Raul::Forge& forge, TimeUnit unit)
Machine::Machine(const Machine& copy)
: Stateful() // don't copy RDF ID
, _active_nodes(MAX_ACTIVE_NODES, SharedPtr<Node>())
- , _forge(copy._forge)
, _is_activated(false)
, _is_finished(false)
, _time(copy.time())
@@ -212,7 +211,7 @@ Machine::earliest_node() const
* Returns true if node was entered, or false if the maximum active nodes has been reached.
*/
bool
-Machine::enter_node(SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates)
+Machine::enter_node(Context& context, SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates)
{
assert(!node->is_active());
@@ -228,7 +227,7 @@ Machine::enter_node(SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<Up
write_set(updates,
node->id(),
URIs::instance().machina_active,
- _forge.make(true));
+ context.forge().make(true));
return true;
}
index = (index + 1) % MAX_ACTIVE_NODES;
@@ -241,13 +240,13 @@ Machine::enter_node(SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<Up
/** Exit an active node at the current _time.
*/
void
-Machine::exit_node(SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates)
+Machine::exit_node(Context& context, SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates)
{
node->exit(sink, _time);
write_set(updates,
node->id(),
URIs::instance().machina_active,
- _forge.make(false));
+ context.forge().make(false));
assert(!node->is_active());
@@ -270,7 +269,7 @@ Machine::exit_node(SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<Upd
&& rand_normal > range_min
&& rand_normal < range_min + (*s)->probability()) {
- enter_node(sink, (*s)->head(), updates);
+ enter_node(context, sink, (*s)->head(), updates);
break;
} else {
@@ -289,7 +288,7 @@ Machine::exit_node(SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<Upd
SharedPtr<Node> head = (*e)->head();
if ( ! head->is_active())
- enter_node(sink, head, updates);
+ enter_node(context, sink, head, updates);
}
}
@@ -306,16 +305,15 @@ Machine::exit_node(SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<Upd
* with sample accuracy if necessary).
*/
uint32_t
-Machine::run(const Raul::TimeSlice& time, SharedPtr<UpdateBuffer> updates)
+Machine::run(Context& context, SharedPtr<UpdateBuffer> updates)
{
if (_is_finished)
return 0;
-
SharedPtr<MIDISink> sink = _sink.lock();
- const TimeStamp cycle_end_frames = time.start_ticks() + time.length_ticks();
- const TimeStamp cycle_end = time.ticks_to_beats(cycle_end_frames);
+ const TimeStamp cycle_end_frames = context.time().start_ticks() + context.time().length_ticks();
+ const TimeStamp cycle_end = context.time().ticks_to_beats(cycle_end_frames);
assert(_is_activated);
@@ -329,11 +327,11 @@ Machine::run(const Raul::TimeSlice& time, SharedPtr<UpdateBuffer> updates)
write_set(updates,
(*n)->id(),
URIs::instance().machina_active,
- _forge.make(false));
+ context.forge().make(false));
}
if ((*n)->is_initial()) {
- if (enter_node(sink, (*n), updates))
+ if (enter_node(context, sink, (*n), updates))
entered = true;
}
}
@@ -357,10 +355,10 @@ Machine::run(const Raul::TimeSlice& time, SharedPtr<UpdateBuffer> updates)
_is_finished = true;
break;
- } else if (time.beats_to_ticks(earliest->exit_time()) < cycle_end_frames) {
+ } else if (context.time().beats_to_ticks(earliest->exit_time()) < cycle_end_frames) {
// Earliest active state ends this cycle
_time = earliest->exit_time();
- exit_node(sink, earliest, updates);
+ exit_node(context, sink, earliest, updates);
} else {
// Earliest active state ends in the future, done this cycle
@@ -370,7 +368,8 @@ Machine::run(const Raul::TimeSlice& time, SharedPtr<UpdateBuffer> updates)
}
- return time.beats_to_ticks(_time).ticks() - time.start_ticks().ticks();
+ return context.time().beats_to_ticks(_time).ticks()
+ - context.time().start_ticks().ticks();
}
/** Push a node onto the learn stack.
diff --git a/src/engine/Recorder.cpp b/src/engine/Recorder.cpp
index 9d8c4fe..4a67f65 100644
--- a/src/engine/Recorder.cpp
+++ b/src/engine/Recorder.cpp
@@ -35,7 +35,7 @@ Recorder::Recorder(Raul::Forge& forge,
, _unit(unit)
, _record_buffer(buffer_size)
, _builder(new MachineBuilder(
- SharedPtr<Machine>(new Machine(forge, unit)), q, step))
+ SharedPtr<Machine>(new Machine(unit)), q, step))
{
}
diff --git a/src/engine/SMFDriver.cpp b/src/engine/SMFDriver.cpp
index 000ce0e..757615b 100644
--- a/src/engine/SMFDriver.cpp
+++ b/src/engine/SMFDriver.cpp
@@ -22,6 +22,7 @@
#include "raul/SharedPtr.hpp"
+#include "machina/Context.hpp"
#include "machina/Machine.hpp"
#include "Edge.hpp"
@@ -51,7 +52,7 @@ SharedPtr<Machine>
SMFDriver::learn(const string& filename, unsigned track, double q, Raul::TimeDuration max_duration)
{
//assert(q.unit() == max_duration.unit());
- SharedPtr<Machine> m(new Machine(_forge, max_duration.unit()));
+ SharedPtr<Machine> m(new Machine(max_duration.unit()));
SharedPtr<MachineBuilder> builder = SharedPtr<MachineBuilder>(new MachineBuilder(m, q, false));
SMFReader reader;
@@ -80,7 +81,7 @@ SMFDriver::learn(const string& filename, unsigned track, double q, Raul::TimeDur
SharedPtr<Machine>
SMFDriver::learn(const string& filename, double q, Raul::TimeStamp max_duration)
{
- SharedPtr<Machine> m(new Machine(_forge, max_duration.unit()));
+ SharedPtr<Machine> m(new Machine(max_duration.unit()));
SharedPtr<MachineBuilder> builder = SharedPtr<MachineBuilder>(new MachineBuilder(m, q, false));
SMFReader reader;
@@ -140,10 +141,10 @@ void
SMFDriver::run(SharedPtr<Machine> machine, Raul::TimeStamp max_time)
{
// FIXME: unit kludge (tempo only)
- Raul::TimeSlice time(machine->time().unit().ppt(), _writer->unit().ppt(), 120.0);
- time.set_slice(TimeStamp(max_time.unit(), 0, 0), time.beats_to_ticks(max_time));
+ Context context(_forge, machine->time().unit().ppt(), _writer->unit().ppt(), 120.0);
+ context.time().set_slice(TimeStamp(max_time.unit(), 0, 0), context.time().beats_to_ticks(max_time));
machine->set_sink(shared_from_this());
- machine->run(time, SharedPtr<UpdateBuffer>());
+ machine->run(context, SharedPtr<UpdateBuffer>());
}
} // namespace Machina
diff --git a/src/engine/machina/Context.hpp b/src/engine/machina/Context.hpp
new file mode 100644
index 0000000..270ede7
--- /dev/null
+++ b/src/engine/machina/Context.hpp
@@ -0,0 +1,44 @@
+/* This file is part of Machina.
+ * Copyright 2007-2012 David Robillard <http://drobilla.net>
+ *
+ * Machina 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Machina 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 Machina. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MACHINA_CONTEXT_HPP
+#define MACHINA_CONTEXT_HPP
+
+#include "raul/Atom.hpp"
+#include "raul/TimeSlice.hpp"
+
+namespace Machina {
+
+class Context {
+public:
+ Context(Raul::Forge& forge, uint32_t rate, uint32_t ppqn, double bpm)
+ : _forge(forge)
+ , _time(rate, ppqn, bpm)
+ {}
+
+ Raul::Forge& forge() { return _forge; }
+ const Raul::TimeSlice& time() const { return _time; }
+ Raul::TimeSlice& time() { return _time; }
+
+private:
+ Raul::Forge& _forge;
+ Raul::TimeSlice _time;
+};
+
+} // namespace Machina
+
+#endif // MACHINA_CONTEXT_HPP
diff --git a/src/engine/machina/Machine.hpp b/src/engine/machina/Machine.hpp
index d65b670..0109742 100644
--- a/src/engine/machina/Machine.hpp
+++ b/src/engine/machina/Machine.hpp
@@ -35,6 +35,7 @@
namespace Machina {
+class Context;
class Controller;
class LearnRequest;
@@ -42,7 +43,7 @@ class LearnRequest;
*/
class Machine : public Stateful {
public:
- Machine(Raul::Forge& forge, TimeUnit unit);
+ Machine(TimeUnit unit);
Machine(const Machine& copy);
Machine& operator=(const Machine& other);
@@ -66,7 +67,7 @@ public:
// Audio context
void reset(Raul::TimeStamp time);
- uint32_t run(const Raul::TimeSlice& time, SharedPtr<UpdateBuffer> updates);
+ uint32_t run(Context& context, SharedPtr<UpdateBuffer> updates);
// Any context
inline Raul::TimeStamp time() const { return _time; }
@@ -87,13 +88,12 @@ private:
// Audio context
SharedPtr<Node> earliest_node() const;
- bool enter_node(SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates);
- void exit_node(SharedPtr<MIDISink> sink, SharedPtr<Node>, SharedPtr<UpdateBuffer> updates);
+ bool enter_node(Context& context, SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates);
+ void exit_node(Context& context, SharedPtr<MIDISink> sink, SharedPtr<Node>, SharedPtr<UpdateBuffer> updates);
static const size_t MAX_ACTIVE_NODES = 128;
std::vector< SharedPtr<Node> > _active_nodes;
- Raul::Forge& _forge;
bool _is_activated;
bool _is_finished;
Raul::TimeStamp _time;