aboutsummaryrefslogtreecommitdiffstats
path: root/src/engine/Machine.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-02-11 01:26:07 +0000
committerDavid Robillard <d@drobilla.net>2007-02-11 01:26:07 +0000
commitda3ac16cbfbf66edebe929f8d9bf7d76ab24dd74 (patch)
tree8371f2d2e46925df9337be9b578cfb74d671d285 /src/engine/Machine.cpp
parentcee33ba4c0859b117be94df6ccbf3eb756a850af (diff)
downloadmachina-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.cpp114
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;
}