aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-12-17 01:43:22 +0000
committerDavid Robillard <d@drobilla.net>2010-12-17 01:43:22 +0000
commit02bb4118d6f056553daf383975e7a5e7eac4f38b (patch)
tree28f9c558335a2ca15bc3f1e17fd8f9ea4e8c1252
parent95b4da8350d77e28f2c37a58a18be5684c90a450 (diff)
downloadmachina-02bb4118d6f056553daf383975e7a5e7eac4f38b.tar.gz
machina-02bb4118d6f056553daf383975e7a5e7eac4f38b.tar.bz2
machina-02bb4118d6f056553daf383975e7a5e7eac4f38b.zip
Fix run duration handling and associated constant crashes (assertion failures).
Execution seemingly works for fractional note durations now... git-svn-id: http://svn.drobilla.net/lad/trunk/machina@2730 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/engine/JackDriver.cpp37
-rw-r--r--src/engine/Machine.cpp23
-rw-r--r--src/engine/Node.cpp4
-rw-r--r--src/engine/machina/Machine.hpp4
4 files changed, 23 insertions, 45 deletions
diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp
index 6e6dd4d..134ca82 100644
--- a/src/engine/JackDriver.cpp
+++ b/src/engine/JackDriver.cpp
@@ -282,39 +282,28 @@ JackDriver::on_process(jack_nframes_t nframes)
goto end;
while (true) {
- const TimeDuration run_dur = machine->run(_cycle_time);
- const TimeDuration run_dur_frames = _cycle_time.beats_to_ticks(run_dur);
+ const uint32_t run_dur_frames = machine->run(_cycle_time);
- // Machine didn't run at all (empty, or no initial states)
-
- if (run_dur.is_zero()) {
+ 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(_cycle_time.ticks_unit(), 0, 0), run_dur_frames);
- goto end;
+ _cycle_time.set_slice(TimeStamp(_frames_unit, 0, 0),
+ TimeStamp(_frames_unit, 0, 0));
+ break;
- // Machine ran for portion of cycle (finished)
} else if (machine->is_finished()) {
- const TimeStamp finish_offset = _cycle_time.offset_ticks() + run_dur_frames;
- assert(finish_offset < length_ticks);
-
+ // Machine ran for portion of cycle and is finished
machine->reset(machine->time());
_cycle_time.set_slice(TimeStamp(_frames_unit, 0, 0),
- TimeDuration(_frames_unit, nframes - finish_offset.ticks()));
- _cycle_time.set_offset(finish_offset);
+ TimeStamp(_frames_unit, nframes - run_dur_frames, 0));
+ _cycle_time.set_offset(TimeStamp(_frames_unit, run_dur_frames, 0));
- // Machine ran for entire cycle
} else {
- if (machine->is_finished()) {
- machine->reset(machine->time());
- _cycle_time.set_slice(TimeStamp(_frames_unit, 0, 0),
- TimeStamp(_frames_unit, 0, 0));
- } else {
- _cycle_time.set_slice(
- _cycle_time.start_ticks() + _cycle_time.length_ticks(),
- TimeStamp(_frames_unit, 0, 0));
- }
-
+ // Machine ran for entire cycle
+ _cycle_time.set_slice(
+ _cycle_time.start_ticks() + _cycle_time.length_ticks(),
+ TimeStamp(_frames_unit, 0, 0));
break;
}
}
diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp
index fffadc3..cbfa54e 100644
--- a/src/engine/Machine.cpp
+++ b/src/engine/Machine.cpp
@@ -299,11 +299,11 @@ Machine::exit_node(SharedPtr<Raul::MIDISink> sink, SharedPtr<Node> node)
* machine actually finished on (so it can be restarted immediately
* with sample accuracy if necessary).
*/
-TimeDuration
+uint32_t
Machine::run(const Raul::TimeSlice& time)
{
if (_is_finished)
- return TimeDuration(_time.unit(), 0, 0);
+ return 0;
SharedPtr<Raul::MIDISink> sink = _sink.lock();
@@ -317,7 +317,6 @@ Machine::run(const Raul::TimeSlice& time)
bool entered = false;
if ( ! _nodes.empty()) {
for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) {
-
if ((*n)->is_active())
(*n)->exit(sink, _time);
@@ -325,23 +324,20 @@ Machine::run(const Raul::TimeSlice& time)
if (enter_node(sink, (*n)))
entered = true;
}
-
}
}
if (!entered) {
_is_finished = true;
- return TimeStamp(_time.unit(), 0, 0);
+ return 0;
}
}
- TimeStamp this_time(_time.unit(), 0, 0);
-
while (true) {
SharedPtr<Node> earliest = earliest_node();
- // No more active states, machine is finished
if (!earliest) {
+ // No more active states, machine is finished
#ifndef NDEBUG
for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n)
assert( ! (*n)->is_active());
@@ -349,23 +345,20 @@ Machine::run(const Raul::TimeSlice& time)
_is_finished = true;
break;
- // Earliest active state ends this cycle
- } else if (earliest->exit_time() <= cycle_end) {
- this_time += earliest->exit_time() - _time;
+ } else if (time.beats_to_ticks(earliest->exit_time()) < cycle_end_frames) {
+ // Earliest active state ends this cycle
_time = earliest->exit_time();
exit_node(sink, earliest);
- // Earliest active state ends in the future, done this cycle
} else {
+ // Earliest active state ends in the future, done this cycle
_time = cycle_end;
- this_time = cycle_end; // ran the entire cycle
break;
}
}
- //assert(this_time <= time.length_beats());
- return this_time;
+ return time.beats_to_ticks(_time).ticks() - time.start_ticks().ticks();
}
diff --git a/src/engine/Node.cpp b/src/engine/Node.cpp
index cf0d5a4..c5a9192 100644
--- a/src/engine/Node.cpp
+++ b/src/engine/Node.cpp
@@ -136,8 +136,6 @@ Node::enter(SharedPtr<MIDISink> sink, TimeStamp time)
_is_active = true;
_enter_time = time;
- cerr << "ENTERING " << this << endl;
-
if (sink && _enter_action)
_enter_action->execute(sink, time);
}
@@ -148,8 +146,6 @@ Node::exit(SharedPtr<MIDISink> sink, TimeStamp time)
{
assert(_is_active);
- cerr << "EXITING " << this << endl;
-
if (sink && _exit_action)
_exit_action->execute(sink, time);
diff --git a/src/engine/machina/Machine.hpp b/src/engine/machina/Machine.hpp
index 6b29444..1d07a2c 100644
--- a/src/engine/machina/Machine.hpp
+++ b/src/engine/machina/Machine.hpp
@@ -59,8 +59,8 @@ public:
void write_state(Redland::Model& model);
// Audio context
- void reset(Raul::TimeStamp time);
- TimeDuration run(const Raul::TimeSlice& time);
+ void reset(Raul::TimeStamp time);
+ uint32_t run(const Raul::TimeSlice& time);
// Any context
inline Raul::TimeStamp time() const { return _time; }