Timeline: Fix invalid output of control sequence playback before initial and after final control point.

Closes #180
This commit is contained in:
Jonathan Moore Liles 2015-10-03 20:23:09 -07:00
parent f483957996
commit 5984b12b1a
2 changed files with 46 additions and 25 deletions

View File

@ -635,7 +635,9 @@ Control_Sequence::process_osc ( void )
if ( _osc_output() ) if ( _osc_output() )
{ {
sample_t buf[1]; sample_t buf[1];
*buf = 0;
play( buf, (nframes_t)transport->frame, (nframes_t) 1 ); play( buf, (nframes_t)transport->frame, (nframes_t) 1 );
_osc_output()->value( (float)buf[0] ); _osc_output()->value( (float)buf[0] );
} }

View File

@ -56,7 +56,7 @@ Control_Sequence::play ( sample_t *buf, nframes_t frame, nframes_t nframes )
{ {
// THREAD_ASSERT( RT ); // THREAD_ASSERT( RT );
Control_Point *p2, *p1 = (Control_Point*)&_widgets.front(); Control_Point *p2, *p1 = (Control_Point*)_widgets.front();
nframes_t n = nframes; 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 ) i != _widgets.end(); ++i, p1 = p2 )
{ {
p2 = (Control_Point*)(*i); p2 = (Control_Point*)(*i);
if ( p2->when() < frame )
continue;
/* do incremental linear interpolation */
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();
float incr;
if ( interpolation() != None )
incr = ( y2 - y1 ) / (float)len;
else
incr = 0.0f;
float v = y1 + start * incr;
if ( ! n ) if ( ! n )
/* buffer's full, no point in continuing */ /* buffer's full, no point in continuing */
break; break;
if ( p2->when() < frame )
{
if ( p2 != _widgets.back() )
continue;
/* no more control points left, fill buffer with last value */
const float v = 1.0f - p2->control();
while ( n && n-- )
*(buf++) = v;
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;
for ( nframes_t i = start; i < len && n && n--; ++i, v += incr ) float incr;
*(buf++) = v;
if ( interpolation() != None )
incr = ( y2 - y1 ) / (float)len;
else
incr = 0.0f;
float v = y1 + start * incr;
for ( nframes_t i = start;
i < start + len && n && n--;
++i, v += incr )
*(buf++) = v;
}
} }
return nframes - n; return nframes - n;