Optimize fade calculations.
This commit is contained in:
parent
14330f607d
commit
fc2ed291aa
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue