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

@ -636,6 +636,8 @@ Control_Sequence::process_osc ( void )
{
sample_t buf[1];
*buf = 0;
play( buf, (nframes_t)transport->frame, (nframes_t) 1 );
_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 );
Control_Point *p2, *p1 = (Control_Point*)&_widgets.front();
Control_Point *p2, *p1 = (Control_Point*)_widgets.front();
nframes_t n = nframes;
@ -65,33 +65,52 @@ Control_Sequence::play ( sample_t *buf, nframes_t frame, nframes_t nframes )
{
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 )
/* buffer's full, no point in continuing */
break;
for ( nframes_t i = start; i < len && n && n--; ++i, v += incr )
*(buf++) = v;
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;
float incr;
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;