aboutsummaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2013-01-11 22:15:55 +0000
committerDavid Robillard <d@drobilla.net>2013-01-11 22:15:55 +0000
commit6c61c79d43d1d4715ce04b46e459279d0fa6c854 (patch)
tree6193c4f634494260b33190dbdf1cf4cb440d19be /src/engine
parent5df770bf97b1cc7ac1c73e68fb617164f662d7b7 (diff)
downloadmachina-6c61c79d43d1d4715ce04b46e459279d0fa6c854.tar.gz
machina-6c61c79d43d1d4715ce04b46e459279d0fa6c854.tar.bz2
machina-6c61c79d43d1d4715ce04b46e459279d0fa6c854.zip
Move MIDISink from Machine state to Context parameter.
git-svn-id: http://svn.drobilla.net/lad/trunk/machina@4925 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/Action.hpp4
-rw-r--r--src/engine/Engine.cpp4
-rw-r--r--src/engine/JackDriver.cpp12
-rw-r--r--src/engine/JackDriver.hpp5
-rw-r--r--src/engine/Loader.cpp2
-rw-r--r--src/engine/MIDISink.hpp4
-rw-r--r--src/engine/Machine.cpp43
-rw-r--r--src/engine/MachineBuilder.cpp6
-rw-r--r--src/engine/MidiAction.cpp2
-rw-r--r--src/engine/MidiAction.hpp2
-rw-r--r--src/engine/Node.cpp4
-rw-r--r--src/engine/Node.hpp4
-rw-r--r--src/engine/SMFDriver.cpp6
-rw-r--r--src/engine/SMFDriver.hpp4
-rw-r--r--src/engine/machina/Context.hpp7
-rw-r--r--src/engine/machina/Machine.hpp9
16 files changed, 48 insertions, 70 deletions
diff --git a/src/engine/Action.hpp b/src/engine/Action.hpp
index 7e0cc4f..76834d9 100644
--- a/src/engine/Action.hpp
+++ b/src/engine/Action.hpp
@@ -35,7 +35,7 @@ namespace Machina {
/** An Action, executed on entering or exiting of a state.
*/
struct Action : public Raul::Manageable, public Stateful {
- virtual void execute(SharedPtr<MIDISink> sink, Raul::TimeStamp time) = 0;
+ virtual void execute(MIDISink* sink, Raul::TimeStamp time) = 0;
virtual void write_state(Sord::Model& model);
};
@@ -44,7 +44,7 @@ class PrintAction : public Action {
public:
PrintAction(const std::string& msg) : _msg(msg) {}
- void execute(SharedPtr<MIDISink>, Raul::TimeStamp time)
+ void execute(MIDISink* sink, Raul::TimeStamp time)
{ std::cout << "t=" << time << ": " << _msg << std::endl; }
private:
diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp
index 80eead7..1a8c867 100644
--- a/src/engine/Engine.cpp
+++ b/src/engine/Engine.cpp
@@ -117,11 +117,9 @@ Engine::export_midi(const Glib::ustring& filename, Raul::TimeDuration dur)
if (activated)
_driver->deactivate(); // FIXME: disable instead
- machine->set_sink(file_driver->writer());
file_driver->writer()->start(filename, TimeStamp(dur.unit(), 0.0));
file_driver->run(machine, dur);
- machine->set_sink(_driver);
- machine->reset(machine->time());
+ machine->reset(NULL, machine->time());
file_driver->writer()->finish();
if (activated)
diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp
index bc1e38e..f863bae 100644
--- a/src/engine/JackDriver.cpp
+++ b/src/engine/JackDriver.cpp
@@ -50,6 +50,7 @@ JackDriver::JackDriver(Raul::Forge& forge, SharedPtr<Machine> machine)
, _recording(false)
, _is_activated(false)
{
+ _context.set_sink(this);
}
JackDriver::~JackDriver()
@@ -313,8 +314,7 @@ JackDriver::on_process(jack_nframes_t nframes)
if (machine != _last_machine) {
if (_last_machine) {
assert(!_last_machine.unique()); // Realtime, can't delete
- _last_machine->set_sink(shared_from_this());
- _last_machine->reset(_last_machine->time()); // Exit all active states
+ _last_machine->reset(_context.sink(), _last_machine->time()); // Exit all active states
_last_machine.reset(); // Cut our reference
}
_machine_changed.post(); // Signal we're done with it
@@ -325,10 +325,8 @@ JackDriver::on_process(jack_nframes_t nframes)
return;
}
- machine->set_sink(shared_from_this());
-
if (_stop_flag)
- machine->reset(_context.time().start_beats());
+ machine->reset(_context.sink(), _context.time().start_beats());
process_input(machine, _context.time());
@@ -340,14 +338,14 @@ JackDriver::on_process(jack_nframes_t nframes)
if (run_dur_frames == 0) {
// Machine didn't run at all (machine has no initial states)
- machine->reset(machine->time()); // Try again next cycle
+ machine->reset(_context.sink(), machine->time()); // Try again next cycle
_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());
+ machine->reset(_context.sink(), machine->time());
_context.time().set_slice(TimeStamp(_frames_unit, 0, 0),
TimeStamp(_frames_unit, nframes - run_dur_frames, 0));
diff --git a/src/engine/JackDriver.hpp b/src/engine/JackDriver.hpp
index f28e78d..9f47363 100644
--- a/src/engine/JackDriver.hpp
+++ b/src/engine/JackDriver.hpp
@@ -20,8 +20,6 @@
#include <atomic>
-#include <boost/enable_shared_from_this.hpp>
-
#include <jack/jack.h>
#include <jack/midiport.h>
@@ -45,8 +43,7 @@ class Node;
* "Ticks" are individual frames when running under this driver, and all code
* in the processing context must be realtime safe (non-blocking).
*/
-class JackDriver : public Machina::Driver,
- public boost::enable_shared_from_this<JackDriver> {
+class JackDriver : public Machina::Driver {
public:
JackDriver(Raul::Forge& forge,
SharedPtr<Machine> machine = SharedPtr<Machine>());
diff --git a/src/engine/Loader.cpp b/src/engine/Loader.cpp
index 3baa5a0..1ce8fae 100644
--- a/src/engine/Loader.cpp
+++ b/src/engine/Loader.cpp
@@ -189,7 +189,7 @@ Loader::load(const Glib::ustring& uri)
}
if (machine && machine->nodes().size() > 0) {
- machine->reset(machine->time());
+ machine->reset(NULL, machine->time());
return machine;
} else {
return SharedPtr<Machine>();
diff --git a/src/engine/MIDISink.hpp b/src/engine/MIDISink.hpp
index ff4a1a7..47aa234 100644
--- a/src/engine/MIDISink.hpp
+++ b/src/engine/MIDISink.hpp
@@ -23,9 +23,7 @@
namespace Machina {
-/** Pure virtual base for anything you can write MIDI to.
- * \ingroup raul
- */
+/** Pure virtual base for anything you can write MIDI to. */
class MIDISink : public Raul::Deletable {
public:
virtual void write_event(Raul::TimeStamp time,
diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp
index 9538be2..8a7f0b4 100644
--- a/src/engine/Machine.cpp
+++ b/src/engine/Machine.cpp
@@ -54,10 +54,9 @@ Machine::Machine(TimeUnit unit)
Machine::Machine(const Machine& copy)
: Stateful() // don't copy RDF ID
, _active_nodes(MAX_ACTIVE_NODES, SharedPtr<Node>())
+ , _time(copy.time())
, _is_activated(false)
, _is_finished(false)
- , _time(copy.time())
- , _sink(copy._sink)
{
std::map< SharedPtr<Node>, SharedPtr<Node> > replacements;
@@ -84,7 +83,6 @@ Machine::operator=(const Machine& other)
_is_finished = false;
_time = other._time;
_pending_learn = SharedPtr<LearnRequest>();
- _sink = other._sink;
_nodes.clear();
map< SharedPtr<Node>, SharedPtr<Node> > replacements;
@@ -106,17 +104,6 @@ Machine::operator=(const Machine& other)
return *this;
}
-/** Set the MIDI sink to be used for executing MIDI actions.
- *
- * MIDI actions will silently do nothing unless this call is passed an
- * existing MIDISink before running.
- */
-void
-Machine::set_sink(SharedPtr<MIDISink> sink)
-{
- _sink = sink;
-}
-
/** Always returns a node, unless there are none */
SharedPtr<Node>
Machine::random_node()
@@ -165,16 +152,16 @@ Machine::remove_node(SharedPtr<Node> node)
/** Exit all active states and reset time to 0.
*/
void
-Machine::reset(Raul::TimeStamp time)
+Machine::reset(MIDISink* sink, Raul::TimeStamp time)
{
if (!_is_finished) {
for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) {
SharedPtr<Node> node = (*n);
- if (node->is_active())
- node->exit(_sink.lock(), time);
+ if (sink && node->is_active())
+ node->exit(sink, time);
- assert(! node->is_active());
+ assert(!node->is_active());
}
for (size_t i=0; i < MAX_ACTIVE_NODES; ++i)
@@ -211,7 +198,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(Context& context, SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates)
+Machine::enter_node(Context& context, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates)
{
assert(!node->is_active());
@@ -220,7 +207,7 @@ Machine::enter_node(Context& context, SharedPtr<MIDISink> sink, SharedPtr<Node>
size_t index = (rand() % MAX_ACTIVE_NODES);
for (size_t i=0; i < MAX_ACTIVE_NODES; ++i) {
if (_active_nodes.at(index) == NULL) {
- node->enter(sink, _time);
+ node->enter(context.sink(), _time);
assert(node->is_active());
_active_nodes.at(index) = node;
@@ -240,9 +227,9 @@ Machine::enter_node(Context& context, SharedPtr<MIDISink> sink, SharedPtr<Node>
/** Exit an active node at the current _time.
*/
void
-Machine::exit_node(Context& context, SharedPtr<MIDISink> sink, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates)
+Machine::exit_node(Context& context, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates)
{
- node->exit(sink, _time);
+ node->exit(context.sink(), _time);
write_set(updates,
node->id(),
URIs::instance().machina_active,
@@ -269,7 +256,7 @@ Machine::exit_node(Context& context, SharedPtr<MIDISink> sink, SharedPtr<Node> n
&& rand_normal > range_min
&& rand_normal < range_min + (*s)->probability()) {
- enter_node(context, sink, (*s)->head(), updates);
+ enter_node(context, (*s)->head(), updates);
break;
} else {
@@ -288,7 +275,7 @@ Machine::exit_node(Context& context, SharedPtr<MIDISink> sink, SharedPtr<Node> n
SharedPtr<Node> head = (*e)->head();
if ( ! head->is_active())
- enter_node(context, sink, head, updates);
+ enter_node(context, head, updates);
}
}
@@ -310,8 +297,6 @@ Machine::run(Context& context, SharedPtr<UpdateBuffer> updates)
if (_is_finished)
return 0;
- SharedPtr<MIDISink> sink = _sink.lock();
-
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);
@@ -323,7 +308,7 @@ Machine::run(Context& context, SharedPtr<UpdateBuffer> updates)
if ( ! _nodes.empty()) {
for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) {
if ((*n)->is_active()) {
- (*n)->exit(sink, _time);
+ (*n)->exit(context.sink(), _time);
write_set(updates,
(*n)->id(),
URIs::instance().machina_active,
@@ -331,7 +316,7 @@ Machine::run(Context& context, SharedPtr<UpdateBuffer> updates)
}
if ((*n)->is_initial()) {
- if (enter_node(context, sink, (*n), updates))
+ if (enter_node(context, (*n), updates))
entered = true;
}
}
@@ -358,7 +343,7 @@ Machine::run(Context& context, SharedPtr<UpdateBuffer> updates)
} 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(context, sink, earliest, updates);
+ exit_node(context, earliest, updates);
} else {
// Earliest active state ends in the future, done this cycle
diff --git a/src/engine/MachineBuilder.cpp b/src/engine/MachineBuilder.cpp
index 0460299..1eaf22e 100644
--- a/src/engine/MachineBuilder.cpp
+++ b/src/engine/MachineBuilder.cpp
@@ -157,7 +157,7 @@ MachineBuilder::event(Raul::TimeStamp time_offset,
_connect_node_end_time = t;
}
- node->enter(SharedPtr<MIDISink>(), t);
+ node->enter(NULL, t);
_active_nodes.push_back(node);
} else if ((buf[0] & 0xF0) == LV2_MIDI_MSG_NOTE_OFF) {
@@ -236,7 +236,7 @@ MachineBuilder::event(Raul::TimeStamp time_offset,
}
if (resolved->is_active())
- resolved->exit(SharedPtr<MIDISink>(), t);
+ resolved->exit(NULL, t);
_active_nodes.erase(i);
@@ -267,7 +267,7 @@ MachineBuilder::resolve()
unsigned char note_off[3] = { ((LV2_MIDI_MSG_NOTE_OFF & 0xF0) | (ev[0] & 0x0F)), ev[1], 0x40 };
(*i)->set_exit_action(SharedPtr<Action>(new MidiAction(3, note_off)));
set_node_duration((*i), _time - (*i)->enter_time());
- (*i)->exit(SharedPtr<MIDISink>(), _time);
+ (*i)->exit(NULL, _time);
_machine->add_node((*i));
}
}
diff --git a/src/engine/MidiAction.cpp b/src/engine/MidiAction.cpp
index d7433b3..c61ce68 100644
--- a/src/engine/MidiAction.cpp
+++ b/src/engine/MidiAction.cpp
@@ -77,7 +77,7 @@ MidiAction::set_event(size_t size, const byte* new_event)
* Safe to call concurrently with set_event.
*/
void
-MidiAction::execute(SharedPtr<MIDISink> sink, Raul::TimeStamp time)
+MidiAction::execute(MIDISink* sink, Raul::TimeStamp time)
{
const byte* const event = _event.load();
diff --git a/src/engine/MidiAction.hpp b/src/engine/MidiAction.hpp
index 7c43584..11863c6 100644
--- a/src/engine/MidiAction.hpp
+++ b/src/engine/MidiAction.hpp
@@ -42,7 +42,7 @@ public:
bool set_event(size_t size, const byte* event);
- void execute(SharedPtr<MIDISink> driver, Raul::TimeStamp time);
+ void execute(MIDISink* sink, Raul::TimeStamp time);
virtual void write_state(Sord::Model& model);
diff --git a/src/engine/Node.cpp b/src/engine/Node.cpp
index 6860452..744d7ac 100644
--- a/src/engine/Node.cpp
+++ b/src/engine/Node.cpp
@@ -123,7 +123,7 @@ Node::set_exit_action(SharedPtr<Action> action)
}
void
-Node::enter(SharedPtr<MIDISink> sink, TimeStamp time)
+Node::enter(MIDISink* sink, TimeStamp time)
{
assert(!_is_active);
@@ -136,7 +136,7 @@ Node::enter(SharedPtr<MIDISink> sink, TimeStamp time)
}
void
-Node::exit(SharedPtr<MIDISink> sink, TimeStamp time)
+Node::exit(MIDISink* sink, TimeStamp time)
{
assert(_is_active);
diff --git a/src/engine/Node.hpp b/src/engine/Node.hpp
index b0ede31..76995b5 100644
--- a/src/engine/Node.hpp
+++ b/src/engine/Node.hpp
@@ -53,8 +53,8 @@ public:
SharedPtr<Action> enter_action() { return _enter_action; }
SharedPtr<Action> exit_action() { return _exit_action; }
- void enter(SharedPtr<MIDISink> driver, TimeStamp time);
- void exit(SharedPtr<MIDISink> driver, TimeStamp time);
+ void enter(MIDISink* sink, TimeStamp time);
+ void exit(MIDISink* sink, TimeStamp time);
void edges_changed();
diff --git a/src/engine/SMFDriver.cpp b/src/engine/SMFDriver.cpp
index 757615b..641baf9 100644
--- a/src/engine/SMFDriver.cpp
+++ b/src/engine/SMFDriver.cpp
@@ -66,7 +66,7 @@ SMFDriver::learn(const string& filename, unsigned track, double q, Raul::TimeDur
else
learn_track(builder, reader, track, q, max_duration);
- m->reset(m->time());
+ m->reset(NULL, m->time());
if (m->nodes().size() > 1)
return m;
@@ -95,7 +95,7 @@ SMFDriver::learn(const string& filename, double q, Raul::TimeStamp max_duration)
learn_track(builder, reader, t, q, max_duration);
}
- m->reset(m->time());
+ m->reset(NULL, m->time());
if (m->nodes().size() > 1)
return m;
@@ -142,8 +142,8 @@ SMFDriver::run(SharedPtr<Machine> machine, Raul::TimeStamp max_time)
{
// FIXME: unit kludge (tempo only)
Context context(_forge, machine->time().unit().ppt(), _writer->unit().ppt(), 120.0);
+ context.set_sink(this);
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(context, SharedPtr<UpdateBuffer>());
}
diff --git a/src/engine/SMFDriver.hpp b/src/engine/SMFDriver.hpp
index 5da6358..f978849 100644
--- a/src/engine/SMFDriver.hpp
+++ b/src/engine/SMFDriver.hpp
@@ -18,7 +18,6 @@
#ifndef MACHINA_SMFDRIVER_HPP
#define MACHINA_SMFDRIVER_HPP
-#include <boost/enable_shared_from_this.hpp>
#include <glibmm/ustring.h>
#include "raul/SharedPtr.hpp"
@@ -35,8 +34,7 @@ namespace Machina {
class Node;
class Machine;
-class SMFDriver : public Driver,
- public boost::enable_shared_from_this<SMFDriver> {
+class SMFDriver : public Driver {
public:
SMFDriver(Raul::Forge& forge, Raul::TimeUnit unit);
diff --git a/src/engine/machina/Context.hpp b/src/engine/machina/Context.hpp
index 270ede7..c863cc4 100644
--- a/src/engine/machina/Context.hpp
+++ b/src/engine/machina/Context.hpp
@@ -19,10 +19,13 @@
#define MACHINA_CONTEXT_HPP
#include "raul/Atom.hpp"
+#include "raul/SharedPtr.hpp"
#include "raul/TimeSlice.hpp"
namespace Machina {
+class MIDISink;
+
class Context {
public:
Context(Raul::Forge& forge, uint32_t rate, uint32_t ppqn, double bpm)
@@ -30,13 +33,17 @@ public:
, _time(rate, ppqn, bpm)
{}
+ void set_sink(MIDISink* sink) { _sink = sink; }
+
Raul::Forge& forge() { return _forge; }
const Raul::TimeSlice& time() const { return _time; }
Raul::TimeSlice& time() { return _time; }
+ MIDISink* sink() { return _sink; }
private:
Raul::Forge& _forge;
Raul::TimeSlice _time;
+ MIDISink* _sink;
};
} // namespace Machina
diff --git a/src/engine/machina/Machine.hpp b/src/engine/machina/Machine.hpp
index 6691b43..164c2e4 100644
--- a/src/engine/machina/Machine.hpp
+++ b/src/engine/machina/Machine.hpp
@@ -66,7 +66,7 @@ public:
void write_state(Sord::Model& model);
// Audio context
- void reset(Raul::TimeStamp time);
+ void reset(MIDISink* sink, Raul::TimeStamp time);
uint32_t run(Context& context, SharedPtr<UpdateBuffer> updates);
// Any context
@@ -82,19 +82,16 @@ public:
SharedPtr<Node> random_node();
SharedPtr<Edge> random_edge();
- void set_sink(SharedPtr<MIDISink> sink);
-
private:
// Audio context
SharedPtr<Node> earliest_node() const;
- 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);
+ bool enter_node(Context& context, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates);
+ void exit_node(Context& context, SharedPtr<Node> node, SharedPtr<UpdateBuffer> updates);
static const size_t MAX_ACTIVE_NODES = 128;
std::vector< SharedPtr<Node> > _active_nodes;
SharedPtr<LearnRequest> _pending_learn;
- WeakPtr<MIDISink> _sink;
Nodes _nodes;
Raul::TimeStamp _time;
bool _is_activated;