From 02bb4118d6f056553daf383975e7a5e7eac4f38b Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 17 Dec 2010 01:43:22 +0000 Subject: 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 --- src/engine/JackDriver.cpp | 37 +++++++++++++------------------------ src/engine/Machine.cpp | 23 ++++++++--------------- src/engine/Node.cpp | 4 ---- src/engine/machina/Machine.hpp | 4 ++-- 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 sink, SharedPtr 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 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 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 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 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; } -- cgit v1.2.1