diff --git a/Timeline/Audio_Sequence.C b/Timeline/Audio_Sequence.C index cf28fe8..69e56bb 100644 --- a/Timeline/Audio_Sequence.C +++ b/Timeline/Audio_Sequence.C @@ -131,7 +131,7 @@ Audio_Sequence::play ( sample_t *buf, nframes_t frame, nframes_t nframes, int ch /* quick and dirty--let the regions figure out coverage for themselves */ for ( list ::const_iterator i = _widgets.begin(); - i != _widgets.end(); i++ ) + i != _widgets.end(); ++i ) { const Region *r = (Region*)(*i); diff --git a/Timeline/Control_Point.H b/Timeline/Control_Point.H index 3ef484d..da0e267 100644 --- a/Timeline/Control_Point.H +++ b/Timeline/Control_Point.H @@ -110,6 +110,9 @@ public: float control ( void ) const { return _y; } void control ( float v ) { _y = v; } + /* only for playback thread */ + nframes_t when ( void ) const { return _range.offset; } + int handle ( int m ) diff --git a/Timeline/Control_Sequence.C b/Timeline/Control_Sequence.C index 6061a54..12befc3 100644 --- a/Timeline/Control_Sequence.C +++ b/Timeline/Control_Sequence.C @@ -20,11 +20,14 @@ #include "Control_Sequence.H" #include "Track.H" + +#include "Transport.H" // for transport->frame + bool Control_Sequence::draw_with_gradient = true; bool Control_Sequence::draw_with_polygon = true; bool Control_Sequence::draw_with_grid = true; -Control_Sequence::Control_Sequence ( Track *track ) : Sequence( 0, 0, 0, 0 ) +Control_Sequence::Control_Sequence ( Track *track ) : Sequence( 0, 0, 0, 0 ), output( "foo", Port::Output ) { init(); @@ -267,3 +270,72 @@ Control_Sequence::handle ( int m ) return 0; } } + + +/**********/ +/* Engine */ +/**********/ + + +static inline float +linear_interpolate ( float y1, float y2, float mu ) +{ + return y1 * (1 - mu) + y2 * mu; +} + +static inline float +sigmoid_interpolate ( float y1, float y2, float mu ) +{ + return linear_interpolate( y1, y2, ( 1 - cos( mu * M_PI ) ) / 2 ); +} + +/* static inline float */ +/* exponential_interpolate ( float y1, float y2, float mu ) */ +/* { */ + + +/* } */ + +/* THREAD: ?? */ +/** fill buf with /nframes/ of interpolated control curve values + * starting at /frame/ */ +nframes_t +Control_Sequence::play ( sample_t *buf, nframes_t frame, nframes_t nframes ) +{ + Control_Point *p2, *p1 = (Control_Point*)&_widgets.front(); + + nframes_t n = nframes; + + for ( list ::const_iterator i = _widgets.begin(); + i != _widgets.end(); ++i, p1 = p2 ) + { + p2 = (Control_Point*)(*i); + + if ( p2->when() < frame ) + continue; + + nframes_t d = p2->when() - p1->when(); + + for ( nframes_t i = frame - p1->when(); i < d; ++i ) + { + *(buf++) = 1.0f - ( 2 * sigmoid_interpolate( p1->control(), p2->control(), i / (float)d ) ); + + if ( ! n-- ) + return nframes; + + frame++; + } + } + + return frame; +} + + +/* THREAD: RT */ +nframes_t +Control_Sequence::process ( nframes_t nframes ) +{ + void *buf = output.buffer( nframes ); + + return play( (sample_t*)buf, transport->frame, nframes ); +} diff --git a/Timeline/Control_Sequence.H b/Timeline/Control_Sequence.H index a0033a7..e38f441 100644 --- a/Timeline/Control_Sequence.H +++ b/Timeline/Control_Sequence.H @@ -21,6 +21,7 @@ #include "Sequence.H" #include "Control_Point.H" +#include "Port.H" class Control_Sequence : public Sequence { @@ -29,13 +30,15 @@ class Control_Sequence : public Sequence void init ( void ); + Port output; + protected: virtual void get ( Log_Entry &e ) const; void set ( Log_Entry &e ); - Control_Sequence ( ) : Sequence( 0, 0, 0, 1 ) + Control_Sequence ( ) : Sequence( 0, 0, 0, 1 ), output( "foo", Port::Output ) { init(); } @@ -60,4 +63,9 @@ public: void draw ( void ); int handle ( int m ); + + /* Engine */ + nframes_t play ( sample_t *buf, nframes_t frame, nframes_t nframes ); + nframes_t process ( nframes_t nframes ); + }; diff --git a/Timeline/Track.C b/Timeline/Track.C index 9f09185..fdf3e38 100644 --- a/Timeline/Track.C +++ b/Timeline/Track.C @@ -615,6 +615,9 @@ Track::configure_inputs ( int n ) nframes_t Track::process ( nframes_t nframes ) { + for ( int i = control->children(); i--; ) + ((Control_Sequence*)control->child( i ))->process( nframes ); + if ( playback_ds ) { record_ds->process( nframes );