From 6c61c79d43d1d4715ce04b46e459279d0fa6c854 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 11 Jan 2013 22:15:55 +0000 Subject: Move MIDISink from Machine state to Context parameter. git-svn-id: http://svn.drobilla.net/lad/trunk/machina@4925 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/Action.hpp | 4 ++-- src/engine/Engine.cpp | 4 +--- src/engine/JackDriver.cpp | 12 +++++------- src/engine/JackDriver.hpp | 5 +---- src/engine/Loader.cpp | 2 +- src/engine/MIDISink.hpp | 4 +--- src/engine/Machine.cpp | 43 ++++++++++++++---------------------------- src/engine/MachineBuilder.cpp | 6 +++--- src/engine/MidiAction.cpp | 2 +- src/engine/MidiAction.hpp | 2 +- src/engine/Node.cpp | 4 ++-- src/engine/Node.hpp | 4 ++-- src/engine/SMFDriver.cpp | 6 +++--- src/engine/SMFDriver.hpp | 4 +--- src/engine/machina/Context.hpp | 7 +++++++ src/engine/machina/Machine.hpp | 9 +++------ 16 files changed, 48 insertions(+), 70 deletions(-) (limited to 'src/engine') 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 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, 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) , _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 -#include - #include #include @@ -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 { +class JackDriver : public Machina::Driver { public: JackDriver(Raul::Forge& forge, SharedPtr machine = SharedPtr()); 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(); 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()) + , _time(copy.time()) , _is_activated(false) , _is_finished(false) - , _time(copy.time()) - , _sink(copy._sink) { std::map< SharedPtr, SharedPtr > replacements; @@ -84,7 +83,6 @@ Machine::operator=(const Machine& other) _is_finished = false; _time = other._time; _pending_learn = SharedPtr(); - _sink = other._sink; _nodes.clear(); map< SharedPtr, SharedPtr > 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 sink) -{ - _sink = sink; -} - /** Always returns a node, unless there are none */ SharedPtr Machine::random_node() @@ -165,16 +152,16 @@ Machine::remove_node(SharedPtr 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 = (*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 sink, SharedPtr node, SharedPtr updates) +Machine::enter_node(Context& context, SharedPtr node, SharedPtr updates) { assert(!node->is_active()); @@ -220,7 +207,7 @@ Machine::enter_node(Context& context, SharedPtr sink, SharedPtr 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 sink, SharedPtr /** Exit an active node at the current _time. */ void -Machine::exit_node(Context& context, SharedPtr sink, SharedPtr node, SharedPtr updates) +Machine::exit_node(Context& context, SharedPtr node, SharedPtr 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 sink, SharedPtr 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 sink, SharedPtr n SharedPtr 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 updates) if (_is_finished) return 0; - SharedPtr 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 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 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 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(), 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(), 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(new MidiAction(3, note_off))); set_node_duration((*i), _time - (*i)->enter_time()); - (*i)->exit(SharedPtr(), _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 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 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) } void -Node::enter(SharedPtr sink, TimeStamp time) +Node::enter(MIDISink* sink, TimeStamp time) { assert(!_is_active); @@ -136,7 +136,7 @@ Node::enter(SharedPtr sink, TimeStamp time) } void -Node::exit(SharedPtr 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 enter_action() { return _enter_action; } SharedPtr exit_action() { return _exit_action; } - void enter(SharedPtr driver, TimeStamp time); - void exit(SharedPtr 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, 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()); } 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 #include #include "raul/SharedPtr.hpp" @@ -35,8 +34,7 @@ namespace Machina { class Node; class Machine; -class SMFDriver : public Driver, - public boost::enable_shared_from_this { +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 updates); // Any context @@ -82,19 +82,16 @@ public: SharedPtr random_node(); SharedPtr random_edge(); - void set_sink(SharedPtr sink); - private: // Audio context SharedPtr earliest_node() const; - bool enter_node(Context& context, SharedPtr sink, SharedPtr node, SharedPtr updates); - void exit_node(Context& context, SharedPtr sink, SharedPtr, SharedPtr updates); + bool enter_node(Context& context, SharedPtr node, SharedPtr updates); + void exit_node(Context& context, SharedPtr node, SharedPtr updates); static const size_t MAX_ACTIVE_NODES = 128; std::vector< SharedPtr > _active_nodes; SharedPtr _pending_learn; - WeakPtr _sink; Nodes _nodes; Raul::TimeStamp _time; bool _is_activated; -- cgit v1.2.1