From fc2ed291aa8c4398fd3842854443d8a8df58d3e5 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Wed, 16 Apr 2008 00:50:32 -0500 Subject: [PATCH] Optimize fade calculations. --- Timeline/Region.C | 56 ++++++++++++++++++++++++++++++----------------- Timeline/Region.H | 29 ++++++++++-------------- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/Timeline/Region.C b/Timeline/Region.C index 47ce61e..1ca6fa9 100644 --- a/Timeline/Region.C +++ b/Timeline/Region.C @@ -482,8 +482,8 @@ changed: /** Draws the curve for a single fade. /X/ and /W/ repersent the - portion of the region covered by this draw, which may or may not - cover the fade in question. */ + portion of the region covered by this draw, which may or may not + cover the fade in question. */ void Region::draw_fade ( const Fade &fade, Fade::fade_dir_e dir, bool line, int X, int W ) { @@ -515,10 +515,16 @@ Region::draw_fade ( const Fade &fade, Fade::fade_dir_e dir, bool line, int X, in fl_vertex( 0.0, 0.0 ); fl_vertex( 0.0, 1.0 ); - nframes_t tsx = timeline->x_to_ts( 1 ); - nframes_t ts = 0; - for ( int i = 0; i < width; ++i, ts += tsx ) - fl_vertex( i / (float)width, 1.0f - fade.gain( ts ) ); + +// if ( draw_real_fade_curve ) + { + nframes_t tsx = timeline->x_to_ts( 1 ); + nframes_t ts = 0; + + for ( int i = 0; i < width; ++i, ts += tsx ) + fl_vertex( i / (float)width, 1.0f - fade.gain( ts / (float)fade.length ) ); + + } fl_vertex( 1.0, 0.0 ); @@ -695,17 +701,27 @@ Region::normalize ( void ) void Region::Fade::apply ( sample_t *buf, Region::Fade::fade_dir_e dir, long start, nframes_t end, nframes_t nframes ) const { - 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 == Fade::Out ? "out" : "in", start, end ); - nframes_t i = start > 0 ? start : 0; - nframes_t e = end > nframes ? nframes : end; + const nframes_t i = start > 0 ? start : 0; + const nframes_t e = end > nframes ? nframes : end; + + const float inc = increment(); + float fi = ( i - start ) / (float)length; + + buf += i; + + nframes_t n = e - i; if ( dir == Fade::Out ) - for ( ; i < e; ++i ) - buf[ i ] *= gain( (length - 1) - (i - start) ); + { + fi = 1.0f - fi; + for ( ; n--; fi -= inc ) + *(buf++) *= gain( fi ); + } else - for ( ; i < e; ++i ) - buf[ i ] *= gain( i - start ); + for ( ; n--; fi += inc ) + *(buf++) *= gain( fi ); } @@ -793,13 +809,13 @@ float gain_on_curve ( int type, int dir, nframes_t nframes, nframes_t offset, nf this region into /buf/, where /pos/ is in timeline frames */ /* this runs in the diskstream thread. */ /* FIXME: it is far more efficient to read all the channels from a - multichannel source at once... But how should we handle the case of a - mismatch between the number of channels in this region's source and - the number of channels on the track/buffer this data is being read - for? Would it not be better to simply buffer and deinterlace the - frames in the Audio_File class instead, so that sequential requests - for different channels at the same position avoid hitting the disk - again? */ + multichannel source at once... But how should we handle the case of a + mismatch between the number of channels in this region's source and + the number of channels on the track/buffer this data is being read + for? Would it not be better to simply buffer and deinterlace the + frames in the Audio_File class instead, so that sequential requests + for different channels at the same position avoid hitting the disk + again? */ nframes_t Region::read ( sample_t *buf, nframes_t pos, nframes_t nframes, int channel ) const { diff --git a/Timeline/Region.H b/Timeline/Region.H index a92f300..4b5e4bf 100644 --- a/Timeline/Region.H +++ b/Timeline/Region.H @@ -59,38 +59,31 @@ public: return length < rhs.length; } + float increment ( void ) const + { + return 1.0f / (float)length; + } + /** 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. */ inline float - gain ( nframes_t index ) const + gain ( const float fi ) const { - float g; - - const float fi = index / (float)length; - switch ( type ) { case Linear: - g = fi; - break; + return fi; case Sigmoid: - g = (1.0f - cos( fi * M_PI )) / 2.0f; - break; + return (1.0f - cos( fi * M_PI )) / 2.0f; case Logarithmic: - /* FIXME: this is wrong */ - g = pow( 0.1f, (1.0f - fi) * 3.0f ); - break; + return pow( 0.1f, (1.0f - fi) * 3.0f ); case Parabolic: - g = 1.0f - (1.0f - fi) * (1.0f - fi); - break; + return 1.0f - (1.0f - fi) * (1.0f - fi); default: - g = 1.0f; + return 1.0f; } - - return g; - } void apply ( sample_t *buf, fade_dir_e dir, long start, nframes_t end, nframes_t nframes ) const;