From 8391526f794b296e5b6edd5707bbf25b5be73e17 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Mon, 28 Apr 2008 08:37:18 +0000 Subject: * introduce AUDIOHW_CAPS to define which audio codec can do what kind of operations in hw, e.g. setting bass * added documentation why and when we need the software based prescaler * implement audiohw_set_bass and audiohw_set_treble for mas35xx * clean up sound_set_bass and sound_set_treble * simplify some #ifdef logic * fix special handling of WM8751 - looking for tester :) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17274 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/audio/mas35xx.c | 20 +++++++++++ firmware/drivers/audio/wm8751.c | 2 +- firmware/export/audiohw.h | 35 +++++++++++++++++++ firmware/export/mas35xx.h | 2 ++ firmware/export/uda1380.h | 4 +-- firmware/export/wm8758.h | 4 +-- firmware/export/wm8975.h | 4 +-- firmware/export/wm8985.h | 4 +-- firmware/sound.c | 74 ++++++++++++++++------------------------ 9 files changed, 95 insertions(+), 54 deletions(-) diff --git a/firmware/drivers/audio/mas35xx.c b/firmware/drivers/audio/mas35xx.c index dac890ddc8..983818bf61 100644 --- a/firmware/drivers/audio/mas35xx.c +++ b/firmware/drivers/audio/mas35xx.c @@ -150,3 +150,23 @@ void audiohw_set_stereo_width(int val) set_channel_config(); } } + +void audiohw_set_bass(int val) +{ +#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) + unsigned tmp = ((unsigned)(val * 8) & 0xff) << 8; + mas_codec_writereg(0x14, tmp); +#elif CONFIG_CODEC == MAS3507D + mas_writereg(MAS_REG_KBASS, bass_table[val+15]); +#endif +} + +void audiohw_set_treble(int val) +{ +#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) + unsigned tmp = ((unsigned)(val * 8) & 0xff) << 8; + mas_codec_writereg(0x15, tmp); +#elif CONFIG_CODEC == MAS3507D + mas_writereg(MAS_REG_KTREBLE, treble_table[val+15]); +#endif +} diff --git a/firmware/drivers/audio/wm8751.c b/firmware/drivers/audio/wm8751.c index 831f16ab17..26123456b6 100644 --- a/firmware/drivers/audio/wm8751.c +++ b/firmware/drivers/audio/wm8751.c @@ -79,7 +79,7 @@ static int tone_tenthdb2hw(int value) /* -6.0db..+0db..+9.0db step 1.5db - translate -60..+0..+90 step 15 to 10..6..0 step -1. */ - value = 10 - (value + 60) / 15; + value = (10 - (value + 60) / 15) / 10; if (value == 6) value = 0xf; /* 0db -> off */ diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h index b3493b86d9..d450613aff 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h @@ -23,6 +23,10 @@ #include "config.h" #include +/* define some audiohw caps */ +#define TREBLE_CAP (1 << 0) +#define BASS_CAP (1 << 1) + #ifdef HAVE_UDA1380 #include "uda1380.h" #elif defined(HAVE_WM8751) @@ -49,6 +53,17 @@ #include "tsc2100.h" #endif +/* convert caps into defines */ +#ifdef AUDIOHW_CAPS +#if (AUDIOHW_CAPS & TREBLE_CAP) +#define AUDIOHW_HAVE_TREBLE +#endif + +#if (AUDIOHW_CAPS & BASS_CAP) +#define AUDIOHW_HAVE_BASS +#endif +#endif /* AUDIOHW_CAPS */ + enum { SOUND_VOLUME = 0, SOUND_BASS, @@ -141,6 +156,26 @@ void audiohw_mute(bool mute); */ void audiohw_enable_output(bool enable); +#ifdef AUDIOHW_HAVE_TREBLE +/** + * Set new treble value. + * @param val to set. + * NOTE: AUDIOHW_CAPS need to contain + * TREBLE_CAP + */ +void audiohw_set_treble(int val); +#endif + +#ifdef AUDIOHW_HAVE_BASS +/** + * Set new bass value. + * @param val to set. + * NOTE: AUDIOHW_CAPS need to contain + * BASS_CAP + */ +void audiohw_set_bass(int val); +#endif + #ifdef HAVE_RECORDING /** diff --git a/firmware/export/mas35xx.h b/firmware/export/mas35xx.h index a4e2413344..dbe9d38a37 100644 --- a/firmware/export/mas35xx.h +++ b/firmware/export/mas35xx.h @@ -24,6 +24,8 @@ #include "config.h" +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) + #if CONFIG_CODEC == MAS3507D #define VOLUME_MIN -780 #define VOLUME_MAX 180 diff --git a/firmware/export/uda1380.h b/firmware/export/uda1380.h index cd27536e87..c23f95265b 100644 --- a/firmware/export/uda1380.h +++ b/firmware/export/uda1380.h @@ -24,13 +24,13 @@ #define VOLUME_MIN -840 #define VOLUME_MAX 0 +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) + extern int tenthdb2master(int db); extern int tenthdb2mixer(int db); extern void audiohw_set_master_vol(int vol_l, int vol_r); extern void audiohw_set_mixer_vol(int channel1, int channel2); -extern void audiohw_set_bass(int value); -extern void audiohw_set_treble(int value); /** * Sets frequency settings for DAC and ADC relative to MCLK diff --git a/firmware/export/wm8758.h b/firmware/export/wm8758.h index 61db094684..5e37e203d5 100644 --- a/firmware/export/wm8758.h +++ b/firmware/export/wm8758.h @@ -24,15 +24,15 @@ #define VOLUME_MIN -570 #define VOLUME_MAX 60 +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) + extern int tenthdb2master(int db); extern int tenthdb2mixer(int db); extern void audiohw_set_master_vol(int vol_l, int vol_r); extern void audiohw_set_lineout_vol(int vol_l, int vol_r); extern void audiohw_set_mixer_vol(int channel1, int channel2); -extern void audiohw_set_bass(int value); extern void audiohw_set_bass_cutoff(int value); -extern void audiohw_set_treble(int value); extern void audiohw_set_treble_cutoff(int value); extern void audiohw_set_nsorder(int order); extern void audiohw_set_sample_rate(int sampling_control); diff --git a/firmware/export/wm8975.h b/firmware/export/wm8975.h index 1ae82061ee..6457f255f6 100644 --- a/firmware/export/wm8975.h +++ b/firmware/export/wm8975.h @@ -24,12 +24,12 @@ #define VOLUME_MIN -730 #define VOLUME_MAX 60 +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) + extern int tenthdb2master(int db); extern void audiohw_set_master_vol(int vol_l, int vol_r); extern void audiohw_set_lineout_vol(int vol_l, int vol_r); -extern void audiohw_set_bass(int value); -extern void audiohw_set_treble(int value); extern void audiohw_set_nsorder(int order); extern void audiohw_set_sample_rate(int sampling_control); diff --git a/firmware/export/wm8985.h b/firmware/export/wm8985.h index 8fa58425bf..8696e3dd6f 100644 --- a/firmware/export/wm8985.h +++ b/firmware/export/wm8985.h @@ -24,15 +24,15 @@ #define VOLUME_MIN -570 #define VOLUME_MAX 60 +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) + extern int tenthdb2master(int db); extern int tenthdb2mixer(int db); extern void audiohw_set_master_vol(int vol_l, int vol_r); extern void audiohw_set_lineout_vol(int vol_l, int vol_r); extern void audiohw_set_mixer_vol(int channel1, int channel2); -extern void audiohw_set_bass(int value); extern void audiohw_set_bass_cutoff(int value); -extern void audiohw_set_treble(int value); extern void audiohw_set_treble_cutoff(int value); extern void audiohw_set_nsorder(int order); extern void audiohw_set_sample_rate(int sampling_control); diff --git a/firmware/sound.c b/firmware/sound.c index eda223bff0..325c42639a 100644 --- a/firmware/sound.c +++ b/firmware/sound.c @@ -222,10 +222,20 @@ static int tenthdb2reg(int db) } #endif -#if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \ - || defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_WM8731) \ - || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \ - || defined(HAVE_AS3514) || defined(HAVE_WM8985) || defined(HAVE_TSC2100) + +/* MAS3587F and MAS3539F handle clipping prevention internally so we do not need + * the prescaler. + */ +#if (CONFIG_CODEC != MAS3587F) && (CONFIG_CODEC != MAS3539F) + +/* + * The prescaler compensates for any kind of boosts, to prevent clipping. + * + * It's basically just a measure to make sure that audio does not clip during + * tone controls processing, like if i want to boost bass 12 dB, i can decrease + * the audio amplitude by -12 dB before processing, then increase master gain + * by 12 dB after processing. + */ /* all values in tenth of dB MAS3507D UDA1380 */ int current_volume = 0; /* -780..+180 -840.. 0 */ @@ -352,60 +362,34 @@ void sound_set_bass(int value) { if(!audio_is_initialized) return; -#if defined(HAVE_SW_TONE_CONTROLS) - current_bass = value * 10; - dsp_callback(DSP_CALLBACK_SET_BASS, current_bass); - set_prescaled_volume(); -#elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) - unsigned tmp = ((unsigned)(value * 8) & 0xff) << 8; - mas_codec_writereg(0x14, tmp); -#elif CONFIG_CODEC == MAS3507D - mas_writereg(MAS_REG_KBASS, bass_table[value+15]); - current_bass = value * 10; - set_prescaled_volume(); -#elif defined(HAVE_WM8751) - current_bass = value; + +#if defined(AUDIOHW_HAVE_BASS) audiohw_set_bass(value); - set_prescaled_volume(); -#elif defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_UDA1380) \ - || defined HAVE_WM8731 || defined(HAVE_WM8721) || defined(HAVE_WM8985) +#else + dsp_callback(DSP_CALLBACK_SET_BASS, current_bass); +#endif + +#if (CONFIG_CODEC != MAS3587F) && (CONFIG_CODEC != MAS3539F) current_bass = value * 10; - audiohw_set_bass(value); set_prescaled_volume(); -#elif CONFIG_CPU == PNX0101 - /* TODO: implement for iFP */ -#endif - (void)value; +#endif } void sound_set_treble(int value) { if(!audio_is_initialized) return; -#if defined(HAVE_SW_TONE_CONTROLS) - current_treble = value * 10; - dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble); - set_prescaled_volume(); -#elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) - unsigned tmp = ((unsigned)(value * 8) & 0xff) << 8; - mas_codec_writereg(0x15, tmp); -#elif CONFIG_CODEC == MAS3507D - mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]); - current_treble = value * 10; - set_prescaled_volume(); -#elif defined(HAVE_WM8751) - audiohw_set_treble(value); - current_treble = value; - set_prescaled_volume(); -#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_UDA1380) \ - || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8985) + +#if defined(AUDIOHW_HAVE_TREBLE) audiohw_set_treble(value); +#else + dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble); +#endif + +#if (CONFIG_CODEC != MAS3587F) && (CONFIG_CODEC != MAS3539F) current_treble = value * 10; set_prescaled_volume(); -#elif CONFIG_CPU == PNX0101 - /* TODO: implement for iFP */ #endif - (void)value; } void sound_set_channels(int value) -- cgit v1.2.3