diff --git a/Timeline/Region.C b/Timeline/Region.C index e762d3e..aaf7568 100644 --- a/Timeline/Region.C +++ b/Timeline/Region.C @@ -539,14 +539,11 @@ Region::normalize ( void ) /**********/ -enum fade_type_e { Linear, Cosine, Logarithmic, Parabolic }; -enum fade_dir_e { FADE_IN, FADE_OUT }; - /** Return gain for frame /index/ of /nframes/ on a gain curve of type /type/.*/ /* FIXME: calling a function per sample is bad, switching on type mid * fade is bad. */ static inline float -fade_gain ( fade_type_e type, nframes_t index, nframes_t nframes ) +fade_gain ( Region::fade_type_e type, nframes_t index, nframes_t nframes ) { float g = 0; @@ -554,17 +551,17 @@ fade_gain ( fade_type_e type, nframes_t index, nframes_t nframes ) switch ( type ) { - case Linear: + case Region::Linear: g = fi; break; - case Cosine: + case Region::Cosine: // g = sin( fi * M_PI / 2 ); g = (1.0f - cos( fi * M_PI )) / 2.0f; break; - case Logarithmic: + case Region::Logarithmic: g = pow( 0.1f, (1.0f - fi) * 5.0f ); break; - case Parabolic: + case Region::Parabolic: g = 1.0f - (1.0f - fi) * (1.0f - fi); break; } @@ -577,25 +574,21 @@ fade_gain ( fade_type_e type, nframes_t index, nframes_t nframes ) * buffer size of /nframes/. /start/ and /end/ are relative to the * given buffer, and /start/ may be negative. */ static void -apply_fade ( sample_t *buf, fade_dir_e dir, fade_type_e type, long start, nframes_t end, nframes_t nframes ) +apply_fade ( sample_t *buf, Region::fade_dir_e dir, Region::fade_type_e type, long start, nframes_t end, nframes_t nframes ) { - float gain = 1.0f; - - printf( "apply fade %s: start=%ld end=%lu\n", dir == FADE_OUT ? "out" : "in", start, end ); + printf( "apply fade %s: start=%ld end=%lu\n", dir == Region::FADE_OUT ? "out" : "in", start, end ); nframes_t i = start > 0 ? start : 0; nframes_t e = end > nframes ? nframes : end; - float d = dir == FADE_OUT ? 1.0f : -1.0f; - - if ( dir == FADE_OUT ) + if ( dir == Region::FADE_OUT ) for ( ; i < e; ++i ) { long n = end - start; const float g = fade_gain( type, (n - 1) - (i - start), n); - printf( "gain for %lu is %f\n", i, g ); +// printf( "gain for %lu is %f\n", i, g ); buf[ i ] *= g; } else @@ -603,7 +596,7 @@ apply_fade ( sample_t *buf, fade_dir_e dir, fade_type_e type, long start, nframe { const float g = fade_gain( type, i - start, end - start ); - printf( "gain for %lu is %f\n", i, g ); +// printf( "gain for %lu is %f\n", i, g ); buf[ i ] *= g; } } @@ -756,30 +749,37 @@ Region::read ( sample_t *buf, nframes_t pos, nframes_t nframes, int channel ) co for ( int i = cnt; i--; ) buf[i] *= _scale; - /* TODO: do fade in/out here */ - /* perform declicking if necessary */ - /* FIXME: shouldn't this be wallclock time? */ - const nframes_t declick_frames = 256; - const fade_type_e type = Linear; + /* FIXME: keep the declick defults someplace else */ + Fade declick; + + declick.length = 256; + declick.type = Linear; - if ( start + cnt + declick_frames > r.end ) { - /* declick end */ - const nframes_t d = r.end - start; + Fade fade; - apply_fade( buf, FADE_OUT, type , cnt + (long)d - declick_frames, cnt + d, cnt ); - } + fade = declick < _fade_in ? _fade_in : declick; - if ( sofs < declick_frames ) - { - /* declick start */ - const long d = 0 - sofs; + /* do fade in if necessary */ + if ( sofs < fade.length ) + { + const long d = 0 - sofs; - apply_fade( buf + ofs, FADE_IN, type, d, d + declick_frames, cnt - ofs ); - } + apply_fade( buf + ofs, FADE_IN, fade.type, d, d + fade.length, cnt - ofs ); + } + + fade = declick < _fade_out ? _fade_out : declick; + /* do fade out if necessary */ + if ( start + cnt + fade.length > r.end ) + { + const nframes_t d = r.end - start; + + apply_fade( buf, FADE_OUT, fade.type, cnt + (long)d - fade.length, cnt + d, cnt ); + } + } // printf( "read %lu frames\n", cnt ); return cnt; diff --git a/Timeline/Region.H b/Timeline/Region.H index a820097..14956da 100644 --- a/Timeline/Region.H +++ b/Timeline/Region.H @@ -36,12 +36,38 @@ class Region; class Region_Base : public Track_Widget { +public: + + enum fade_type_e { Linear, Cosine, Logarithmic, Parabolic }; + enum fade_dir_e { FADE_IN, FADE_OUT }; + + struct Fade + { + fade_type_e type; + nframes_t length; + + Fade ( ) + { + type = Linear; + length = 0; + } + + bool + operator< ( const Fade &rhs ) + { + return length < rhs.length; + } + }; + private: Audio_File *_clip; /* clip this region represents */ float _scale; /* amplitude adjustment */ + Fade _fade_in; + Fade _fade_out; + protected: const char *class_name ( void ) { return "Region"; } @@ -174,6 +200,7 @@ class Region : public Region_Base public: + static Loggable * create ( char **sa ) {