diff options
author | Thom Johansen <thomj@rockbox.org> | 2006-03-21 23:20:17 +0000 |
---|---|---|
committer | Thom Johansen <thomj@rockbox.org> | 2006-03-21 23:20:17 +0000 |
commit | b0960aed111d63695f328d47b181a0bd620b42cb (patch) | |
tree | 95598c4ff1df1329e377962348529122e7d52173 /apps/dsp.c | |
parent | a27123fe81aa01997a2897cfb9b5872e41c71703 (diff) |
Enabled channel configuration and stereo width option on software codec
platforms.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9173 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/dsp.c')
-rw-r--r-- | apps/dsp.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/apps/dsp.c b/apps/dsp.c index de88c97ca6..f735456393 100644 --- a/apps/dsp.c +++ b/apps/dsp.c @@ -18,6 +18,7 @@ ****************************************************************************/ #include <inttypes.h> #include <string.h> +#include <sound.h> #include "dsp.h" #include "eq.h" #include "kernel.h" @@ -224,6 +225,8 @@ struct crossfeed_data crossfeed_data IBSS_ATTR; static struct eq_state eq_data; static int pitch_ratio = 1000; +static int channels_mode = 0; +static int32_t sw_gain, sw_cross; extern int current_codec; struct dsp_config *dsp; @@ -773,6 +776,70 @@ static void apply_gain(int32_t* _src[], int _count) } } +void channels_set(int value) +{ + channels_mode = value; +} + +void stereo_width_set(int value) +{ + long width, straight, cross; + + width = value*0x7fffff/100; + if (value <= 100) { + straight = (0x7fffff + width)/2; + cross = straight - width; + } else { + straight = 0x7fffff; + cross = 0x7fffff - ((int64_t)(2*width) << 23)/(0x7fffff + width); + } + sw_gain = straight << 8; + sw_cross = cross << 8; +} + +/* Implements the different channel configurations and stereo width. + * We might want to combine this with the write_samples stage for efficiency, + * but for now we'll just let it stay as a stage of its own. + */ +static void channels_process(int32_t **src, int num) +{ + int i; + int32_t *sl = src[0], *sr = src[1]; + + if (channels_mode == SOUND_CHAN_STEREO) + return; + switch (channels_mode) { + case SOUND_CHAN_MONO: + for (i = 0; i < num; i++) + sl[i] = sr[i] = sl[i]/2 + sr[i]/2; + break; + case SOUND_CHAN_CUSTOM: + for (i = 0; i < num; i++) { + int32_t left_sample = sl[i]; + + sl[i] = FRACMUL(sl[i], sw_gain) + FRACMUL(sr[i], sw_cross); + sr[i] = FRACMUL(sr[i], sw_gain) + FRACMUL(left_sample, sw_cross); + } + break; + case SOUND_CHAN_MONO_LEFT: + for (i = 0; i < num; i++) + sr[i] = sl[i]; + break; + case SOUND_CHAN_MONO_RIGHT: + for (i = 0; i < num; i++) + sl[i] = sr[i]; + break; + case SOUND_CHAN_KARAOKE: + for (i = 0; i < num; i++) { + int32_t left_sample = sl[i]; + + sl[i] -= sr[i]; + sr[i] -= left_sample; + } + break; + } +} + static void write_samples(short* dst, int32_t* src[], int count) { int32_t* s0 = src[0]; @@ -843,6 +910,8 @@ long dsp_process(char* dst, const char* src[], long size) apply_crossfeed(tmp, samples); if (dsp->eq_enabled) eq_process(tmp, samples); + if (dsp->stereo_mode != STEREO_MONO) + channels_process(tmp, samples); write_samples((short*) dst, tmp, samples); written += samples; dst += samples * sizeof(short) * 2; |