From 5984b12b1a34840732da670ba1536f2b26a63276 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Sat, 3 Oct 2015 20:23:09 -0700 Subject: [PATCH] Timeline: Fix invalid output of control sequence playback before initial and after final control point. Closes #180 --- timeline/src/Control_Sequence.C | 4 +- timeline/src/Engine/Control_Sequence.C | 61 +++++++++++++++++--------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/timeline/src/Control_Sequence.C b/timeline/src/Control_Sequence.C index f1fa049..503052e 100644 --- a/timeline/src/Control_Sequence.C +++ b/timeline/src/Control_Sequence.C @@ -635,7 +635,9 @@ Control_Sequence::process_osc ( void ) if ( _osc_output() ) { sample_t buf[1]; - + + *buf = 0; + play( buf, (nframes_t)transport->frame, (nframes_t) 1 ); _osc_output()->value( (float)buf[0] ); } diff --git a/timeline/src/Engine/Control_Sequence.C b/timeline/src/Engine/Control_Sequence.C index d58abbb..f334e65 100644 --- a/timeline/src/Engine/Control_Sequence.C +++ b/timeline/src/Engine/Control_Sequence.C @@ -56,7 +56,7 @@ Control_Sequence::play ( sample_t *buf, nframes_t frame, nframes_t nframes ) { // THREAD_ASSERT( RT ); - Control_Point *p2, *p1 = (Control_Point*)&_widgets.front(); + Control_Point *p2, *p1 = (Control_Point*)_widgets.front(); nframes_t n = nframes; @@ -64,34 +64,53 @@ Control_Sequence::play ( sample_t *buf, nframes_t frame, nframes_t nframes ) i != _widgets.end(); ++i, p1 = p2 ) { p2 = (Control_Point*)(*i); + + if ( ! n ) + /* buffer's full, no point in continuing */ + break; if ( p2->when() < frame ) - continue; + { + if ( p2 != _widgets.back() ) + continue; - /* do incremental linear interpolation */ + /* no more control points left, fill buffer with last value */ + const float v = 1.0f - p2->control(); + + while ( n && n-- ) + *(buf++) = v; - const nframes_t len = p2->when() - p1->when(); - - const float y1 = 1.0f - p1->control(); - const float y2 = 1.0f - p2->control(); - - const nframes_t start = frame - p1->when(); + break; + } + else + { + /* do incremental linear interpolation */ + + const nframes_t len = p1 != p2 ? + p2->when() - p1->when() : + p1->when(); + + const float y1 = 1.0f - p1->control(); + const float y2 = 1.0f - p2->control(); + + const nframes_t start = frame > p1->when() ? + frame - p1->when() : + frame; - float incr; + float incr; - if ( interpolation() != None ) - incr = ( y2 - y1 ) / (float)len; - else - incr = 0.0f; + if ( interpolation() != None ) + incr = ( y2 - y1 ) / (float)len; + else + incr = 0.0f; - float v = y1 + start * incr; - - if ( ! n ) - /* buffer's full, no point in continuing */ - break; + float v = y1 + start * incr; - for ( nframes_t i = start; i < len && n && n--; ++i, v += incr ) - *(buf++) = v; + for ( nframes_t i = start; + i < start + len && n && n--; + ++i, v += incr ) + *(buf++) = v; + } } return nframes - n;