From 11b02a2bda36b55cc2a3b6c470e51d95761e755c Mon Sep 17 00:00:00 2001 From: Sean Bartell Date: Mon, 22 Aug 2011 01:36:36 -0400 Subject: [PATCH 1/7] rbcodec refactoring: dsp_callback --- apps/misc.c | 41 +++++++++++++++++- apps/misc.h | 1 + apps/plugins/mpegplayer/mpeg_settings.c | 1 + apps/plugins/wavplay.c | 1 + apps/rbcodecconfig.h | 4 ++ firmware/drivers/audio/mas35xx.c | 1 + firmware/export/audiohw.h | 10 ---- firmware/export/mas35xx.h | 12 +++++ firmware/export/sound.h | 20 +++----- lib/rbcodec/dsp/dsp.c | 73 ++++++++---------------------- lib/rbcodec/dsp/dsp.h | 24 ++++++++++- lib/rbcodec/dsp/tdspeed.c | 1 - lib/rbcodec/rbcodecconfig-example.h | 1 + lib/rbcodec/test/warble.c | 3 +- 14 files changed, 113 insertions(+), 80 deletions(-) diff --git a/apps/misc.c b/apps/misc.c index 1138642..8bdf057 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -810,7 +810,46 @@ void dsp_set_replaygain(void) rbcodec_dsp_set_replaygain(type, global_settings.replaygain_noclip, global_settings.replaygain_preamp); } + +/* Hook back from firmware/ part of audio, which can't/shouldn't call apps/ + * code directly. + */ +int dsp_callback(int msg, intptr_t param) +{ + static int bass, treble; + switch (msg) + { +#ifdef HAVE_SW_TONE_CONTROLS + case DSP_CALLBACK_SET_PRESCALE: + set_tone_controls(bass, treble, param); + break; + /* prescaler is always set after calling any of these, so we wait with + * calculating coefs until the above case is hit. + */ + case DSP_CALLBACK_SET_BASS: + bass = param; + break; + case DSP_CALLBACK_SET_TREBLE: + treble = param; + break; +#ifdef HAVE_SW_VOLUME_CONTROL + case DSP_CALLBACK_SET_SW_VOLUME: + rbcodec_dsp_set_volume(global_settings.volume); + break; +#endif #endif + case DSP_CALLBACK_SET_CHANNEL_CONFIG: + dsp_set_channel_config(param); + break; + case DSP_CALLBACK_SET_STEREO_WIDTH: + dsp_set_stereo_width(param); + break; + default: + break; + } + return 0; +} +#endif /* CONFIG_CODEC == SWCODEC */ char* strrsplt(char* str, int c) { diff --git a/apps/misc.h b/apps/misc.h index d6c55f3..aad864e 100644 --- a/apps/misc.h +++ b/apps/misc.h @@ -79,6 +79,7 @@ void check_bootfile(bool do_rolo); void setvol(void); void dsp_set_replaygain(void); +int dsp_callback(int msg, intptr_t param); #ifdef HAVE_LCD_COLOR int hex_to_rgb(const char* hex, int* color); diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c index 1b1ac8e..2cd9b93 100644 --- a/apps/plugins/mpegplayer/mpeg_settings.c +++ b/apps/plugins/mpegplayer/mpeg_settings.c @@ -1,6 +1,7 @@ #include "plugin.h" #include "lib/helper.h" #include "lib/configfile.h" +#include "dsp.h" /* SOUND_CHAN_STEREO */ #include "mpegplayer.h" #include "mpeg_settings.h" diff --git a/apps/plugins/wavplay.c b/apps/plugins/wavplay.c index 073af31..20dd792 100644 --- a/apps/plugins/wavplay.c +++ b/apps/plugins/wavplay.c @@ -19,6 +19,7 @@ * ****************************************************************************/ #include "plugin.h" +#include "dsp.h" /* SOUND_CHAN_* */ diff --git a/apps/rbcodecconfig.h b/apps/rbcodecconfig.h index e155796..4248245 100644 --- a/apps/rbcodecconfig.h +++ b/apps/rbcodecconfig.h @@ -14,4 +14,8 @@ * {be,le}toh{16,32}, ROCKBOX_{BIG,LITTLE}_ENDIAN */ #include "system.h" +#ifndef HAVE_MAS35XX +#define RBCODEC_ENABLE_CHANNEL_MODES +#endif + #endif diff --git a/firmware/drivers/audio/mas35xx.c b/firmware/drivers/audio/mas35xx.c index e6cc665..0ba58bb 100644 --- a/firmware/drivers/audio/mas35xx.c +++ b/firmware/drivers/audio/mas35xx.c @@ -25,6 +25,7 @@ #include "config.h" #include "system.h" /* MAX MIN macros */ #include "audiohw.h" +#include "mas35xx.h" const struct sound_settings_info audiohw_settings[] = { #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h index 593924d..d58fa51 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h @@ -333,16 +333,6 @@ enum { SOUND_LAST_SETTING, /* Keep this last */ }; -enum Channel { - SOUND_CHAN_STEREO, - SOUND_CHAN_MONO, - SOUND_CHAN_CUSTOM, - SOUND_CHAN_MONO_LEFT, - SOUND_CHAN_MONO_RIGHT, - SOUND_CHAN_KARAOKE, - SOUND_CHAN_NUM_MODES, -}; - struct sound_settings_info { const char *unit; char numdecimals; diff --git a/firmware/export/mas35xx.h b/firmware/export/mas35xx.h index f75658f..fc3a433 100644 --- a/firmware/export/mas35xx.h +++ b/firmware/export/mas35xx.h @@ -272,4 +272,16 @@ extern void audiohw_set_balance(int val); extern void audiohw_set_pitch(unsigned long val); #endif +/* This platform has hardware support for channel modes. Since librbcodec's + * version isn't being used, we need our own copy of this enum. */ +enum Channel { + SOUND_CHAN_STEREO, + SOUND_CHAN_MONO, + SOUND_CHAN_CUSTOM, + SOUND_CHAN_MONO_LEFT, + SOUND_CHAN_MONO_RIGHT, + SOUND_CHAN_KARAOKE, + SOUND_CHAN_NUM_MODES, +}; + #endif /* _MAS35XX_H */ diff --git a/firmware/export/sound.h b/firmware/export/sound.h index 7243f48..5f057b7 100644 --- a/firmware/export/sound.h +++ b/firmware/export/sound.h @@ -128,21 +128,17 @@ void sound_set_mdb_center(int value); void sound_set_mdb_shape(int value); void sound_set_mdb_enable(int value); void sound_set_superbass(int value); -#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ - -void sound_set(int setting, int value); -int sound_val2phys(int setting, int value); -#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) +/* Precision of the pitch and speed variables. 100 = 1%, 10000 = 100%. Since + * librbcodec's pitch scaling isn't being used, we need our own copy of these + * defines. */ +#define PITCH_SPEED_PRECISION 100L +#define PITCH_SPEED_100 (100L * PITCH_SPEED_PRECISION) /* 100% speed */ void sound_set_pitch(int32_t pitch); int32_t sound_get_pitch(void); -#endif +#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ -#ifdef HAVE_PITCHSCREEN -/* precision of the pitch and speed variables */ -/* One zero per decimal (100 means two decimal places */ -#define PITCH_SPEED_PRECISION 100L -#define PITCH_SPEED_100 (100L * PITCH_SPEED_PRECISION) /* 100% speed */ -#endif /* HAVE_PITCHSCREEN */ +void sound_set(int setting, int value); +int sound_val2phys(int setting, int value); #endif diff --git a/lib/rbcodec/dsp/dsp.c b/lib/rbcodec/dsp/dsp.c index 95e0409..fca594b 100644 --- a/lib/rbcodec/dsp/dsp.c +++ b/lib/rbcodec/dsp/dsp.c @@ -213,9 +213,10 @@ static struct eq_state eq_data; /* A */ /* Software tone controls */ #ifdef HAVE_SW_TONE_CONTROLS -static int prescale; /* A/V */ -static int bass; /* A/V */ -static int treble; /* A/V */ +static bool tone_controls_enabled; /* A/V */ +#ifdef HAVE_SW_VOLUME_CONTROL +static int volume; +#endif #endif /* Settings applicable to audio codec only */ @@ -923,10 +924,9 @@ static void set_gain(struct dsp_config *dsp) } #ifdef HAVE_SW_VOLUME_CONTROL - if (global_settings.volume < SW_VOLUME_MAX || - global_settings.volume > SW_VOLUME_MIN) + if (volume < SW_VOLUME_MAX || volume > SW_VOLUME_MIN) { - int vol_gain = get_replaygain_int(global_settings.volume * 100); + int vol_gain = get_replaygain_int(volume * 100); dsp->data.gain = (long) (((int64_t) dsp->data.gain * vol_gain) >> 24); } #endif @@ -943,6 +943,14 @@ static void set_gain(struct dsp_config *dsp) dsp->apply_gain = dsp->data.gain != 0 ? dsp_apply_gain : NULL; } +#ifdef HAVE_SW_VOLUME_CONTROL +void dsp_set_volume(int vol) +{ + volume = vol; + set_gain(&AUDIO_DSP); +} +#endif + /** * Update the amount to cut the audio before applying the equalizer. * @@ -1026,7 +1034,7 @@ void dsp_set_eq(bool enable) set_gain(&AUDIO_DSP); } -static void dsp_set_stereo_width(int value) +void dsp_set_stereo_width(int value) { long width, straight, cross; @@ -1119,7 +1127,7 @@ static void channels_process_sound_chan_karaoke(int count, int32_t *buf[]) } #endif /* DSP_HAVE_ASM_SOUND_CHAN_KARAOKE */ -static void dsp_set_channel_config(int value) +void dsp_set_channel_config(int value) { static const channels_process_fn_type channels_process_functions[] = { @@ -1143,11 +1151,10 @@ static void dsp_set_channel_config(int value) AUDIO_DSP.channels_process = channels_process_functions[value]; } -#if CONFIG_CODEC == SWCODEC - -#ifdef HAVE_SW_TONE_CONTROLS -static void set_tone_controls(void) +#if CONFIG_CODEC == SWCODEC && defined(HAVE_SW_TONE_CONTROLS) +void set_tone_controls(int bass, int treble, int prescale) { + tone_controls_enabled = bass || treble; filter_bishelf_coefs(0xffffffff/NATIVE_FREQUENCY*200, 0xffffffff/NATIVE_FREQUENCY*3500, bass, treble, -prescale, @@ -1158,46 +1165,6 @@ static void set_tone_controls(void) } #endif -/* Hook back from firmware/ part of audio, which can't/shouldn't call apps/ - * code directly. - */ -int dsp_callback(int msg, intptr_t param) -{ - switch (msg) - { -#ifdef HAVE_SW_TONE_CONTROLS - case DSP_CALLBACK_SET_PRESCALE: - prescale = param; - set_tone_controls(); - break; - /* prescaler is always set after calling any of these, so we wait with - * calculating coefs until the above case is hit. - */ - case DSP_CALLBACK_SET_BASS: - bass = param; - break; - case DSP_CALLBACK_SET_TREBLE: - treble = param; - break; -#ifdef HAVE_SW_VOLUME_CONTROL - case DSP_CALLBACK_SET_SW_VOLUME: - set_gain(&AUDIO_DSP); - break; -#endif -#endif - case DSP_CALLBACK_SET_CHANNEL_CONFIG: - dsp_set_channel_config(param); - break; - case DSP_CALLBACK_SET_STEREO_WIDTH: - dsp_set_stereo_width(param); - break; - default: - break; - } - return 0; -} -#endif - static void dsp_recalc_replaygain(void) { long gain = 0; @@ -1308,7 +1275,7 @@ int dsp_process(struct dsp_config *dsp, char *dst, const char *src[], int count) dsp->eq_process(chunk, t2); #ifdef HAVE_SW_TONE_CONTROLS - if ((bass | treble) != 0) + if (tone_controls_enabled) eq_filter(t2, &dsp->tone_filter, chunk, dsp->data.num_channels, FILTER_BISHELF_SHIFT); #endif diff --git a/lib/rbcodec/dsp/dsp.h b/lib/rbcodec/dsp/dsp.h index 79ef934..1dc7092 100644 --- a/lib/rbcodec/dsp/dsp.h +++ b/lib/rbcodec/dsp/dsp.h @@ -24,9 +24,16 @@ #include #include +#include "rbcodecconfig.h" #define NATIVE_FREQUENCY 44100 +#ifdef HAVE_PITCHSCREEN +/* Precision of the pitch and speed variables. 100 = 1%, 10000 = 100%. */ +#define PITCH_SPEED_PRECISION 100L +#define PITCH_SPEED_100 (100L * PITCH_SPEED_PRECISION) /* 100% speed */ +#endif /* HAVE_PITCHSCREEN */ + enum { STEREO_INTERLEAVED = 0, @@ -35,6 +42,18 @@ enum STEREO_NUM_MODES, }; +#ifdef RBCODEC_ENABLE_CHANNEL_MODES +enum Channel { + SOUND_CHAN_STEREO, + SOUND_CHAN_MONO, + SOUND_CHAN_CUSTOM, + SOUND_CHAN_MONO_LEFT, + SOUND_CHAN_MONO_RIGHT, + SOUND_CHAN_KARAOKE, + SOUND_CHAN_NUM_MODES, +}; +#endif + enum { CODEC_IDX_AUDIO = 0, @@ -88,8 +107,11 @@ void sound_set_pitch(int32_t r); int32_t sound_get_pitch(void); void dsp_set_timestretch(int32_t percent); int32_t dsp_get_timestretch(void); -int dsp_callback(int msg, intptr_t param); void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio, int c_knee, int c_release); +void dsp_set_volume(int vol); +void set_tone_controls(int bass, int treble, int prescale); +void dsp_set_channel_config(int value); +void dsp_set_stereo_width(int value); #endif diff --git a/lib/rbcodec/dsp/tdspeed.c b/lib/rbcodec/dsp/tdspeed.c index c5bd923..a984eaa 100644 --- a/lib/rbcodec/dsp/tdspeed.c +++ b/lib/rbcodec/dsp/tdspeed.c @@ -24,7 +24,6 @@ #include #include #include -#include "sound.h" #include "buffer.h" #include "system.h" #include "tdspeed.h" diff --git a/lib/rbcodec/rbcodecconfig-example.h b/lib/rbcodec/rbcodecconfig-example.h index c3b23fa..bf516bc 100644 --- a/lib/rbcodec/rbcodecconfig-example.h +++ b/lib/rbcodec/rbcodecconfig-example.h @@ -3,6 +3,7 @@ #define HAVE_SW_TONE_CONTROLS #define NUM_CORES 1 #define __PCTOOL__ +#define RBCODEC_ENABLE_CHANNEL_MODES /* {,u}int{8,16,32,64}_t */ #include diff --git a/lib/rbcodec/test/warble.c b/lib/rbcodec/test/warble.c index b22e049..1eb52d7 100644 --- a/lib/rbcodec/test/warble.c +++ b/lib/rbcodec/test/warble.c @@ -350,8 +350,7 @@ static void perform_config(void) } else if (!strncmp(name, "tempo=", 6)) { dsp_set_timestretch(atof(val) * PITCH_SPEED_100); } else if (!strncmp(name, "vol=", 4)) { - global_settings.volume = atoi(val); - dsp_callback(DSP_CALLBACK_SET_SW_VOLUME, 0); + dsp_set_volume(atoi(val)); } else { fprintf(stderr, "error: unrecognized config \"%.*s\"\n", (int)(eq - name), name); -- 1.7.6