Timeline: Add interpolation mode choice of Linear and None to Control Sequences.
This commit is contained in:
parent
5aff30fef6
commit
b82774dcf3
|
@ -67,6 +67,8 @@ Control_Sequence::Control_Sequence ( Track *track ) : Sequence( 0 )
|
||||||
if ( track )
|
if ( track )
|
||||||
track->add( this );
|
track->add( this );
|
||||||
|
|
||||||
|
interpolation( Linear );
|
||||||
|
|
||||||
log_create();
|
log_create();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -74,6 +76,7 @@ Control_Sequence::Control_Sequence ( Track *track ) : Sequence( 0 )
|
||||||
|
|
||||||
Control_Sequence::~Control_Sequence ( )
|
Control_Sequence::~Control_Sequence ( )
|
||||||
{
|
{
|
||||||
|
Fl::remove_timeout( &Control_Sequence::process_osc, this );
|
||||||
|
|
||||||
Loggable::block_start();
|
Loggable::block_start();
|
||||||
|
|
||||||
|
@ -117,6 +120,12 @@ Control_Sequence::get ( Log_Entry &e ) const
|
||||||
e.add( ":name", name() );
|
e.add( ":name", name() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control_Sequence::get_unjournaled ( Log_Entry &e ) const
|
||||||
|
{
|
||||||
|
e.add( ":interpolation", _interpolation );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Control_Sequence::set ( Log_Entry &e )
|
Control_Sequence::set ( Log_Entry &e )
|
||||||
{
|
{
|
||||||
|
@ -145,6 +154,8 @@ Control_Sequence::set ( Log_Entry &e )
|
||||||
}
|
}
|
||||||
else if ( ! strcmp( ":name", s ) )
|
else if ( ! strcmp( ":name", s ) )
|
||||||
name( v );
|
name( v );
|
||||||
|
else if ( ! strcmp( ":interpolation", s ) )
|
||||||
|
interpolation( (curve_type_e)atoi( v ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,7 +218,6 @@ Control_Sequence::draw_curve ( bool flip, bool filled )
|
||||||
void
|
void
|
||||||
Control_Sequence::draw ( void )
|
Control_Sequence::draw ( void )
|
||||||
{
|
{
|
||||||
|
|
||||||
if ( ! fl_not_clipped( x(), y(), w(), h() ) )
|
if ( ! fl_not_clipped( x(), y(), w(), h() ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -230,64 +240,67 @@ Control_Sequence::draw ( void )
|
||||||
const Fl_Color color = active ? this->color() : fl_inactive( this->color() );
|
const Fl_Color color = active ? this->color() : fl_inactive( this->color() );
|
||||||
const Fl_Color selection_color = active ? this->selection_color() : fl_inactive( this->selection_color() );
|
const Fl_Color selection_color = active ? this->selection_color() : fl_inactive( this->selection_color() );
|
||||||
|
|
||||||
if ( draw_with_gradient )
|
|
||||||
{
|
if ( draw_with_gradient )
|
||||||
|
{
|
||||||
/* const Fl_Color c2 = fl_color_average( selection_color, FL_WHITE, 0.90f ); */
|
/* const Fl_Color c2 = fl_color_average( selection_color, FL_WHITE, 0.90f ); */
|
||||||
/* const Fl_Color c1 = fl_color_average( color, c2, 0.60f ); */
|
/* const Fl_Color c1 = fl_color_average( color, c2, 0.60f ); */
|
||||||
|
|
||||||
const Fl_Color c1 = fl_color_average( selection_color, FL_WHITE, 0.90f );
|
const Fl_Color c1 = fl_color_average( selection_color, FL_WHITE, 0.90f );
|
||||||
const Fl_Color c2 = fl_color_average( color, c1, 0.60f );
|
const Fl_Color c2 = fl_color_average( color, c1, 0.60f );
|
||||||
|
|
||||||
for ( int gy = 0; gy < bh; gy++ )
|
for ( int gy = 0; gy < bh; gy++ )
|
||||||
{
|
{
|
||||||
fl_color( fl_color_average( c1, c2, gy / (float)bh) );
|
fl_color( fl_color_average( c1, c2, gy / (float)bh) );
|
||||||
fl_line( X, by + gy, X + W, by + gy );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( draw_with_grid )
|
|
||||||
{
|
|
||||||
fl_color( fl_darker( color ) );
|
|
||||||
|
|
||||||
const int inc = bh / 10;
|
|
||||||
if ( inc )
|
|
||||||
for ( int gy = 0; gy < bh; gy += inc )
|
|
||||||
fl_line( X, by + gy, X + W, by + gy );
|
fl_line( X, by + gy, X + W, by + gy );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
if ( draw_with_grid )
|
||||||
|
{
|
||||||
|
fl_color( fl_darker( color ) );
|
||||||
|
|
||||||
|
const int inc = bh / 10;
|
||||||
|
if ( inc )
|
||||||
|
for ( int gy = 0; gy < bh; gy += inc )
|
||||||
|
fl_line( X, by + gy, X + W, by + gy );
|
||||||
|
|
||||||
if ( draw_with_polygon )
|
}
|
||||||
|
|
||||||
|
if ( interpolation() != None )
|
||||||
{
|
{
|
||||||
fl_color( draw_with_gradient ? color : fl_color_average( color, selection_color, 0.45f ) );
|
if ( draw_with_polygon )
|
||||||
|
{
|
||||||
|
fl_color( draw_with_gradient ? color : fl_color_average( color, selection_color, 0.45f ) );
|
||||||
|
|
||||||
fl_begin_complex_polygon();
|
fl_begin_complex_polygon();
|
||||||
draw_curve( draw_with_gradient, true );
|
draw_curve( draw_with_gradient, true );
|
||||||
fl_end_complex_polygon();
|
fl_end_complex_polygon();
|
||||||
|
|
||||||
fl_color( selection_color );
|
fl_color( selection_color );
|
||||||
fl_line_style( FL_SOLID, 2 );
|
fl_line_style( FL_SOLID, 2 );
|
||||||
|
|
||||||
fl_begin_line();
|
fl_begin_line();
|
||||||
draw_curve( draw_with_gradient, false );
|
draw_curve( draw_with_gradient, false );
|
||||||
fl_end_line();
|
fl_end_line();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// fl_color( fl_color_average( selection_color, color, 0.70f ) );
|
// fl_color( fl_color_average( selection_color, color, 0.70f ) );
|
||||||
fl_color( selection_color );
|
fl_color( selection_color );
|
||||||
fl_line_style( FL_SOLID, 2 );
|
fl_line_style( FL_SOLID, 2 );
|
||||||
|
|
||||||
fl_begin_line();
|
fl_begin_line();
|
||||||
draw_curve( draw_with_gradient, false );
|
draw_curve( draw_with_gradient, false );
|
||||||
fl_end_line();
|
fl_end_line();
|
||||||
|
}
|
||||||
|
|
||||||
|
fl_line_style( FL_SOLID, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
fl_line_style( FL_SOLID, 0 );
|
|
||||||
|
|
||||||
timeline->draw_measure_lines( x(), y(), w(), h(), color );
|
timeline->draw_measure_lines( x(), y(), w(), h(), color );
|
||||||
|
|
||||||
if ( _highlighted || Fl::focus() == this )
|
if ( interpolation() == None || _highlighted || Fl::focus() == this )
|
||||||
for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ )
|
for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ )
|
||||||
(*r)->draw_box();
|
(*r)->draw_box();
|
||||||
else
|
else
|
||||||
|
@ -316,27 +329,44 @@ Control_Sequence::menu_cb ( const Fl_Menu_ *m )
|
||||||
|
|
||||||
m->item_pathname( picked, sizeof( picked ), m->mvalue() );
|
m->item_pathname( picked, sizeof( picked ), m->mvalue() );
|
||||||
|
|
||||||
// DMESSAGE( "Picked: %s (%s)", picked, m->mvalue()->label() );
|
if ( ! strncmp( picked, "Connect To/", strlen( "Connect To/" ) ) )
|
||||||
|
{
|
||||||
|
if ( ! _osc_output )
|
||||||
if ( ! _osc_output )
|
{
|
||||||
{
|
char *path;
|
||||||
char *path;
|
asprintf( &path, "/non/daw/%s/control/%i", track()->name(), track()->ncontrols() );
|
||||||
asprintf( &path, "/non/daw/%s/control/%i", track()->name(), track()->ncontrols() );
|
|
||||||
|
|
||||||
_osc_output = timeline->osc->add_signal( path, OSC::Signal::Output, NULL, NULL );
|
_osc_output = timeline->osc->add_signal( path, OSC::Signal::Output, NULL, NULL );
|
||||||
|
|
||||||
free( path );
|
free( path );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: somebody has to free these unsigned longs */
|
/* FIXME: somebody has to free these unsigned longs */
|
||||||
unsigned long id = *(unsigned long*)m->mvalue()->user_data();
|
unsigned long id = *(unsigned long*)m->mvalue()->user_data();
|
||||||
|
|
||||||
char *peer_name = index( picked, '/' ) + 1;
|
char *peer_name = index( picked, '/' ) + 1;
|
||||||
|
|
||||||
*index( peer_name, '/' ) = 0;
|
*index( peer_name, '/' ) = 0;
|
||||||
|
|
||||||
timeline->osc->connect_signal( _osc_output, peer_name, id );
|
timeline->osc->connect_signal( _osc_output, peer_name, id );
|
||||||
|
}
|
||||||
|
else if ( ! strcmp( picked, "Interpolation/Linear" ) )
|
||||||
|
interpolation( Linear );
|
||||||
|
else if ( ! strcmp( picked, "Interpolation/None" ) )
|
||||||
|
interpolation( None );
|
||||||
|
else if ( ! strcmp( picked, "/Rename" ) )
|
||||||
|
{
|
||||||
|
const char *s = fl_input( "Input new name for control sequence:", name() );
|
||||||
|
|
||||||
|
if ( s )
|
||||||
|
name( s );
|
||||||
|
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
else if ( !strcmp( picked, "/Remove" ) )
|
||||||
|
{
|
||||||
|
Fl::delete_widget( this );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -354,9 +384,8 @@ Control_Sequence::process_osc ( void )
|
||||||
if ( _osc_output && _osc_output->connected() )
|
if ( _osc_output && _osc_output->connected() )
|
||||||
{
|
{
|
||||||
sample_t buf[1];
|
sample_t buf[1];
|
||||||
|
|
||||||
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] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,42 +441,15 @@ Control_Sequence::handle ( int m )
|
||||||
|
|
||||||
/* menu.add( "Connect To", 0, 0, 0); */
|
/* menu.add( "Connect To", 0, 0, 0); */
|
||||||
/* menu.add( "Connect To", 0, 0, const_cast< Fl_Menu_Item *>( con->menu() ), FL_SUBMENU_POINTER ); */
|
/* menu.add( "Connect To", 0, 0, const_cast< Fl_Menu_Item *>( con->menu() ), FL_SUBMENU_POINTER ); */
|
||||||
|
menu.add( "Interpolation/None", 0, 0, 0, FL_MENU_RADIO | ( interpolation() == None ? FL_MENU_VALUE : 0 ) );
|
||||||
|
menu.add( "Interpolation/Linear", 0, 0, 0, FL_MENU_RADIO | ( interpolation() == Linear ? FL_MENU_VALUE : 0 ) );
|
||||||
menu.add( "Rename", 0, 0, 0 );
|
menu.add( "Rename", 0, 0, 0 );
|
||||||
menu.add( "Remove", 0, 0, 0 );
|
menu.add( "Remove", 0, 0, 0 );
|
||||||
|
|
||||||
|
|
||||||
menu.callback( &Control_Sequence::menu_cb, (void*)this);
|
menu.callback( &Control_Sequence::menu_cb, (void*)this);
|
||||||
/* Fl_Menu_Item menu[] = */
|
|
||||||
/* { */
|
|
||||||
/* { "Rename" }, */
|
|
||||||
/* { "Remove" }, */
|
|
||||||
/* { "Connect To" }, */
|
|
||||||
|
|
||||||
/* { 0 } */
|
|
||||||
/* }; */
|
|
||||||
|
|
||||||
menu_popup( &menu, x(), y() );
|
menu_popup( &menu, x(), y() );
|
||||||
|
|
||||||
// const Fl_Menu_Item *r = menu.popup( Fl::event_x(), Fl::event_y(), "Control Sequence" );
|
|
||||||
|
|
||||||
/* if ( r ) */
|
|
||||||
/* { */
|
|
||||||
/* if ( r == &menu[ 0 ] ) */
|
|
||||||
/* { */
|
|
||||||
/* const char *s = fl_input( "Input new name for control sequence:", name() ); */
|
|
||||||
|
|
||||||
/* if ( s ) */
|
|
||||||
/* name( s ); */
|
|
||||||
|
|
||||||
/* redraw(); */
|
|
||||||
/* } */
|
|
||||||
/* else if ( r == &menu[ 1 ] ) */
|
|
||||||
/* { */
|
|
||||||
/* Fl::delete_widget( this ); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ class Control_Sequence : public Sequence
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum curve_type_e { Linear, Quadratic };
|
enum curve_type_e { None, Linear, Quadratic };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ private:
|
||||||
|
|
||||||
bool _highlighted;
|
bool _highlighted;
|
||||||
|
|
||||||
curve_type_e _type;
|
curve_type_e _interpolation;
|
||||||
|
|
||||||
void init ( void );
|
void init ( void );
|
||||||
|
|
||||||
|
@ -58,11 +58,13 @@ private:
|
||||||
static void process_osc ( void *v );
|
static void process_osc ( void *v );
|
||||||
void process_osc ( void );
|
void process_osc ( void );
|
||||||
|
|
||||||
|
float _rate;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
virtual void get ( Log_Entry &e ) const;
|
virtual void get ( Log_Entry &e ) const;
|
||||||
|
virtual void get_unjournaled ( Log_Entry &e ) const;
|
||||||
void set ( Log_Entry &e );
|
void set ( Log_Entry &e );
|
||||||
|
|
||||||
Control_Sequence ( ) : Sequence( 0 )
|
Control_Sequence ( ) : Sequence( 0 )
|
||||||
|
@ -87,6 +89,9 @@ public:
|
||||||
|
|
||||||
Fl_Cursor cursor ( void ) const { return FL_CURSOR_CROSS; }
|
Fl_Cursor cursor ( void ) const { return FL_CURSOR_CROSS; }
|
||||||
|
|
||||||
|
curve_type_e interpolation ( void ) const { return _interpolation; }
|
||||||
|
void interpolation ( curve_type_e v ) { _interpolation = v; }
|
||||||
|
|
||||||
/* Engine */
|
/* Engine */
|
||||||
void output ( JACK::Port *p ) { _output = p; }
|
void output ( JACK::Port *p ) { _output = p; }
|
||||||
nframes_t play ( sample_t *buf, nframes_t frame, nframes_t nframes );
|
nframes_t play ( sample_t *buf, nframes_t frame, nframes_t nframes );
|
||||||
|
|
|
@ -71,18 +71,23 @@ Control_Sequence::play ( sample_t *buf, nframes_t frame, nframes_t nframes )
|
||||||
/* do incremental linear interpolation */
|
/* do incremental linear interpolation */
|
||||||
|
|
||||||
const nframes_t len = p2->when() - p1->when();
|
const nframes_t len = p2->when() - p1->when();
|
||||||
|
|
||||||
const float y1 = 1.0f - p1->control();
|
const float y1 = 1.0f - p1->control();
|
||||||
const float y2 = 1.0f - p2->control();
|
const float y2 = 1.0f - p2->control();
|
||||||
|
|
||||||
const nframes_t start = frame - p1->when();
|
const nframes_t start = frame - p1->when();
|
||||||
const float incr = ( y2 - y1 ) / (float)len;
|
|
||||||
|
float incr;
|
||||||
|
|
||||||
|
if ( interpolation() != None )
|
||||||
|
incr = ( y2 - y1 ) / (float)len;
|
||||||
|
else
|
||||||
|
incr = 0.0f;
|
||||||
|
|
||||||
float v = y1 + start * incr;
|
float v = y1 + start * incr;
|
||||||
|
|
||||||
for ( nframes_t i = start; i < len && n--; ++i, v += incr )
|
for ( nframes_t i = start; i < len && n--; ++i, v += incr )
|
||||||
*(buf++) = v;
|
*(buf++) = v;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nframes - n;
|
return nframes - n;
|
||||||
|
|
Loading…
Reference in New Issue