diff options
author | David Robillard <d@drobilla.net> | 2007-02-11 01:26:07 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2007-02-11 01:26:07 +0000 |
commit | da3ac16cbfbf66edebe929f8d9bf7d76ab24dd74 (patch) | |
tree | 8371f2d2e46925df9337be9b578cfb74d671d285 /src/engine/Machine.cpp | |
parent | cee33ba4c0859b117be94df6ccbf3eb756a850af (diff) | |
download | machina-da3ac16cbfbf66edebe929f8d9bf7d76ab24dd74.tar.gz machina-da3ac16cbfbf66edebe929f8d9bf7d76ab24dd74.tar.bz2 machina-da3ac16cbfbf66edebe929f8d9bf7d76ab24dd74.zip |
Moved Maid from Ingen to Raul.
Working machina MIDI learn, fixes, etc, etc.
git-svn-id: http://svn.drobilla.net/lad/machina@302 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine/Machine.cpp')
-rw-r--r-- | src/engine/Machine.cpp | 114 |
1 files changed, 41 insertions, 73 deletions
diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp index 3f28414..476e3d1 100644 --- a/src/engine/Machine.cpp +++ b/src/engine/Machine.cpp @@ -15,10 +15,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include <algorithm> +#include "raul/SharedPtr.h" #include "machina/Machine.hpp" #include "machina/Node.hpp" #include "machina/Edge.hpp" +#include "machina/MidiAction.hpp" namespace Machina { @@ -103,25 +104,27 @@ Machine::exit_node(const SharedPtr<Node> node) /** Run the machine for @a nframes frames. * - * Returns false when the machine has finished running (i.e. there are - * no currently active states). - * - * If this returns false, time() will return the exact time stamp the + * Returns the duration of time the machine actually ran (from 0 to nframes). + * Caller can check is_finished() to determine if the machine still has any + * active states. If not, time() will return the exact time stamp the * machine actually finished on (so it can be restarted immediately * with sample accuracy if necessary). */ -bool +FrameCount Machine::run(FrameCount nframes) { - if (_is_finished) - return false; + using namespace std; + if (_is_finished) { + cerr << "FINISHED\n"; + return 0; + } const FrameCount cycle_end = _time + nframes; + //std::cerr << "Start: " << _time << std::endl; + assert(_is_activated); - //std::cerr << "--------- " << _time << " - " << _time + nframes << std::endl; - // Initial run, enter all initial states if (_time == 0) { bool entered = false; @@ -131,16 +134,19 @@ Machine::run(FrameCount nframes) (*n)->enter(0); entered = true; } else { - (*n)->exit(0); + if ((*n)->is_active()) + (*n)->exit(0); } } } if (!entered) { - _is_finished = false; // run next time - return false; // but done this cycle + _is_finished = true; + return 0; } } + FrameCount this_time = 0; + while (true) { SharedPtr<Node> earliest = earliest_node(); @@ -148,83 +154,45 @@ Machine::run(FrameCount nframes) // No more active states, machine is finished if (!earliest) { _is_finished = true; - return false; + break; // Earliest active state ends this cycle } else if (earliest->exit_time() < cycle_end) { + this_time += earliest->exit_time() - _time; _time = earliest->exit_time(); exit_node(earliest); // Earliest active state ends in the future, done this cycle } else { _time = cycle_end; - return true; + this_time = nframes; // ran the entire cycle + break; } } -#if 0 - while (!done) { - - done = true; - - for (std::vector<Node*>::iterator i = _voices.begin(); - i != _voices.end(); ++i) { - - Node* const n = *i; - - // Active voice which ends within this cycle, transition - if (n && n->is_active() && n->end_time() < cycle_end) { - // Guaranteed to be within this cycle - const FrameCount end_time = std::max(_time, n->end_time()); - n->exit(std::max(_time, n->end_time())); - done = false; - - // Greedily grab one of the successors with the voice already - // on this node so voices follow paths nicely - for (Node::EdgeList::const_iterator s = n->outgoing_edges().begin(); - s != n->outgoing_edges().end(); ++s) { - Node* dst = (*s)->dst(); - if (!dst->is_active()) { - dst->enter(end_time); - *i = dst; - break; - } - } + //std::cerr << "Done: " << this_time << std::endl; - latest_event = end_time; - } + assert(this_time <= nframes); + return this_time; +} - } - // FIXME: use free voices to claim any 'free successors' - // (when nodes have multiple successors and one gets chosen in the - // greedy bit above) - - // If every voice is on the initial node... - bool is_reset = true; - for (std::vector<Node*>::iterator i = _voices.begin(); - i != _voices.end(); ++i) - if ((*i) != NULL && (*i)->is_active()) - is_reset = false; - - // ... then start - if (is_reset) { - - std::vector<Node*>::iterator n = _voices.begin(); - for (Node::EdgeList::const_iterator s = _initial_node->outgoing_edges().begin(); - s != _initial_node->outgoing_edges().end() && n != _voices.end(); - ++s, ++n) { - (*s)->dst()->enter(latest_event); - done = false; - *n = (*s)->dst(); - } - } - } - _time += nframes; +/** Push a node onto the learn stack. + * + * NOT realtime (actions are allocated here). + */ +void +Machine::learn(SharedPtr<LearnRequest> learn) +{ + std::cerr << "LEARN\n"; + + /*LearnRequest request(node, + SharedPtr<MidiAction>(new MidiAction(4, NULL)), + SharedPtr<MidiAction>(new MidiAction(4, NULL)));*/ - return false; -#endif + //_pending_learns.push_back(learn); + _pending_learn = learn; } |