Browse Source

Prepare to support generalized fade-in/outs.

tags/non-daw-v1.1.0
Jonathan Moore Liles 17 years ago
parent
commit
91abbf543d
2 changed files with 60 additions and 33 deletions
  1. +33
    -33
      Timeline/Region.C
  2. +27
    -0
      Timeline/Region.H

+ 33
- 33
Timeline/Region.C View File

@@ -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/.*/ /** 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 /* FIXME: calling a function per sample is bad, switching on type mid
* fade is bad. */ * fade is bad. */
static inline float 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; float g = 0;


@@ -554,17 +551,17 @@ fade_gain ( fade_type_e type, nframes_t index, nframes_t nframes )


switch ( type ) switch ( type )
{ {
case Linear:
case Region::Linear:
g = fi; g = fi;
break; break;
case Cosine:
case Region::Cosine:
// g = sin( fi * M_PI / 2 ); // g = sin( fi * M_PI / 2 );
g = (1.0f - cos( fi * M_PI )) / 2.0f; g = (1.0f - cos( fi * M_PI )) / 2.0f;
break; break;
case Logarithmic:
case Region::Logarithmic:
g = pow( 0.1f, (1.0f - fi) * 5.0f ); g = pow( 0.1f, (1.0f - fi) * 5.0f );
break; break;
case Parabolic:
case Region::Parabolic:
g = 1.0f - (1.0f - fi) * (1.0f - fi); g = 1.0f - (1.0f - fi) * (1.0f - fi);
break; 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 * buffer size of /nframes/. /start/ and /end/ are relative to the
* given buffer, and /start/ may be negative. */ * given buffer, and /start/ may be negative. */
static void 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 i = start > 0 ? start : 0;
nframes_t e = end > nframes ? nframes : end; 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 ) for ( ; i < e; ++i )
{ {
long n = end - start; long n = end - start;


const float g = fade_gain( type, (n - 1) - (i - start), n); 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; buf[ i ] *= g;
} }
else 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 ); 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; 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--; ) for ( int i = cnt; i--; )
buf[i] *= _scale; buf[i] *= _scale;


/* TODO: do fade in/out here */

/* perform declicking if necessary */ /* 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 ); // printf( "read %lu frames\n", cnt );


return cnt; return cnt;


+ 27
- 0
Timeline/Region.H View File

@@ -36,12 +36,38 @@ class Region;
class Region_Base : public Track_Widget 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: private:


Audio_File *_clip; /* clip this region represents */ Audio_File *_clip; /* clip this region represents */


float _scale; /* amplitude adjustment */ float _scale; /* amplitude adjustment */


Fade _fade_in;
Fade _fade_out;

protected: protected:


const char *class_name ( void ) { return "Region"; } const char *class_name ( void ) { return "Region"; }
@@ -174,6 +200,7 @@ class Region : public Region_Base


public: public:



static Loggable * static Loggable *
create ( char **sa ) create ( char **sa )
{ {


Loading…
Cancel
Save