| @@ -319,7 +319,7 @@ Control_Sequence::handle ( int m ) | |||||
| static inline float | static inline float | ||||
| linear_interpolate ( float y1, float y2, float mu ) | linear_interpolate ( float y1, float y2, float mu ) | ||||
| { | { | ||||
| return y1 * (1 - mu) + y2 * mu; | |||||
| return y1 + mu * ( y2 - y1 ); | |||||
| } | } | ||||
| static inline float | static inline float | ||||
| @@ -328,11 +328,21 @@ sigmoid_interpolate ( float y1, float y2, float mu ) | |||||
| return linear_interpolate( y1, y2, ( 1 - cos( mu * M_PI ) ) / 2 ); | return linear_interpolate( y1, y2, ( 1 - cos( mu * M_PI ) ) / 2 ); | ||||
| } | } | ||||
| static inline float | |||||
| quadratic_interpolate ( float y1, float y2, float mu ) | |||||
| { | |||||
| return ( y1 * y1 ) * ( mu * mu ) + ( 2.0f * y1 * y2 ) * mu * ( y1 * y1 ); | |||||
| } | |||||
| /* static inline float */ | /* static inline float */ | ||||
| /* exponential_interpolate ( float y1, float y2, float mu ) */ | |||||
| /* quadratic_interpolate ( float y1, float y2, float mu ) */ | |||||
| /* { */ | /* { */ | ||||
| /* } */ | |||||
| /* static inline float */ | |||||
| /* exponential_interpolate ( float y1, float y2, float mu ) */ | |||||
| /* { */ | |||||
| /* // return y1 * pow( y2 / y1, mu ); */ | |||||
| /* } */ | /* } */ | ||||
| /* THREAD: ?? */ | /* THREAD: ?? */ | ||||
| @@ -357,7 +367,9 @@ Control_Sequence::play ( sample_t *buf, nframes_t frame, nframes_t nframes ) | |||||
| for ( nframes_t i = frame - p1->when(); i < d; ++i ) | for ( nframes_t i = frame - p1->when(); i < d; ++i ) | ||||
| { | { | ||||
| *(buf++) = 1.0f - ( 2 * sigmoid_interpolate( p1->control(), p2->control(), i / (float)d ) ); | |||||
| // *(buf++) = 1.0f - ( 2 * sigmoid_interpolate( p1->control(), p2->control(), i / (float)d ) ); | |||||
| *(buf++) = 1.0f - ( 2 * linear_interpolate( p1->control(), p2->control(), i / (float)d ) ); | |||||
| // *(buf++) = 1.0f - ( 2 * quadratic_interpolate( p1->control(), p2->control(), i / (float)d ) ); | |||||
| if ( ! n-- ) | if ( ! n-- ) | ||||
| return nframes; | return nframes; | ||||
| @@ -25,11 +25,18 @@ | |||||
| class Control_Sequence : public Sequence | class Control_Sequence : public Sequence | ||||
| { | { | ||||
| public: | |||||
| enum curve_type_e { Linear, Quadratic }; | |||||
| private: | |||||
| Port *_output; | Port *_output; | ||||
| bool _highlighted; | bool _highlighted; | ||||
| curve_type_e _type; | |||||
| void init ( void ); | void init ( void ); | ||||
| @@ -766,86 +766,6 @@ Region::Fade::apply ( sample_t *buf, Region::Fade::fade_dir_e dir, long start, n | |||||
| *(buf++) *= gain( fi ); | *(buf++) *= gain( fi ); | ||||
| } | } | ||||
| #if 0 | |||||
| /** Compute the gain value (0 to 1f) for a fade-in/out curve of /type/ | |||||
| * (LINEAR, QUADRAIC, CUBIC), of /nframes/ in length at point | |||||
| * /offset/ */ | |||||
| static inline | |||||
| float gain_on_curve ( int type, int dir, nframes_t nframes, nframes_t offset, nframes_t length ) | |||||
| { | |||||
| float a, b; | |||||
| /* FIXME: these first two sections should *definitely* be cached */ | |||||
| /* calculate coefficients */ | |||||
| if ( dir == FADE_OUT ) | |||||
| { | |||||
| a = -1.0f / (double)nframes; | |||||
| /* fixme why would we need to know the clip length? */ | |||||
| b = length / (double)nframes; | |||||
| // b = nframes; | |||||
| } | |||||
| else | |||||
| { | |||||
| a = 1.0f / (double)nframes; | |||||
| b = 0.0f; | |||||
| } | |||||
| float c[4]; | |||||
| /* interpolate points */ | |||||
| switch ( type ) | |||||
| { | |||||
| case Linear: | |||||
| c[1] = a; | |||||
| c[0] = b; | |||||
| break; | |||||
| case Quadratic: | |||||
| c[2] = a * a; | |||||
| c[1] = 2.0f * a * b; | |||||
| c[0] = b * b; | |||||
| break; | |||||
| case Cubic: | |||||
| { | |||||
| const float a2 = a * a; | |||||
| const float b2 = b * b; | |||||
| c[3] = a * a2; | |||||
| c[2] = 3.0f * a2 * b; | |||||
| c[1] = 3.0f * a * b2; | |||||
| c[0] = b * b2; | |||||
| break; | |||||
| } | |||||
| default: | |||||
| printf( "unknown curve order\n" ); | |||||
| } | |||||
| /* now get the gain for the given point */ | |||||
| const float f = offset; | |||||
| const float f2 = f * f; | |||||
| float g = 1.0f; | |||||
| switch ( type ) | |||||
| { | |||||
| case Linear: | |||||
| g *= c[1] * f + c[0]; | |||||
| break; | |||||
| case Quadratic: | |||||
| g *= c[2] * f2 + c[1] * f + c[0]; | |||||
| break; | |||||
| case Cubic: | |||||
| g *= c[3] * f2 * f + c[2] * f2 + c[1] * f + c[0]; | |||||
| break; | |||||
| } | |||||
| printf( "gain for %lu is %f\n", offset, g ); | |||||
| return g; | |||||
| } | |||||
| #endif | |||||
| /* THREAD: IO */ | /* THREAD: IO */ | ||||
| /** read the overlapping part of /channel/ at /pos/ for /nframes/ of | /** read the overlapping part of /channel/ at /pos/ for /nframes/ of | ||||
| this region into /buf/, where /pos/ is in timeline frames */ | this region into /buf/, where /pos/ is in timeline frames */ | ||||