Mercurial > mplayer.hg
changeset 36402:2c9356ac0d01
af_volume: optimize for common case where all channels
have same volume.
author | reimar |
---|---|
date | Tue, 29 Oct 2013 19:24:16 +0000 |
parents | abdc52a1ab2c |
children | 07e9ebd91b98 |
files | libaf/af_volume.c |
diffstat | 1 files changed, 45 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/libaf/af_volume.c Tue Oct 29 19:24:13 2013 +0000 +++ b/libaf/af_volume.c Tue Oct 29 19:24:16 2013 +0000 @@ -111,6 +111,36 @@ free(af->setup); } +static av_always_inline void s16_inner_loop(int16_t *data, int len, int offset, int step, float level) +{ + int i; + register int vol = (int)(255.0 * level); + for (i = offset; i < len; i += step) + { + register int x = (data[i] * vol) >> 8; + data[i] = av_clip_int16(x); + } +} + +static av_always_inline void float_inner_loop(float *data, int len, int offset, int step, float level, int softclip) +{ + int i; + for (i = offset; i < len; i += step) + { + register float x = data[i]; + // Set volume + x *= level; + /* Soft clipping, the sound of a dream, thanks to Jon Wattes + post to Musicdsp.org */ + if (softclip) + x = af_softclip(x); + // Hard clipping + else + x = av_clipf(x,-1.0,1.0); + data[i] = x; + } +} + // Filter data through filter static af_data_t* play(struct af_instance_s* af, af_data_t* data) { @@ -119,18 +149,20 @@ int ch = 0; // Channel counter register int nch = c->nch; // Number of channels register int i = 0; + int same_vol = 1; + for (ch = 1; ch < nch; ch++) + { + same_vol &= s->level[ch] == s->level[ch - 1]; + } // Basic operation volume control only (used on slow machines) if(af->data->format == (AF_FORMAT_S16_NE)){ int16_t* a = (int16_t*)c->audio; // Audio data int len = c->len/2; // Number of samples - for(ch = 0; ch < nch ; ch++){ - register int vol = (int)(255.0 * s->level[ch]); - for(i=ch;i<len;i+=nch){ - register int x = (a[i] * vol) >> 8; - a[i]=av_clip_int16(x); - } - } + if (same_vol) + s16_inner_loop(a, len, 0, 1, s->level[0]); + else for (ch = 0; ch < nch; ch++) + s16_inner_loop(a, len, ch, nch, s->level[ch]); } // Machine is fast and data is floating point else if(af->data->format == (AF_FORMAT_FLOAT_NE)){ @@ -139,22 +171,12 @@ for (i = 0; !s->fast && i < len; i++) // Check maximum power value s->max = FFMAX(s->max, a[i] * a[i]); - for(ch = 0; ch < nch ; ch++){ - // Volume control (fader) - for(i=ch;i<len;i+=nch){ - register float x = a[i]; - // Set volume - x *= s->level[ch]; - /* Soft clipping, the sound of a dream, thanks to Jon Wattes - post to Musicdsp.org */ - if(s->soft) - x=af_softclip(x); - // Hard clipping - else - x=av_clipf(x,-1.0,1.0); - a[i] = x; - } - } + if (same_vol && s->soft) + float_inner_loop(a, len, 0, 1, s->level[0], 1); + else if (same_vol) + float_inner_loop(a, len, 0, 1, s->level[0], 0); + else for (ch = 0; ch < nch; ch++) + float_inner_loop(a, len, ch, nch, s->level[ch], s->soft); } return c; }