Prepare to support generalized fade-in/outs.
This commit is contained in:
parent
ee576b7ff7
commit
91abbf543d
|
@ -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;
|
||||
|
||||
/* do fade in if necessary */
|
||||
if ( sofs < fade.length )
|
||||
{
|
||||
const long d = 0 - sofs;
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( sofs < declick_frames )
|
||||
{
|
||||
/* declick start */
|
||||
const long d = 0 - sofs;
|
||||
|
||||
apply_fade( buf + ofs, FADE_IN, type, d, d + declick_frames, cnt - ofs );
|
||||
}
|
||||
|
||||
// printf( "read %lu frames\n", cnt );
|
||||
|
||||
return cnt;
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue