Actually generate CV output for control sequences.

This commit is contained in:
Jonathan Moore Liles 2008-04-28 09:20:17 -05:00
parent 4af2a85cc7
commit a77e7a708c
5 changed files with 89 additions and 3 deletions

View File

@ -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 */ /* quick and dirty--let the regions figure out coverage for themselves */
for ( list <Sequence_Widget *>::const_iterator i = _widgets.begin(); for ( list <Sequence_Widget *>::const_iterator i = _widgets.begin();
i != _widgets.end(); i++ ) i != _widgets.end(); ++i )
{ {
const Region *r = (Region*)(*i); const Region *r = (Region*)(*i);

View File

@ -110,6 +110,9 @@ public:
float control ( void ) const { return _y; } float control ( void ) const { return _y; }
void control ( float v ) { _y = v; } void control ( float v ) { _y = v; }
/* only for playback thread */
nframes_t when ( void ) const { return _range.offset; }
int int
handle ( int m ) handle ( int m )

View File

@ -20,11 +20,14 @@
#include "Control_Sequence.H" #include "Control_Sequence.H"
#include "Track.H" #include "Track.H"
#include "Transport.H" // for transport->frame
bool Control_Sequence::draw_with_gradient = true; bool Control_Sequence::draw_with_gradient = true;
bool Control_Sequence::draw_with_polygon = true; bool Control_Sequence::draw_with_polygon = true;
bool Control_Sequence::draw_with_grid = 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(); init();
@ -267,3 +270,72 @@ Control_Sequence::handle ( int m )
return 0; 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 <Sequence_Widget *>::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 );
}

View File

@ -21,6 +21,7 @@
#include "Sequence.H" #include "Sequence.H"
#include "Control_Point.H" #include "Control_Point.H"
#include "Port.H"
class Control_Sequence : public Sequence class Control_Sequence : public Sequence
{ {
@ -29,13 +30,15 @@ class Control_Sequence : public Sequence
void init ( void ); void init ( void );
Port output;
protected: protected:
virtual void get ( Log_Entry &e ) const; virtual void get ( Log_Entry &e ) const;
void set ( Log_Entry &e ); void set ( Log_Entry &e );
Control_Sequence ( ) : Sequence( 0, 0, 0, 1 ) Control_Sequence ( ) : Sequence( 0, 0, 0, 1 ), output( "foo", Port::Output )
{ {
init(); init();
} }
@ -60,4 +63,9 @@ public:
void draw ( void ); void draw ( void );
int handle ( int m ); int handle ( int m );
/* Engine */
nframes_t play ( sample_t *buf, nframes_t frame, nframes_t nframes );
nframes_t process ( nframes_t nframes );
}; };

View File

@ -615,6 +615,9 @@ Track::configure_inputs ( int n )
nframes_t nframes_t
Track::process ( nframes_t nframes ) Track::process ( nframes_t nframes )
{ {
for ( int i = control->children(); i--; )
((Control_Sequence*)control->child( i ))->process( nframes );
if ( playback_ds ) if ( playback_ds )
{ {
record_ds->process( nframes ); record_ds->process( nframes );