diff --git a/apps/fixedpoint.c b/apps/fixedpoint.c index 5051cc78e7..b212929245 100644 --- a/apps/fixedpoint.c +++ b/apps/fixedpoint.c @@ -353,7 +353,7 @@ long fp16_exp(int x) /** FIXED POINT EXP10 * Return 10^x as FP integer. Argument is FP integer. */ -static long fp_exp10(long x, unsigned int fracbits) +long fp_exp10(long x, unsigned int fracbits) { long k; long z; diff --git a/apps/settings.c b/apps/settings.c index 1bb6c74b43..0984143dbb 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -723,7 +723,7 @@ void settings_apply_pm_range(void) void sound_settings_apply(void) { #if CONFIG_CODEC == SWCODEC - sound_set_dsp_callback(dsp_callback); + audiohw_swcodec_set_callback(dsp_callback); #endif #ifdef AUDIOHW_HAVE_BASS sound_set(SOUND_BASS, global_settings.bass); diff --git a/firmware/SOURCES b/firmware/SOURCES index 964d57ff5d..e6c0b967d4 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -361,6 +361,8 @@ pcm_sw_volume.c #ifdef HAVE_RECORDING enc_base.c #endif /* HAVE_RECORDING */ + +drivers/audio/audiohw-swcodec.c #endif /* BOOTLOADER */ #endif /* SWCODEC */ diff --git a/firmware/drivers/audio/aic3x.c b/firmware/drivers/audio/aic3x.c index 97eb17ebef..08c4db3f53 100644 --- a/firmware/drivers/audio/aic3x.c +++ b/firmware/drivers/audio/aic3x.c @@ -44,7 +44,7 @@ const struct sound_settings_info audiohw_settings[] = { }; /* convert tenth of dB volume to master volume register value */ -int tenthdb2master(int db) +static int vol_tenthdb2hw(int db) { /* 0 to -63.0dB in 1dB steps, aic3x can goto -63.5 in 0.5dB steps */ if (db < VOLUME_MIN) @@ -270,8 +270,11 @@ void audiohw_set_frequency(int fsel) /* TODO */ } -void audiohw_set_headphone_vol(int vol_l, int vol_r) +void audiohw_set_volume(int vol_l, int vol_r) { + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); + if ((volume_left & 0x7F) == (vol_l & 0x7F) && (volume_right & 0x7F) == (vol_r & 0x7F)) { diff --git a/firmware/drivers/audio/ak4537.c b/firmware/drivers/audio/ak4537.c index c3ce02a3af..4a9010d4e7 100644 --- a/firmware/drivers/audio/ak4537.c +++ b/firmware/drivers/audio/ak4537.c @@ -80,7 +80,7 @@ static void codec_set_active(int active) #endif /* convert tenth of dB volume (-1270..0) to master volume register value */ -int tenthdb2master(int db) +static int vol_tenthdb2hw(int db) { if (db < VOLUME_MIN) return 0xff; /* mute */ @@ -90,29 +90,6 @@ int tenthdb2master(int db) return ((-db)/5); } -int sound_val2phys(int setting, int value) -{ - int result; - - switch(setting) - { -#ifdef HAVE_RECORDING - case SOUND_LEFT_GAIN: - case SOUND_RIGHT_GAIN: - result = (value - 23) * 15; /* fix */ - break; - case SOUND_MIC_GAIN: - result = value * 200; /* fix */ - break; -#endif - default: - result = value; - break; - } - - return result; -} - /*static void audiohw_mute(bool mute) { if (mute) @@ -232,6 +209,8 @@ void audiohw_close(void) void audiohw_set_master_vol(int vol_l, int vol_r) { + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); akc_write(AK4537_ATTL, vol_l & 0xff); akc_write(AK4537_ATTR, vol_r & 0xff); } diff --git a/firmware/drivers/audio/as3514.c b/firmware/drivers/audio/as3514.c index 5f18bc6ec1..b9118f9fcf 100644 --- a/firmware/drivers/audio/as3514.c +++ b/firmware/drivers/audio/as3514.c @@ -63,21 +63,6 @@ #endif -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN/10, 6, -25}, - /* HAVE_SW_TONE_CONTROLS */ - [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, - [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -#ifdef HAVE_RECORDING - [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 39, 23}, - [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23}, -#endif -}; - /* Shadow registers */ static uint8_t as3514_regs[AS3514_NUM_AUDIO_REGS]; /* 8-bit registers */ @@ -112,7 +97,7 @@ static void as3514_write_masked(unsigned int reg, unsigned int bits, } /* convert tenth of dB volume to master volume register value */ -int tenthdb2master(int db) +static int vol_tenthdb2hw(int db) { /* +6 to -73.5dB (or -81.0 dB) in 1.5dB steps == 53 (or 58) levels */ if (db < VOLUME_MIN) { @@ -124,22 +109,6 @@ int tenthdb2master(int db) } } -int sound_val2phys(int setting, int value) -{ - switch(setting) - { -#if defined(HAVE_RECORDING) - case SOUND_LEFT_GAIN: - case SOUND_RIGHT_GAIN: - case SOUND_MIC_GAIN: - return (value - 23) * 15; -#endif - - default: - return value; - } -} - /* * Initialise the PP I2C and I2S. */ @@ -276,6 +245,9 @@ void audiohw_set_master_vol(int vol_l, int vol_r) unsigned int hph_r, hph_l; unsigned int mix_l, mix_r; + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); + if (vol_l == 0 && vol_r == 0) { audiohw_mute(true); return; @@ -322,12 +294,14 @@ void audiohw_set_master_vol(int vol_l, int vol_r) } #if 0 /* unused */ -void audiohw_set_lineout_vol(int vol_l, int vol_r) +void audiohw_set_lineout_volume(int vol_l, int vol_r) { #ifdef HAVE_AS3543 /* line out volume is set in the same registers */ - audiohw_set_master_vol(vol_l, vol_r); + audiohw_set_master_volume(vol_l, vol_r); #else + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); as3514_write_masked(AS3514_LINE_OUT_R, vol_r, AS3514_VOL_MASK); as3514_write_masked(AS3514_LINE_OUT_L, vol_l, AS3514_VOL_MASK); #endif diff --git a/firmware/drivers/audio/audiohw-swcodec.c b/firmware/drivers/audio/audiohw-swcodec.c new file mode 100644 index 0000000000..45b21183ad --- /dev/null +++ b/firmware/drivers/audio/audiohw-swcodec.c @@ -0,0 +1,76 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Thom Johansen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include "system.h" +#include "sound.h" +#include "dsp_misc.h" + +/* Linking audio hardware calls to SWCODEC DSP emulation */ + +static audiohw_swcodec_cb_type callback = NULL; + +void audiohw_swcodec_set_callback(audiohw_swcodec_cb_type func) +{ + callback = func; +} + +/** Functions exported by audiohw.h **/ + +void audiohw_set_channel(int value) +{ + callback(DSP_CALLBACK_SET_CHANNEL_CONFIG, value); +} + +void audiohw_set_stereo_width(int value) +{ + callback(DSP_CALLBACK_SET_STEREO_WIDTH, value); +} + +#ifdef HAVE_SW_TONE_CONTROLS +void audiohw_set_bass(int value) +{ + callback(DSP_CALLBACK_SET_BASS, value); +} + +void audiohw_set_treble(int value) +{ + callback(DSP_CALLBACK_SET_TREBLE, value); +} +#endif /* HAVE_SW_TONE_CONTROLS */ + +#ifndef AUDIOHW_HAVE_PRESCALER +void audiohw_set_prescaler(int value) +{ + callback(DSP_CALLBACK_SET_PRESCALE, value); +} +#endif /* AUDIOHW_HAVE_PRESCALER */ + +#ifdef HAVE_PITCHCONTROL +void audiohw_set_pitch(int32_t value) +{ + callback(DSP_CALLBACK_SET_PITCH, value); +} + +int32_t audiohw_get_pitch(void) +{ + return callback(DSP_CALLBACK_GET_PITCH, 0); +} +#endif /* HAVE_PITCHCONTROL */ diff --git a/firmware/drivers/audio/cs42l55.c b/firmware/drivers/audio/cs42l55.c index 38380d5a54..75fcd80b77 100644 --- a/firmware/drivers/audio/cs42l55.c +++ b/firmware/drivers/audio/cs42l55.c @@ -29,27 +29,15 @@ #include "cscodec.h" #include "cs42l55.h" -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, -60, 12, -25}, - [SOUND_BASS] = {"dB", 1, 15,-105, 120, 0}, - [SOUND_TREBLE] = {"dB", 1, 15,-105, 120, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, - [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 2}, - [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1}, -}; - static int bass, treble; -/* convert tenth of dB volume (-600..120) to master volume register value */ -int tenthdb2master(int db) +/* convert tenth of dB volume (-600..120) to volume register value */ +static int vol_tenthdb2hw(int db) { /* -60dB to +12dB in 1dB steps */ /* 0001100 == +12dB (0xc) */ /* 0000000 == 0dB (0x0) */ /* 1000100 == -60dB (0x44, this is actually -58dB) */ - if (db < VOLUME_MIN) return HPACTL_HPAMUTE; return (db / 10) & HPACTL_HPAVOL_MASK; } @@ -125,11 +113,8 @@ void audiohw_postinit(void) void audiohw_set_master_vol(int vol_l, int vol_r) { - /* -60dB to +12dB in 1dB steps */ - /* 0001100 == +12dB (0xc) */ - /* 0000000 == 0dB (0x0) */ - /* 1000100 == -60dB (0x44, this is actually -58dB) */ - + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); cscodec_setbits(HPACTL, HPACTL_HPAVOL_MASK | HPACTL_HPAMUTE, vol_l << HPACTL_HPAVOL_SHIFT); cscodec_setbits(HPBCTL, HPBCTL_HPBVOL_MASK | HPBCTL_HPBMUTE, @@ -138,11 +123,8 @@ void audiohw_set_master_vol(int vol_l, int vol_r) void audiohw_set_lineout_vol(int vol_l, int vol_r) { - /* -60dB to +12dB in 1dB steps */ - /* 0001100 == +12dB (0xc) */ - /* 0000000 == 0dB (0x0) */ - /* 1000100 == -60dB (0x44, this is actually -58dB) */ - + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); cscodec_setbits(LINEACTL, LINEACTL_LINEAVOL_MASK | LINEACTL_LINEAMUTE, vol_l << LINEACTL_LINEAVOL_SHIFT); cscodec_setbits(LINEBCTL, LINEBCTL_LINEBVOL_MASK | LINEBCTL_LINEBMUTE, diff --git a/firmware/drivers/audio/dac3550a.c b/firmware/drivers/audio/dac3550a.c index 9c6dfbb292..0ff5d8ad21 100644 --- a/firmware/drivers/audio/dac3550a.c +++ b/firmware/drivers/audio/dac3550a.c @@ -27,15 +27,6 @@ static bool line_in_enabled = false; static bool dac_enabled = false; -/* convert tenth of dB volume (-780..+180) to dac3550 register value */ -int tenthdb2reg(int db) -{ - if (db < -540) /* 3 dB steps */ - return (db + 780) / 30; - else /* 1.5 dB steps */ - return (db + 660) / 15; -} - int dac_volume(unsigned int left, unsigned int right, bool deemph) { int ret = 0; diff --git a/firmware/drivers/audio/dummy_codec.c b/firmware/drivers/audio/dummy_codec.c index 94ba04b56a..3e73137eb9 100644 --- a/firmware/drivers/audio/dummy_codec.c +++ b/firmware/drivers/audio/dummy_codec.c @@ -26,16 +26,6 @@ #include "system.h" #include "pcm_sw_volume.h" -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN/10, VOLUME_MAX/10, 0}, - /* HAVE_SW_TONE_CONTROLS */ - [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, - [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -}; - void audiohw_preinit(void) { } void audiohw_postinit(void) { } @@ -48,7 +38,7 @@ void audiohw_set_frequency(int fsel) } #ifdef HAVE_SW_VOLUME_CONTROL -void audiohw_set_master_vol(int vol_l, int vol_r) +void audiohw_set_volume(int vol_l, int vol_r) { /* SW volume for <= 1.0 gain, HW at unity, < VOLUME_MIN == MUTE */ int sw_volume_l = vol_l < VOLUME_MIN ? PCM_MUTE_LEVEL : MIN(vol_l, 0); diff --git a/firmware/drivers/audio/imx233-codec.c b/firmware/drivers/audio/imx233-codec.c index 20edf005e8..ef4e3ca1d5 100644 --- a/firmware/drivers/audio/imx233-codec.c +++ b/firmware/drivers/audio/imx233-codec.c @@ -25,30 +25,6 @@ #include "audioout-imx233.h" #include "audioin-imx233.h" -const struct sound_settings_info audiohw_settings[] = -{ - /* i.MX233 has half dB steps */ - [SOUND_VOLUME] = {"dB", 0, 5, VOLUME_MIN / 10, VOLUME_MAX / 10, -25}, - /* HAVE_SW_TONE_CONTROLS */ - [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, - [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -#ifdef HAVE_RECORDING - [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23}, - [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 0}, -#endif - [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0}, -}; - -int tenthdb2master(int tdb) -{ - /* Just go from tenth of dB to half to dB */ - return tdb / 5; -} - void audiohw_preinit(void) { imx233_audioout_preinit(); @@ -69,7 +45,7 @@ void audiohw_close(void) void audiohw_set_headphone_vol(int vol_l, int vol_r) { - imx233_audioout_set_hp_vol(vol_l, vol_r); + imx233_audioout_set_hp_vol(vol_l / 5, vol_r / 5); } void audiohw_set_frequency(int fsel) diff --git a/firmware/drivers/audio/mas35xx.c b/firmware/drivers/audio/mas35xx.c index e6cc665109..deb9223187 100644 --- a/firmware/drivers/audio/mas35xx.c +++ b/firmware/drivers/audio/mas35xx.c @@ -26,36 +26,6 @@ #include "system.h" /* MAX MIN macros */ #include "audiohw.h" -const struct sound_settings_info audiohw_settings[] = { -#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) - [SOUND_VOLUME] = {"dB", 0, 1,-100, 12, -25}, - [SOUND_BASS] = {"dB", 0, 1, -12, 12, 6}, - [SOUND_TREBLE] = {"dB", 0, 1, -12, 12, 6}, -#elif CONFIG_CODEC == MAS3507D - [SOUND_VOLUME] = {"dB", 0, 1, -78, 18, -18}, - [SOUND_BASS] = {"dB", 0, 1, -15, 15, 7}, - [SOUND_TREBLE] = {"dB", 0, 1, -15, 15, 7}, -#endif - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) - [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0}, - [SOUND_AVC] = {"", 0, 1, -1, 4, 0}, - [SOUND_MDB_STRENGTH] = {"dB", 0, 1, 0, 127, 48}, - [SOUND_MDB_HARMONICS] = {"%", 0, 1, 0, 100, 50}, - [SOUND_MDB_CENTER] = {"Hz", 0, 10, 20, 300, 60}, - [SOUND_MDB_SHAPE] = {"Hz", 0, 10, 50, 300, 90}, - [SOUND_MDB_ENABLE] = {"", 0, 1, 0, 1, 0}, - [SOUND_SUPERBASS] = {"", 0, 1, 0, 1, 0}, -#endif -#if CONFIG_CODEC == MAS3587F && defined(HAVE_RECORDING) - [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 15, 8}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 15, 8}, - [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 15, 2}, -#endif -}; - int channel_configuration = SOUND_CHAN_STEREO; int stereo_width = 100; @@ -65,7 +35,6 @@ unsigned long loudness_shadow = 0; unsigned long shadow_io_control_main; #endif - static void set_channel_config(void) { /* default values: stereo */ @@ -185,6 +154,22 @@ void audiohw_set_treble(int val) #endif } +#if (CONFIG_CODEC == MAS3507D) +/* convert tenth of dB volume (-780..+180) to dac3550 register value */ +static unsigned int tenthdb2reg(int db) +{ + if (db < -540) /* 3 dB steps */ + return (db + 780) / 30; + else /* 1.5 dB steps */ + return (db + 660) / 15; +} + +void audiohw_set_volume(int vol_l, int vol_r) +{ + dac_volume(tenthdb2reg(vol_l), tenthdb2reg(vol_r), false); +} +#endif /* CONFIG_CODEC == MAS3507D */ + #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) void audiohw_set_volume(int val) { @@ -268,14 +253,32 @@ void audiohw_set_balance(int val) mas_codec_writereg(MAS_REG_BALANCE, tmp); } -void audiohw_set_pitch(unsigned long val) +/* This functionality works by telling the decoder that we have another + crystal frequency than we actually have. It will adjust its internal + parameters and the result is that the audio is played at another pitch. +*/ +static int32_t last_pitch = PITCH_SPEED_100; + +void audiohw_set_pitch(int32_t val) { - mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1); + if (val == last_pitch) + return; + + /* Calculate the new (bogus) frequency */ + unsigned long reg = 18432 * PITCH_SPEED_100 / val; + mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, ®, 1); /* We must tell the MAS that the frequency has changed. * This will unfortunately cause a short silence. */ + mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, + &shadow_io_control_main, 1); - mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1); + last_pitch = val; +} + +int32_t audiohw_get_pitch(void) +{ + return last_pitch; } #endif /* CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F */ diff --git a/firmware/drivers/audio/rk27xx_codec.c b/firmware/drivers/audio/rk27xx_codec.c index 6f71214df4..aada17cc0a 100644 --- a/firmware/drivers/audio/rk27xx_codec.c +++ b/firmware/drivers/audio/rk27xx_codec.c @@ -27,21 +27,6 @@ #include "system.h" #include "i2c-rk27xx.h" -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, -34, 4, -25}, - /* HAVE_SW_TONE_CONTROLS */ - [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, - [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -#ifdef HAVE_RECORDING /* disabled for now */ - [SOUND_LEFT_GAIN] = {"dB", 2, 75, -1725, 3000, 0}, - [SOUND_RIGHT_GAIN] = {"dB", 2, 75, -1725, 3000, 0}, - [SOUND_MIC_GAIN] = {"dB", 0, 1, 0, 20, 20}, -#endif -}; - /* private functions to read/write codec registers */ static int codec_write(uint8_t reg, uint8_t val) { @@ -66,7 +51,7 @@ static void audiohw_mute(bool mute) } /* public functions */ -int tenthdb2master(int tdb) +static int vol_tenthdb2hw(int tdb) { /* we lie here a bit and present 0.5dB gain steps * but codec has 'variable' gain steps (0.5, 1.0, 2.0) @@ -150,6 +135,8 @@ void audiohw_set_frequency(int fsel) void audiohw_set_master_vol(int vol_l, int vol_r) { + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); if (vol_l > 31 || vol_r > 31) { diff --git a/firmware/drivers/audio/sdl.c b/firmware/drivers/audio/sdl.c index 3c7cc55ce9..eea10ad12c 100644 --- a/firmware/drivers/audio/sdl.c +++ b/firmware/drivers/audio/sdl.c @@ -32,107 +32,32 @@ #ifdef HAVE_SW_VOLUME_CONTROL #include "pcm_sw_volume.h" -void audiohw_set_master_vol(int vol_l, int vol_r) +void audiohw_set_volume(int vol_l, int vol_r) { pcm_set_master_volume(vol_l, vol_r); } + #else /* ndef HAVE_SW_VOLUME_CONTROL */ + extern void pcm_set_mixer_volume(int); void audiohw_set_volume(int volume) { #if CONFIG_CODEC == SWCODEC -#if (CONFIG_PLATFORM & PLATFORM_MAEMO5) +#if !(CONFIG_PLATFORM & PLATFORM_MAEMO5) + if (volume < VOLUME_MIN) + volume = 0; + else + volume = SDL_MIX_MAXVOLUME * (volume - VOLUME_MIN + ONE_DB) / + (VOLUME_RANGE + ONE_DB); +#endif /* !(CONFIG_PLATFORM & PLATFORM_MAEMO5) */ + pcm_set_mixer_volume(volume); -#else - pcm_set_mixer_volume( - SDL_MIX_MAXVOLUME * ((volume - VOLUME_MIN) / 10) / (VOLUME_RANGE / 10)); -#endif /* (CONFIG_PLATFORM & PLATFORM_MAEMO5) */ -#else - (void)volume; #endif /* CONFIG_CODEC == SWCODEC */ + (void)volume; } #endif /* HAVE_SW_VOLUME_CONTROL */ -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25}, -/* Bass and treble tone controls */ -#ifdef AUDIOHW_HAVE_BASS - [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, -#endif -#ifdef AUDIOHW_HAVE_TREBLE - [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, -#endif - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -#if defined(HAVE_RECORDING) - [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, - [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, -#endif -#if defined(AUDIOHW_HAVE_BASS_CUTOFF) - [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1}, -#endif -#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) - [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1}, -#endif -#if defined(AUDIOHW_HAVE_DEPTH_3D) - [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0}, -#endif -/* Hardware EQ tone controls */ -#if defined(AUDIOHW_HAVE_EQ_BAND1) - [SOUND_EQ_BAND1_GAIN] = {"dB", 0, 1, -12, 12, 0}, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND2) - [SOUND_EQ_BAND2_GAIN] = {"dB", 0, 1, -12, 12, 0}, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND3) - [SOUND_EQ_BAND3_GAIN] = {"dB", 0, 1, -12, 12, 0}, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND4) - [SOUND_EQ_BAND4_GAIN] = {"dB", 0, 1, -12, 12, 0}, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND5) - [SOUND_EQ_BAND5_GAIN] = {"dB", 0, 1, -12, 12, 0}, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) - [SOUND_EQ_BAND1_FREQUENCY] = {"", 0, 1, 1, 4, 1}, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY) - [SOUND_EQ_BAND2_FREQUENCY] = {"", 0, 1, 1, 4, 1}, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY) - [SOUND_EQ_BAND3_FREQUENCY] = {"", 0, 1, 1, 4, 1}, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY) - [SOUND_EQ_BAND4_FREQUENCY] = {"", 0, 1, 1, 4, 1}, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY) - [SOUND_EQ_BAND5_FREQUENCY] = {"", 0, 1, 1, 4, 1}, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH) - [SOUND_EQ_BAND2_WIDTH] = {"", 0, 1, 0, 1, 0}, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) - [SOUND_EQ_BAND3_WIDTH] = {"", 0, 1, 0, 1, 0}, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH) - [SOUND_EQ_BAND4_WIDTH] = {"", 0, 1, 0, 1, 0}, -#endif - -#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) - [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0}, - [SOUND_AVC] = {"", 0, 1, -1, 4, 0}, - [SOUND_MDB_STRENGTH] = {"dB", 0, 1, 0, 127, 48}, - [SOUND_MDB_HARMONICS] = {"%", 0, 1, 0, 100, 50}, - [SOUND_MDB_CENTER] = {"Hz", 0, 10, 20, 300, 60}, - [SOUND_MDB_SHAPE] = {"Hz", 0, 10, 50, 300, 90}, - [SOUND_MDB_ENABLE] = {"", 0, 1, 0, 1, 0}, - [SOUND_SUPERBASS] = {"", 0, 1, 0, 1, 0}, -#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ -}; - /** * stubs here, for the simulator **/ @@ -149,12 +74,14 @@ void audiohw_set_prescaler(int value) #if defined(AUDIOHW_HAVE_BALANCE) void audiohw_set_balance(int value) { (void)value; } #endif +#ifndef HAVE_SW_TONE_CONTROLS #if defined(AUDIOHW_HAVE_BASS) void audiohw_set_bass(int value) { (void)value; } #endif #if defined(AUDIOHW_HAVE_TREBLE) void audiohw_set_treble(int value) { (void)value; } #endif +#endif /* HAVE_SW_TONE_CONTROLS */ #if CONFIG_CODEC != SWCODEC void audiohw_set_channel(int value) { (void)value; } void audiohw_set_stereo_width(int value){ (void)value; } @@ -182,6 +109,10 @@ void audiohw_set_eq_band_width(unsigned int band, int value) void audiohw_set_depth_3d(int value) { (void)value; } #endif +#if defined(AUDIOHW_HAVE_LINEOUT) +void audiohw_set_lineout_volume(int vol_l, int vol_r) + { (void)vol_l; (void)vol_r; } +#endif void audiohw_close(void) {} diff --git a/firmware/drivers/audio/tlv320.c b/firmware/drivers/audio/tlv320.c index 6b96ed212f..23d2fea3a1 100644 --- a/firmware/drivers/audio/tlv320.c +++ b/firmware/drivers/audio/tlv320.c @@ -46,8 +46,8 @@ const struct sound_settings_info audiohw_settings[] = { #endif }; -/* convert tenth of dB volume (-840..0) to master volume register value */ -int tenthdb2master(int db) +/* convert tenth of dB volume (-73..6) to master volume register value */ +static int vol_tenthdb2hw(int db) { /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ /* 1111111 == +6dB (0x7f) */ @@ -210,8 +210,11 @@ void audiohw_set_frequency(int fsel) * * Left & Right: 48 .. 121 .. 127 => Volume -73dB (mute) .. +0 dB .. +6 dB */ -void audiohw_set_headphone_vol(int vol_l, int vol_r) +void audiohw_set_volume(int vol_l, int vol_r) { + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); + unsigned value_dap = tlv320_regs[REG_DAP]; unsigned value_dap_last = value_dap; unsigned value_l = LHV_LHV(vol_l); diff --git a/firmware/drivers/audio/tsc2100.c b/firmware/drivers/audio/tsc2100.c index 6479f84b34..41327ae3d7 100644 --- a/firmware/drivers/audio/tsc2100.c +++ b/firmware/drivers/audio/tsc2100.c @@ -29,18 +29,9 @@ #include "sound.h" #include "tsc2100.h" -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN/10, VOLUME_MAX/10, -25}, - /* HAVE_SW_TONE_CONTROLS */ - [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, - [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -}; static bool is_muted = false; -/* convert tenth of dB volume to master volume register value */ -int tenthdb2master(int db) +/* convert tenth of dB volume to volume register value */ +static int vol_tenthdb2hw(int db) { /* 0 to -63.0dB in 1dB steps, tsc2100 can goto -63.5 in 0.5dB steps */ if (db < VOLUME_MIN) { @@ -52,27 +43,6 @@ int tenthdb2master(int db) } } -int sound_val2phys(int setting, int value) -{ - int result; - - switch(setting) - { -#if 0 - case SOUND_LEFT_GAIN: - case SOUND_RIGHT_GAIN: - case SOUND_MIC_GAIN: - result = (value - 23) * 15; - break; -#endif - default: - result = value; - break; - } - - return result; -} - void audiohw_init(void) { short val = tsc2100_readreg(TSAC4_PAGE, TSAC4_ADDRESS); @@ -104,9 +74,12 @@ void audiohw_postinit(void) audiohw_mute(false); } -void audiohw_set_master_vol(int vol_l, int vol_r) +void audiohw_set_master_volume(int vol_l, int vol_r) { - tsc2100_writereg(TSDACGAIN_PAGE, TSDACGAIN_ADDRESS, (short)((vol_l<<8) | vol_r) ); + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); + tsc2100_writereg(TSDACGAIN_PAGE, TSDACGAIN_ADDRESS, + (short)((vol_l<<8) | vol_r) ); } void audiohw_close(void) diff --git a/firmware/drivers/audio/uda1341.c b/firmware/drivers/audio/uda1341.c index 6b38353afe..ac3bcedb7d 100644 --- a/firmware/drivers/audio/uda1341.c +++ b/firmware/drivers/audio/uda1341.c @@ -28,23 +28,8 @@ #include "audiohw.h" - -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, -84, 0, -25}, - [SOUND_BASS] = {"dB", 0, 2, 0, 24, 0}, - [SOUND_TREBLE] = {"dB", 0, 2, 0, 6, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, /* not used */ - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, /* not used */ - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, /* not used */ -#ifdef HAVE_RECORDING - [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, - [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, -#endif -}; - -/* convert tenth of dB volume (-600..0) to master volume register value */ -int tenthdb2master(int db) +/* convert tenth of dB volume (-600..0) to volume register value */ +static int vol_tenthdb2hw(int db) { if (db < -600) return 63; @@ -229,11 +214,12 @@ void audiohw_set_prescaler(int val) #endif /* AUDIOHW_HAVE_PRESCALER */ /** - * Sets left and right master volume (1(max) to 62(muted)) + * Set master volume (1(max) to 62(muted)) */ -void audiohw_set_master_vol(int vol_l, int vol_r) +void audiohw_set_volume(int volume) { - uda_regs[UDA_REG_ID_CTRL0] = (vol_l + vol_r) / 2; + volume = vol_tenthdb2hw(volume) / 2; + uda_regs[UDA_REG_ID_CTRL0] = volume; udacodec_write (UDA_REG_DATA0, UDA_DATA_CTRL0 | uda_regs[UDA_REG_ID_CTRL0]); } diff --git a/firmware/drivers/audio/uda1380.c b/firmware/drivers/audio/uda1380.c index fd32b398ca..9d6ece105b 100644 --- a/firmware/drivers/audio/uda1380.c +++ b/firmware/drivers/audio/uda1380.c @@ -40,22 +40,8 @@ #define USE_WSPLL #endif -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, -84, 0, -25}, - [SOUND_BASS] = {"dB", 0, 2, 0, 24, 0}, - [SOUND_TREBLE] = {"dB", 0, 2, 0, 6, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -#ifdef HAVE_RECORDING - [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, - [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, -#endif -}; - /* convert tenth of dB volume (-840..0) to master volume register value */ -int tenthdb2master(int db) +static int vol_tenthdb2hw(int db) { if (db < -720) /* 1.5 dB steps */ return (2940 - db) / 15; @@ -68,7 +54,7 @@ int tenthdb2master(int db) } /* convert tenth of dB volume (-780..0) to mixer volume register value */ -int tenthdb2mixer(int db) +static int mixer_tenthdb2hw(int db) { if (db < -660) /* 1.5 dB steps */ return (2640 - db) / 15; @@ -138,19 +124,12 @@ static int uda1380_write_reg(unsigned char reg, unsigned short value) /** * Sets left and right master volume (0(max) to 252(muted)) */ -void audiohw_set_master_vol(int vol_l, int vol_r) +void audiohw_set_volume(int vol_l, int vol_r) { + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); uda1380_write_reg(REG_MASTER_VOL, - MASTER_VOL_LEFT(vol_l) | MASTER_VOL_RIGHT(vol_r)); -} - -/** - * Sets mixer volume for both channels (0(max) to 228(muted)) - */ -void audiohw_set_mixer_vol(int channel1, int channel2) -{ - uda1380_write_reg(REG_MIX_VOL, - MIX_VOL_CH_1(channel1) | MIX_VOL_CH_2(channel2)); + MASTER_VOL_LEFT(vol_l) | MASTER_VOL_RIGHT(vol_r)); } /** @@ -285,7 +264,9 @@ void audiohw_postinit(void) void audiohw_set_prescaler(int val) { - audiohw_set_mixer_vol(tenthdb2mixer(-val), tenthdb2mixer(-val)); + val = mixer_tenthdb2hw(-val); + uda1380_write_reg(REG_MIX_VOL, + MIX_VOL_CH_1(val) | MIX_VOL_CH_2(val)); } /* Nice shutdown of UDA1380 codec */ diff --git a/firmware/drivers/audio/wm8731.c b/firmware/drivers/audio/wm8731.c index 71050454f3..3689a28f31 100644 --- a/firmware/drivers/audio/wm8731.c +++ b/firmware/drivers/audio/wm8731.c @@ -37,22 +37,6 @@ #include "wmcodec.h" #include "sound.h" - -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25}, - /* HAVE_SW_TONE_CONTROLS */ - [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, - [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -#if defined(HAVE_WM8731) && defined(HAVE_RECORDING) - [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23}, - [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 0}, -#endif -}; - /* Init values/shadows * Ignore bit 8 since that only specifies "both" for updating * gains - "RESET" (15h) not included */ @@ -109,22 +93,6 @@ static void wmc_write_masked(int reg, unsigned bits, unsigned mask) wmc_write(reg, (wmc_regs[reg] & ~mask) | (bits & mask)); } -/* convert tenth of dB volume (-730..60) to master volume register value */ -int tenthdb2master(int db) -{ - /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ - /* 1111111 == +6dB (0x7f) */ - /* 1111001 == 0dB (0x79) */ - /* 0110000 == -73dB (0x30 */ - /* 0101111 == mute (0x2f) */ - - if (db < VOLUME_MIN) { - return 0x2f; - } else { - return((db/10)+0x30+73); - } -} - int sound_val2phys(int setting, int value) { int result; @@ -148,6 +116,21 @@ int sound_val2phys(int setting, int value) return result; } +/* convert tenth of dB volume (-730..60) to master volume register value */ +static int vol_tenthdb2hw(int db) +{ + /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ + /* 1111111 == +6dB (0x7f) */ + /* 1111001 == 0dB (0x79) */ + /* 0110000 == -73dB (0x30) */ + /* 0101111 == mute (0x2f) */ + if (db < VOLUME_MIN) { + return 0x2f; + } else { + return((db/10)+0x30+73); + } +} + static void audiohw_mute(bool mute) { if (mute) { @@ -207,13 +190,11 @@ void audiohw_postinit(void) #endif } -void audiohw_set_master_vol(int vol_l, int vol_r) +void audiohw_set_volume(int vol_l, int vol_r) { /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ - /* 1111111 == +6dB */ - /* 1111001 == 0dB */ - /* 0110000 == -73dB */ - /* 0101111 == mute (0x2f) */ + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); wmc_write_masked(LOUTVOL, vol_l, WMC_OUT_VOL_MASK); wmc_write_masked(ROUTVOL, vol_r, WMC_OUT_VOL_MASK); } diff --git a/firmware/drivers/audio/wm8751.c b/firmware/drivers/audio/wm8751.c index 4cb85db436..feba05e504 100644 --- a/firmware/drivers/audio/wm8751.c +++ b/firmware/drivers/audio/wm8751.c @@ -32,35 +32,6 @@ #include "system.h" #include "sound.h" -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25}, - [SOUND_BASS] = {"dB", 1, 15, -60, 90, 0}, - [SOUND_TREBLE] = {"dB", 1, 15, -60, 90, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -#ifdef HAVE_RECORDING - /* PGA -17.25dB to 30.0dB in 0.75dB increments 64 steps - * digital gain 0dB to 30.0dB in 0.5dB increments - * we use 0.75dB fake steps through whole range - * - * This combined gives -17.25 to 60.0dB - */ - [SOUND_LEFT_GAIN] = {"dB", 2, 75, -1725, 6000, 0}, - [SOUND_RIGHT_GAIN] = {"dB", 2, 75, -1725, 6000, 0}, - [SOUND_MIC_GAIN] = {"dB", 2, 75, -1725, 6000, 3000}, -#endif -#ifdef AUDIOHW_HAVE_BASS_CUTOFF - [SOUND_BASS_CUTOFF] = {"Hz", 0, 70, 130, 200, 200}, -#endif -#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF - [SOUND_TREBLE_CUTOFF] = {"kHz", 0, 4, 4, 8, 4}, -#endif -#ifdef AUDIOHW_HAVE_DEPTH_3D - [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0}, -#endif -}; - static uint16_t wmcodec_regs[WM_NUM_REGS] = { [0 ... WM_NUM_REGS-1] = 0x200, /* set invalid data in gaps */ @@ -139,7 +110,7 @@ static void wmcodec_set_masked(unsigned int reg, unsigned int val, } /* convert tenth of dB volume (-730..60) to master volume register value */ -int tenthdb2master(int db) +static int vol_tenthdb2hw(int db) { /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ /* 1111111 == +6dB (0x7f) */ @@ -186,25 +157,6 @@ void audiohw_set_treble_cutoff(int val) } #endif - -int sound_val2phys(int setting, int value) -{ - int result; - - switch (setting) - { -#ifdef AUDIOHW_HAVE_DEPTH_3D - case SOUND_DEPTH_3D: - result = (100 * value + 8) / 15; - break; -#endif - default: - result = value; - } - - return result; -} - static void audiohw_mute(bool mute) { /* Mute: Set DACMU = 1 to soft-mute the audio DACs. */ @@ -335,40 +287,39 @@ void audiohw_postinit(void) #endif } -void audiohw_set_master_vol(int vol_l, int vol_r) +void audiohw_set_volume(int vol_l, int vol_r) { - /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ - /* 1111111 == +6dB */ - /* 1111001 == 0dB */ - /* 0110000 == -73dB */ - /* 0101111 == mute (0x2f) */ - + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); wmcodec_set_masked(LOUT1, LOUT1_LOUT1VOL(vol_l), LOUT1_LOUT1VOL_MASK); wmcodec_set_masked(ROUT1, ROUT1_RO1VU | ROUT1_ROUT1VOL(vol_r), ROUT1_ROUT1VOL_MASK); } -#ifdef TOSHIBA_GIGABEAT_F -void audiohw_set_lineout_vol(int vol_l, int vol_r) +#ifdef AUDIOHW_HAVE_LINEOUT +void audiohw_set_lineout_volume(int vol_l, int vol_r) { + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); wmcodec_set_masked(LOUT2, LOUT2_LOUT2VOL(vol_l), LOUT2_LOUT2VOL_MASK); wmcodec_set_masked(ROUT2, ROUT2_RO2VU | ROUT2_ROUT2VOL(vol_r), ROUT2_ROUT2VOL_MASK); } -#endif +#endif /* AUDIOHW_HAVE_LINEOUT */ void audiohw_set_bass(int value) { - wmcodec_set_masked(BASSCTRL, - BASSCTRL_BASS(tone_tenthdb2hw(value)), + value = tone_tenthdb2hw(value); + wmcodec_set_masked(BASSCTRL, BASSCTRL_BASS(value), BASSCTRL_BASS_MASK); } void audiohw_set_treble(int value) { - wmcodec_set_masked(TREBCTRL, TREBCTRL_TREB(tone_tenthdb2hw(value)), + value = tone_tenthdb2hw(value); + wmcodec_set_masked(TREBCTRL, TREBCTRL_TREB(value), TREBCTRL_TREB_MASK); } diff --git a/firmware/drivers/audio/wm8758.c b/firmware/drivers/audio/wm8758.c index aa78a7710d..3e0c88c55c 100644 --- a/firmware/drivers/audio/wm8758.c +++ b/firmware/drivers/audio/wm8758.c @@ -33,22 +33,6 @@ #include "audiohw.h" #include "sound.h" -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, -90, 6, -25}, - [SOUND_BASS] = {"dB", 0, 1, -12, 12, 0}, - [SOUND_TREBLE] = {"dB", 0, 1, -12, 12, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -#ifdef HAVE_RECORDING - [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 63, 16}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 63, 16}, - [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 63, 16}, -#endif - [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1}, - [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1}, -}; - /* shadow registers */ static unsigned short eq1_reg = EQ1_EQ3DMODE | EQ_GAIN_VALUE(0); static unsigned short eq5_reg = EQ_GAIN_VALUE(0); @@ -96,27 +80,6 @@ static void get_volume_params(int db, int *dac, int *amp) } } -int sound_val2phys(int setting, int value) -{ - int result; - - switch(setting) - { -#ifdef HAVE_RECORDING - case SOUND_LEFT_GAIN: - case SOUND_RIGHT_GAIN: - case SOUND_MIC_GAIN: - result = ((value - 16) * 15) / 2; - break; -#endif - default: - result = value; - break; - } - - return result; -} - static void audiohw_mute(bool mute) { if (mute) { diff --git a/firmware/drivers/audio/wm8975.c b/firmware/drivers/audio/wm8975.c index c46dab79de..3b9fef0dbc 100644 --- a/firmware/drivers/audio/wm8975.c +++ b/firmware/drivers/audio/wm8975.c @@ -34,20 +34,6 @@ #include "wmcodec.h" #include "audiohw.h" -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25}, - [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0}, - [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -#ifdef HAVE_RECORDING - [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 63, 23}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 63, 23}, - [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 63, 0}, -#endif -}; - static unsigned short wm8975_regs[WM8975_NUM_REGISTERS] = { [LINVOL] = LINVOL_LZCEN | 23, /* 0dB */ @@ -85,7 +71,7 @@ static void wm8975_write_or(int reg, unsigned bits) } /* convert tenth of dB volume (-730..60) to master volume register value */ -int tenthdb2master(int db) +static int vol_tenthdb2hw(int db) { /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ /* 1111111 == +6dB (0x7f) */ @@ -100,29 +86,6 @@ int tenthdb2master(int db) } } -int sound_val2phys(int setting, int value) -{ - int result; - - switch(setting) - { -#ifdef HAVE_RECORDING - case SOUND_LEFT_GAIN: - case SOUND_RIGHT_GAIN: - result = ((value - 23) * 15) / 2; - break; - case SOUND_MIC_GAIN: - result = ((value - 23) * 15) / 2 + 200; - break; -#endif - default: - result = value; - break; - } - - return result; -} - static void audiohw_mute(bool mute) { if (mute) { @@ -205,13 +168,10 @@ void audiohw_postinit(void) } #endif -void audiohw_set_master_vol(int vol_l, int vol_r) +void audiohw_set_volume(int vol_l, int vol_r) { - /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ - /* 1111111 == +6dB */ - /* 1111001 == 0dB */ - /* 0110000 == -73dB */ - /* 0101111 == mute (0x2f) */ + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); /* OUT1 */ wm8975_write(LOUT1VOL, LOUT1VOL_LO1ZC | vol_l); @@ -220,6 +180,9 @@ void audiohw_set_master_vol(int vol_l, int vol_r) void audiohw_set_lineout_vol(int vol_l, int vol_r) { + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); + /* OUT2 */ wm8975_write(LOUT2VOL, LOUT2VOL_LO2ZC | vol_l); wm8975_write(ROUT2VOL, ROUT2VOL_RO2VU | ROUT2VOL_RO2ZC | vol_r); diff --git a/firmware/drivers/audio/wm8978.c b/firmware/drivers/audio/wm8978.c index 3602bf9cb3..3a86ef204e 100644 --- a/firmware/drivers/audio/wm8978.c +++ b/firmware/drivers/audio/wm8978.c @@ -36,39 +36,6 @@ * file it may break things. */ extern void audiohw_enable_headphone_jack(bool enable); -const struct sound_settings_info audiohw_settings[] = -{ - [SOUND_VOLUME] = {"dB", 0, 1, -90, 6, -25}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, - [SOUND_EQ_BAND1_GAIN] = {"dB", 0, 1, -12, 12, 0}, - [SOUND_EQ_BAND2_GAIN] = {"dB", 0, 1, -12, 12, 0}, - [SOUND_EQ_BAND3_GAIN] = {"dB", 0, 1, -12, 12, 0}, - [SOUND_EQ_BAND4_GAIN] = {"dB", 0, 1, -12, 12, 0}, - [SOUND_EQ_BAND5_GAIN] = {"dB", 0, 1, -12, 12, 0}, - [SOUND_EQ_BAND1_FREQUENCY] = {"", 0, 1, 0, 3, 0}, - [SOUND_EQ_BAND2_FREQUENCY] = {"", 0, 1, 0, 3, 0}, - [SOUND_EQ_BAND3_FREQUENCY] = {"", 0, 1, 0, 3, 0}, - [SOUND_EQ_BAND4_FREQUENCY] = {"", 0, 1, 0, 3, 0}, - [SOUND_EQ_BAND5_FREQUENCY] = {"", 0, 1, 0, 3, 0}, - [SOUND_EQ_BAND2_WIDTH] = {"", 0, 1, 0, 1, 0}, - [SOUND_EQ_BAND3_WIDTH] = {"", 0, 1, 0, 1, 0}, - [SOUND_EQ_BAND4_WIDTH] = {"", 0, 1, 0, 1, 0}, - [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0}, -#ifdef HAVE_RECORDING - /* Digital: -119.0dB to +8.0dB in 0.5dB increments - * Analog: Relegated to volume control - * Circumstances unfortunately do not allow a great deal of positive - * gain. */ - [SOUND_LEFT_GAIN] = {"dB", 1, 1,-238, 16, 0}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-238, 16, 0}, -#if 0 - [SOUND_MIC_GAIN] = {"dB", 1, 1,-238, 16, 0}, -#endif -#endif -}; - static uint16_t wmc_regs[WMC_NUM_REGISTERS] = { /* Initialized with post-reset default values - the 2-wire interface @@ -184,9 +151,9 @@ static void wmc_write_masked(unsigned int reg, unsigned int bits, wmc_write(reg, (wmc_regs[reg] & ~mask) | (bits & mask)); } -/* convert tenth of dB volume (-890..60) to master volume register value +/* convert tenth of dB volume (-890..60) to volume register value * (000000...111111) */ -int tenthdb2master(int db) +static int vol_tenthdb2hw(int db) { /* -90dB to +6dB 1dB steps (96 levels) 7bits */ /* 1100000 == +6dB (0x60,96) */ @@ -194,7 +161,7 @@ int tenthdb2master(int db) /* 1000001 == -57dB (0x21,33,DAC) */ /* 0000001 == -89dB (0x01,01) */ /* 0000000 == -90dB (0x00,00,Mute) */ - if (db <= VOLUME_MIN) + if (db < VOLUME_MIN) { return 0x0; } @@ -204,39 +171,6 @@ int tenthdb2master(int db) } } -int sound_val2phys(int setting, int value) -{ - int result; - - switch (setting) - { -#ifdef HAVE_RECORDING - case SOUND_LEFT_GAIN: - case SOUND_RIGHT_GAIN: - case SOUND_MIC_GAIN: - result = value * 5; - break; -#endif - - case SOUND_EQ_BAND1_GAIN+0x10000: - case SOUND_EQ_BAND2_GAIN+0x10000: - case SOUND_EQ_BAND3_GAIN+0x10000: - case SOUND_EQ_BAND4_GAIN+0x10000: - case SOUND_EQ_BAND5_GAIN+0x10000: - result = value * 10; - break; - - case SOUND_DEPTH_3D: - result = (100 * value + 8) / 15; - break; - - default: - result = value; - } - - return result; -} - void audiohw_preinit(void) { /* 1. Turn on external power supplies. Wait for supply voltage to settle. */ @@ -350,13 +284,16 @@ static void sync_prescaler(void) WMC_DVOL); } -void audiohw_set_headphone_vol(int vol_l, int vol_r) +void audiohw_set_volume(int vol_l, int vol_r) { int prev_l = wmc_vol.vol_l; int prev_r = wmc_vol.vol_r; int dac_l, dac_r, hp_l, hp_r; int mix_l, mix_r, boost_l, boost_r; + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); + wmc_vol.vol_l = vol_l; wmc_vol.vol_r = vol_r; diff --git a/firmware/drivers/audio/wm8985.c b/firmware/drivers/audio/wm8985.c index 06b3fa3b44..2d49e706c8 100644 --- a/firmware/drivers/audio/wm8985.c +++ b/firmware/drivers/audio/wm8985.c @@ -88,32 +88,12 @@ #define OUT4MIX 0x39 #define BIASCTL 0x3d -const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, -90, 6, -25}, - [SOUND_BASS] = {"dB", 0, 1, -12, 12, 0}, - [SOUND_TREBLE] = {"dB", 0, 1, -12, 12, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -#ifdef HAVE_RECORDING - [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, - [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, -#endif -#ifdef AUDIOHW_HAVE_BASS_CUTOFF - [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1}, -#endif -#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF - [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1}, -#endif -}; - /* shadow registers */ static unsigned int eq1_reg; static unsigned int eq5_reg; /* convert tenth of dB volume (-89..6) to master volume register value */ -int tenthdb2master(int db) +static int vol_tenthdb2hw(int db) { /* Might have no sense, taken from wm8758.c : att DAC AMP result @@ -216,9 +196,13 @@ void audiohw_postinit(void) audiohw_mute(0); } -void audiohw_set_headphone_vol(int vol_l, int vol_r) +void audiohw_set_volume(int vol_l, int vol_r) { int dac_l, amp_l, dac_r, amp_r; + + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); + get_volume_params(vol_l, &dac_l, &_l); get_volume_params(vol_r, &dac_r, &_r); @@ -232,15 +216,19 @@ void audiohw_set_headphone_vol(int vol_l, int vol_r) wmcodec_write(ROUT1VOL, amp_r | 0x180); } -void audiohw_set_lineout_vol(int vol_l, int vol_r) +void audiohw_set_lineout_volume(int vol_l, int vol_r) { - int dac_l, amp_l, dac_r, amp_r; - get_volume_params(vol_l, &dac_l, &_l); - get_volume_params(vol_r, &dac_r, &_r); + int dac_l, amp_l, dac_r, amp_r; + + vol_l = vol_tenthdb2hw(vol_l); + vol_r = vol_tenthdb2hw(vol_r); + + get_volume_params(vol_l, &dac_l, &_l); + get_volume_params(vol_r, &dac_r, &_r); - /* set lineout amp OUT2 */ - wmcodec_write(LOUT2VOL, amp_l); - wmcodec_write(ROUT2VOL, amp_r | 0x100); + /* set lineout amp OUT2 */ + wmcodec_write(LOUT2VOL, amp_l); + wmcodec_write(ROUT2VOL, amp_r | 0x100); } void audiohw_set_aux_vol(int vol_l, int vol_r) diff --git a/firmware/export/aic3x.h b/firmware/export/aic3x.h index 4cfa0a5535..65e1ebd62c 100644 --- a/firmware/export/aic3x.h +++ b/firmware/export/aic3x.h @@ -25,12 +25,10 @@ #define VOLUME_MIN -630 #define VOLUME_MAX 0 -extern int tenthdb2master(int db); +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -64, 0, -25) /*** definitions ***/ -extern void audiohw_set_headphone_vol(int vol_l, int vol_r); - -extern void aic3x_switch_output(bool stereo); +void aic3x_switch_output(bool stereo); /* Page 0 registers */ #define AIC3X_PAGE_SELECT 0 diff --git a/firmware/export/ak4537.h b/firmware/export/ak4537.h index 1f272d41fc..abf2a378ae 100644 --- a/firmware/export/ak4537.h +++ b/firmware/export/ak4537.h @@ -26,9 +26,7 @@ #define VOLUME_MIN -1270 #define VOLUME_MAX 0 -extern int tenthdb2master(int db); - -extern void audiohw_set_master_vol(int vol_l, int vol_r); +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -128, 0, -25) #define AKC_NUM_REGS 0x11 diff --git a/firmware/export/as3514.h b/firmware/export/as3514.h index 85da14493f..e9e48fab63 100644 --- a/firmware/export/as3514.h +++ b/firmware/export/as3514.h @@ -24,11 +24,32 @@ #include "config.h" -extern int tenthdb2master(int db); +#if 0 +#define AUDIOHW_CAPS (LINEOUT_CAP | LIN_GAIN_CAP | MIC_GAIN_CAP) +#endif -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_sampr_dividers(int fsel); +#define AUDIOHW_CAPS (LIN_GAIN_CAP | MIC_GAIN_CAP) + +/*different volume ranges for different AMS chips*/ +#if CONFIG_CPU == AS3525v2 +/* Headphone volume goes from -81.0 ... +6dB */ +#define VOLUME_MIN -810 +#define VOLUME_MAX 60 +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -82, 6, -25) +#else /* AS3525v1 */ +/* Headphone volume goes from -73.5 ... +6dB */ +#define VOLUME_MIN -735 +#define VOLUME_MAX 60 +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -25) +#endif /* CONFIG_CPU == AS3525v2 */ + +#ifdef HAVE_RECORDING +AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 39, 23, (val - 23) * 15) +AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 31, 23, (val - 23) * 15) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 31, 23, (val - 23) * 15) +#endif /* HAVE_RECORDING */ + +void audiohw_set_sampr_dividers(int fsel); /* Register Descriptions */ @@ -126,16 +147,6 @@ extern void audiohw_set_sampr_dividers(int fsel); #define AS3514_UID_LEN 16 #endif -/*different volume ranges for different AMS chips*/ -#if CONFIG_CPU == AS3525v2 -/* Headphone volume goes from -81.0 ... +6dB */ -#define VOLUME_MIN -810 -#else -/* Headphone volume goes from -73.5 ... +6dB */ -#define VOLUME_MIN -735 -#endif -#define VOLUME_MAX 60 - /*** Audio Registers ***/ /* 00h (LINE_OUT_R) to 16h (AUDIOSET3) */ diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h index 304c5aa460..e18e996282 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h @@ -35,6 +35,35 @@ #define TREBLE_CUTOFF_CAP (1 << 6) #define EQ_CAP (1 << 7) #define DEPTH_3D_CAP (1 << 8) +#define LINEOUT_CAP (1 << 9) +#define MONO_VOL_CAP (1 << 10) +#define LIN_GAIN_CAP (1 << 11) +#define MIC_GAIN_CAP (1 << 12) + +/* Used by every driver to export its min/max/default values for its audio + settings. */ +#ifdef AUDIOHW_IS_SOUND_C +/* This is the master file with the settings table... */ +struct sound_settings_info +{ + const char *unit; + char numdecimals; + char steps; + short minval; + short maxval; + short defaultval; +}; + +#define AUDIOHW_SETTING(name, us, nd, st, minv, maxv, defv, expr...) \ + static const struct sound_settings_info _audiohw_setting_##name = \ + { .unit = us, .numdecimals = nd, .steps = st, \ + .minval = minv, .maxval = maxv, .defaultval = defv }; \ + static inline int _sound_val2phys_##name(int val) \ + { return #expr[0] ? expr : val; } +#else +/* ...otherwise these produce nothing. */ +#define AUDIOHW_SETTING(name, us, nd, st, minv, maxv, defv, expr...) +#endif #ifdef HAVE_UDA1380 #include "uda1380.h" @@ -78,17 +107,25 @@ #include "imx233-codec.h" #elif defined(HAVE_DUMMY_CODEC) #include "dummy_codec.h" -#endif -#if (CONFIG_PLATFORM & (PLATFORM_ANDROID|PLATFORM_MAEMO|PLATFORM_PANDORA|PLATFORM_SDL)) -/* #include gives errors in other code areas, - * we don't really need it here, so don't. but it should maybe be fixed */ -#ifndef SIMULATOR /* simulator gets values from the target .h files */ -#define VOLUME_MIN -990 -#define VOLUME_MAX 0 -#endif +#elif (CONFIG_PLATFORM & (PLATFORM_ANDROID | PLATFORM_MAEMO\ + | PLATFORM_PANDORA | PLATFORM_SDL)) +#include "hosted_codec.h" #endif +#if defined(SIMULATOR) && !defined(HAVE_SW_VOLUME_CONTROL) +/* For now, without software volume control, sim only supports mono control */ +#define AUDIOHW_HAVE_MONO_VOLUME +#endif +/* Some values are the same for every codec and can be defined here one + time. */ +#ifdef HAVE_SW_TONE_CONTROLS +AUDIOHW_SETTING(BASS, "dB", 0, 1, -24, 24, 0) +AUDIOHW_SETTING(TREBLE, "dB", 0, 1, -24, 24, 0) +#endif /* HAVE_SW_TONE_CONTROLS */ +AUDIOHW_SETTING(BALANCE, "%", 0, 1, -100, 100, 0) +AUDIOHW_SETTING(CHANNELS, "", 0, 1, 0, 5, 0) +AUDIOHW_SETTING(STEREO_WIDTH, "%", 0, 5, 0, 250, 100) #define ONE_DB 10 @@ -246,7 +283,26 @@ enum AUDIOHW_EQ_SETTINGS #if (AUDIOHW_CAPS & DEPTH_3D_CAP) #define AUDIOHW_HAVE_DEPTH_3D #endif -#else + +#if (AUDIOHW_CAPS & LINEOUT_CAP) +#define AUDIOHW_HAVE_LINEOUT +#endif + +#if (AUDIOHW_CAPS & MONO_VOL_CAP) +#define AUDIOHW_HAVE_MONO_VOLUME +#endif + +#ifdef HAVE_RECORDING +#if (AUDIOHW_CAPS & LIN_GAIN_CAP) +#define AUDIOHW_HAVE_LIN_GAIN +#endif + +#if (AUDIOHW_CAPS & MIC_GAIN_CAP) +#define AUDIOHW_HAVE_MIC_GAIN +#endif +#endif /* HAVE_RECORDING */ + +#else /* ndef AUDIOHW_CAPS */ #if defined (HAVE_SW_TONE_CONTROLS) /* Needed for proper sound support */ #define AUDIOHW_HAVE_BASS @@ -255,6 +311,7 @@ enum AUDIOHW_EQ_SETTINGS #endif /* AUDIOHW_CAPS */ enum { + /* TODO: Volume shouldn't be needed if device doesn't have digital control */ SOUND_VOLUME = 0, /* Tone control */ #if defined(AUDIOHW_HAVE_BASS) @@ -276,9 +333,11 @@ enum { SOUND_MDB_ENABLE, SOUND_SUPERBASS, #endif -#if defined(HAVE_RECORDING) +#if defined(AUDIOHW_HAVE_LIN_GAIN) SOUND_LEFT_GAIN, SOUND_RIGHT_GAIN, +#endif +#if defined(AUDIOHW_HAVE_MIC_GAIN) SOUND_MIC_GAIN, #endif /* Bass and treble tone controls */ @@ -339,7 +398,8 @@ enum { SOUND_LAST_SETTING, /* Keep this last */ }; -enum Channel { +enum Channel +{ SOUND_CHAN_STEREO, SOUND_CHAN_MONO, SOUND_CHAN_CUSTOM, @@ -349,19 +409,6 @@ enum Channel { SOUND_CHAN_NUM_MODES, }; -struct sound_settings_info { - const char *unit; - char numdecimals; - char steps; - short minval; - short maxval; - short defaultval; -}; - -/* This struct is used by every driver to export its min/max/default values for - * its audio settings. Keep in mind that the order must be correct! */ -extern const struct sound_settings_info audiohw_settings[]; - /* All usable functions implemented by a audio codec drivers. Most of * the function in sound settings are only called, when in audio codecs * .h file suitable defines are added. @@ -390,17 +437,35 @@ void audiohw_postinit(void); */ void audiohw_close(void); -#if defined(AUDIOHW_HAVE_CLIPPING) || defined(HAVE_SDL_AUDIO) || defined(ANDROID) - /** +#ifdef AUDIOHW_HAVE_MONO_VOLUME + /** * Set new volume value * @param val to set. * NOTE: AUDIOHW_CAPS need to contain * CLIPPING_CAP */ void audiohw_set_volume(int val); +#else /* Stereo volume */ +/** + * Set new voluem value for each channel + * @param vol_l sets left channel volume + * @param vol_r sets right channel volume + */ +void audiohw_set_volume(int vol_l, int vol_r); +#endif /* AUDIOHW_HAVE_MONO_VOLUME */ + +#ifdef AUDIOHW_HAVE_LINEOUT + /** + * Set new voluem value for each channel + * @param vol_l sets left channel volume + * @param vol_r sets right channel volume + */ +void audiohw_set_lineout_volume(int vol_l, int vol_r); #endif -#ifdef AUDIOHW_HAVE_PRESCALER +#ifndef AUDIOHW_HAVE_CLIPPING +#if defined(AUDIOHW_HAVE_BASS) || defined(AUDIOHW_HAVE_TREBLE) \ + || defined(AUDIOHW_HAVE_EQ) /** * Set new prescaler value. * @param val to set. @@ -409,6 +474,7 @@ void audiohw_set_volume(int val); */ void audiohw_set_prescaler(int val); #endif +#endif /* !AUDIOHW_HAVE_CLIPPING */ #ifdef AUDIOHW_HAVE_BALANCE /** @@ -552,31 +618,38 @@ void audiohw_set_recvol(int left, int right, int type); void audiohw_set_monitor(bool enable); #endif - - -#if CONFIG_CODEC != SWCODEC - -/* functions which are only used by mas35xx codecs, but are also - aviable on SWCODECS through dsp */ - /** * Set channel configuration. * @param val new channel value (see enum Channel). */ void audiohw_set_channel(int val); +#ifdef HAVE_PITCHCONTROL +/** + * Set the pitch ratio + * @param ratio to set in .01% units + */ +void audiohw_set_pitch(int32_t val); + +/** + * Return the set pitch ratio + */ +int32_t audiohw_get_pitch(void); +#endif /* HAVE_PITCHCONTROL */ + /** * Set stereo width. * @param val new stereo width value. */ void audiohw_set_stereo_width(int val); -#endif /* CONFIG_CODEC != SWCODEC */ - #ifdef HAVE_SPEAKER - void audiohw_enable_speaker(bool on); - #endif /* HAVE_SPEAKER */ +#if CONFIG_CODEC == SWCODEC +typedef int (*audiohw_swcodec_cb_type)(int msg, intptr_t param); +void audiohw_swcodec_set_callback(audiohw_swcodec_cb_type func); +#endif /* CONFIG_CODEC == SWCODEC */ + #endif /* _AUDIOHW_H_ */ diff --git a/firmware/export/audiohw_settings.h b/firmware/export/audiohw_settings.h new file mode 100644 index 0000000000..8efbc0dbe7 --- /dev/null +++ b/firmware/export/audiohw_settings.h @@ -0,0 +1,143 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2005 by Linus Nielsen Feltzing + * Copyright (C) 2007 by Christian Gmeiner + * Copyright (C) 2013 by Michael Sevakis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#if defined(AUDIOHW_SOUND_SETTINGS_ENTRIES) +/* Define sound_setting_entries table */ + +#define AUDIOHW_SETTINGS(...) \ + static const struct sound_setting_entry \ + { \ + const struct sound_settings_info *info; \ + sound_set_type *function; \ + } sound_setting_entries[] = \ + { \ + [0 ... SOUND_LAST_SETTING-1] = { NULL, NULL }, \ + __VA_ARGS__ \ + }; + +#define AUDIOHW_SETTING_ENT(name, fn) \ + [SOUND_##name] = { .info = &_audiohw_setting_##name, .function = fn }, + +#elif defined(AUDIOHW_SOUND_SETTINGS_VAL2PHYS) + +/* Implements sound_val2phys */ +#define AUDIOHW_SETTINGS(...) \ + int sound_val2phys(int setting, int value) \ + { \ + switch (setting) \ + { \ + __VA_ARGS__ \ + default: \ + return value; \ + } \ + } + +#define AUDIOHW_SETTING_ENT(name, fn) \ + case SOUND_##name: return _sound_val2phys_##name(value); + +#endif /* setting table type selection */ + +AUDIOHW_SETTINGS( + /* TODO: Volume shouldn't be needed if device doesn't have digital + control */ + AUDIOHW_SETTING_ENT(VOLUME, sound_set_volume) +#if defined(AUDIOHW_HAVE_BASS) + AUDIOHW_SETTING_ENT(BASS, sound_set_bass) +#endif +#if defined(AUDIOHW_HAVE_TREBLE) + AUDIOHW_SETTING_ENT(TREBLE, sound_set_treble) +#endif + AUDIOHW_SETTING_ENT(BALANCE, sound_set_balance) + AUDIOHW_SETTING_ENT(CHANNELS, sound_set_channels) + AUDIOHW_SETTING_ENT(STEREO_WIDTH, sound_set_stereo_width) +#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) + AUDIOHW_SETTING_ENT(LOUDNESS, sound_set_loudness) + AUDIOHW_SETTING_ENT(AVC, sound_set_avc) + AUDIOHW_SETTING_ENT(MDB_STRENGTH, sound_set_mdb_strength) + AUDIOHW_SETTING_ENT(MDB_HARMONICS, sound_set_mdb_harmonics) + AUDIOHW_SETTING_ENT(MDB_CENTER, sound_set_mdb_center) + AUDIOHW_SETTING_ENT(MDB_SHAPE, sound_set_mdb_shape) + AUDIOHW_SETTING_ENT(MDB_ENABLE, sound_set_mdb_enable) + AUDIOHW_SETTING_ENT(SUPERBASS, sound_set_superbass) +#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ +#if defined(AUDIOHW_HAVE_LIN_GAIN) + AUDIOHW_SETTING_ENT(LEFT_GAIN, NULL) + AUDIOHW_SETTING_ENT(RIGHT_GAIN, NULL) +#endif +#if defined(AUDIOHW_HAVE_MIC_GAIN) + AUDIOHW_SETTING_ENT(MIC_GAIN, NULL) +#endif +#if defined(AUDIOHW_HAVE_BASS_CUTOFF) + AUDIOHW_SETTING_ENT(BASS_CUTOFF, sound_set_bass_cutoff) +#endif +#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) + AUDIOHW_SETTING_ENT(TREBLE_CUTOFF, sound_set_treble_cutoff) +#endif +#if defined(AUDIOHW_HAVE_DEPTH_3D) + AUDIOHW_SETTING_ENT(DEPTH_3D, sound_set_depth_3d) +#endif +/* Hardware EQ tone controls */ +#if defined(AUDIOHW_HAVE_EQ) + AUDIOHW_SETTING_ENT(EQ_BAND1_GAIN, sound_set_hw_eq_band1_gain) +#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) + AUDIOHW_SETTING_ENT(EQ_BAND1_FREQUENCY, sound_set_hw_eq_band1_frequency) +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND2) + AUDIOHW_SETTING_ENT(EQ_BAND2_GAIN, sound_set_hw_eq_band2_gain) +#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY) + AUDIOHW_SETTING_ENT(EQ_BAND2_FREQUENCY, sound_set_hw_eq_band2_frequency) +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH) + AUDIOHW_SETTING_ENT(EQ_BAND2_WIDTH, sound_set_hw_eq_band2_width) +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND2 */ +#if defined(AUDIOHW_HAVE_EQ_BAND3) + AUDIOHW_SETTING_ENT(EQ_BAND3_GAIN, sound_set_hw_eq_band3_gain) +#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY) + AUDIOHW_SETTING_ENT(EQ_BAND3_FREQUENCY, sound_set_hw_eq_band3_frequency) +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) + AUDIOHW_SETTING_ENT(EQ_BAND3_WIDTH, sound_set_hw_eq_band3_width) +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND3 */ +#if defined(AUDIOHW_HAVE_EQ_BAND4) + AUDIOHW_SETTING_ENT(EQ_BAND4_GAIN, sound_set_hw_eq_band4_gain) +#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY) + AUDIOHW_SETTING_ENT(EQ_BAND4_FREQUENCY, sound_set_hw_eq_band4_frequency) +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH) + AUDIOHW_SETTING_ENT(EQ_BAND4_WIDTH, sound_set_hw_eq_band4_width) +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND4 */ +#if defined(AUDIOHW_HAVE_EQ_BAND5) + AUDIOHW_SETTING_ENT(EQ_BAND5_GAIN, sound_set_hw_eq_band5_gain) +#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY) + AUDIOHW_SETTING_ENT(EQ_BAND5_FREQUENCY, sound_set_hw_eq_band5_frequency) +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND5 */ +#endif /* AUDIOHW_HAVE_EQ */ +); /* AUDIOHW_SETTINGS */ + +#undef AUDIOHW_SETTINGS +#undef AUDIOHW_SETTING_ENT +#undef AUDIOHW_SOUND_SETTINGS_ENTRIES +#undef AUDIOHW_SOUND_SETTINGS_VAL2PHYS diff --git a/firmware/export/cs42l55.h b/firmware/export/cs42l55.h index 86b54ef272..4584706dfd 100644 --- a/firmware/export/cs42l55.h +++ b/firmware/export/cs42l55.h @@ -26,14 +26,16 @@ #define VOLUME_MIN -580 #define VOLUME_MAX 120 -#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP \ - | TREBLE_CUTOFF_CAP | PRESCALER_CAP) +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP | \ + TREBLE_CUTOFF_CAP | PRESCALER_CAP | LINEOUT_CAP) -extern int tenthdb2master(int db); +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -60, 12, -25) +AUDIOHW_SETTING(BASS, "dB", 1, 15,-105, 120, 0) +AUDIOHW_SETTING(TREBLE, "dB", 1, 15,-105, 120, 0) +AUDIOHW_SETTING(BASS_CUTOFF, "", 0, 1, 1, 4, 2) +AUDIOHW_SETTING(TREBLE_CUTOFF, "", 0, 1, 1, 4, 1) -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_enable_lineout(bool enable); +void audiohw_enable_lineout(bool enable); /* Register addresses and bits */ @@ -480,5 +482,4 @@ extern void audiohw_enable_lineout(bool enable); #define HIDDEN3F 0x3f #define HIDDEN3F_DEFAULT 0x46 - #endif /* __CS42L55_H__ */ diff --git a/firmware/export/dac3550a.h b/firmware/export/dac3550a.h index 23c4db9cbc..50bf922e90 100644 --- a/firmware/export/dac3550a.h +++ b/firmware/export/dac3550a.h @@ -37,7 +37,6 @@ #define DAC_GCFG 3 /* function prototypes */ -extern int tenthdb2reg(int db); extern int dac_volume(unsigned int left, unsigned int right, bool deemph); extern void dac_enable(bool enable); extern void dac_line_in(bool enable); diff --git a/firmware/export/dummy_codec.h b/firmware/export/dummy_codec.h index 122b55ef2f..90fd7b03c2 100644 --- a/firmware/export/dummy_codec.h +++ b/firmware/export/dummy_codec.h @@ -25,6 +25,6 @@ #define VOLUME_MIN -730 #define VOLUME_MAX 0 -void audiohw_set_master_vol(int vol_l, int vol_r); +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, VOLUME_MIN/10, VOLUME_MAX/10, 0) #endif /* __DUMMY_CODEC_H_ */ diff --git a/firmware/export/hosted_codec.h b/firmware/export/hosted_codec.h new file mode 100644 index 0000000000..50d1281394 --- /dev/null +++ b/firmware/export/hosted_codec.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Thomas Martitz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef HOSTED_CODEC_H +#define HOSTED_CODEC_H + +#define VOLUME_MIN -990 +#define VOLUME_MAX 0 + +#define AUDIOHW_CAPS (MONO_VOL_CAP) +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -100, 0, 0) + +#endif /* HOSTED_CODEC_H */ \ No newline at end of file diff --git a/firmware/export/imx233-codec.h b/firmware/export/imx233-codec.h index 6c329ccd1a..2fbd8bde59 100644 --- a/firmware/export/imx233-codec.h +++ b/firmware/export/imx233-codec.h @@ -27,10 +27,19 @@ #define VOLUME_MIN -1000 #define VOLUME_MAX 60 -#define AUDIOHW_CAPS (DEPTH_3D_CAP | BASS_CAP | TREBLE_CAP) +#define AUDIOHW_CAPS (DEPTH_3D_CAP | BASS_CAP | TREBLE_CAP | \ + LIN_GAIN_CAP | MIC_GAIN_CAP) /* Work with half dB since the i.MX233 doesn't have a better resolution */ -int tenthdb2master(int tdb); -void audiohw_set_headphone_vol(int vol_l, int vol_r); + +/* i.MX233 has half dB steps */ +AUDIOHW_SETTING(VOLUME, "dB", 0, 1,-101, 6, -25) +/* HAVE_SW_TONE_CONTROLS */ +#ifdef HAVE_RECORDING +AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 31, 23) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 31, 23) +AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 1, 1) +#endif /* HAVE_RECORDING */ +AUDIOHW_SETTING(DEPTH_3D, "%", 0, 1, 0, 15, 0) #endif /* __IMX233_CODEC_H_ */ diff --git a/firmware/export/jz4740-codec.h b/firmware/export/jz4740-codec.h index 3c088f5bf7..fc731fdf50 100644 --- a/firmware/export/jz4740-codec.h +++ b/firmware/export/jz4740-codec.h @@ -24,6 +24,17 @@ #define VOLUME_MIN -730 #define VOLUME_MAX 60 -void audiohw_set_master_vol(int vol_l, int vol_r); +/* TODO */ +#ifdef HAVE_SW_VOLUME_CONTROL +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -25) +#else +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, 0, 6, 0) +#endif /* HAVE_SW_VOLUME_CONTROL */ + +#ifdef HAVE_RECORDING +AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 31, 23) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 31, 23) +AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 1, 1) +#endif /* HAVE_RECORDING */ #endif /* __JZ4740_CODEC_H_ */ diff --git a/firmware/export/mas35xx.h b/firmware/export/mas35xx.h index f75658fce1..7643e0efdc 100644 --- a/firmware/export/mas35xx.h +++ b/firmware/export/mas35xx.h @@ -39,6 +39,14 @@ #if CONFIG_CODEC == MAS3507D +#define VOLUME_MIN -780 +#define VOLUME_MAX 180 +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP) + +AUDIOHW_SETTING(SOUND_VOLUME, "dB", 0, 1, -78, 18, -18) +AUDIOHW_SETTING(SOUND_BASS, "dB", 0, 1, -15, 15, 7) +AUDIOHW_SETTING(SOUND_TREBLE, "dB", 0, 1, -15, 15, 7) + /* I2C defines */ #define MAS_ADR 0x3a #define MAS_DEV_WRITE (MAS_ADR | 0x00) @@ -71,10 +79,6 @@ #define MAS_D0_OUT_RL 0x7fa #define MAS_D0_OUT_RR 0x7fb -#define VOLUME_MIN -780 -#define VOLUME_MAX 180 -#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP) - static const unsigned int bass_table[] = { 0x9e400, /* -15dB */ @@ -167,6 +171,36 @@ static const unsigned int prescale_table[] = #else /* CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F */ +#define VOLUME_MIN -400 +#define VOLUME_MAX 600 + +AUDIOHW_SETTING(VOLUME, "dB", 0, 1,-100, 12, -25) +AUDIOHW_SETTING(BASS, "dB", 0, 1, -12, 12, 6) +AUDIOHW_SETTING(TREBLE, "dB", 0, 1, -12, 12, 6) +AUDIOHW_SETTING(LOUDNESS, "dB", 0, 1, 0, 17, 0) +AUDIOHW_SETTING(AVC "", 0, 1, -1, 4, 0) +AUDIOHW_SETTING(MDB_STRENGTH, "dB", 0, 1, 0, 127, 48) +AUDIOHW_SETTING(MDB_HARMONICS, "%", 0, 1, 0, 100, 50) +AUDIOHW_SETTING(MDB_CENTER "Hz", 0, 10, 20, 300, 60) +AUDIOHW_SETTING(MDB_SHAPE "Hz", 0, 10, 50, 300, 90) +AUDIOHW_SETTING(MDB_ENABLE "", 0, 1, 0, 1, 0) +AUDIOHW_SETTING(SUPERBASS "", 0, 1, 0, 1, 0) + +#if CONFIG_CODEC == MAS3587F && defined(HAVE_RECORDING) +/* MAS3587F and MAS3539F handle clipping prevention internally so we do not + * need the prescaler -> CLIPPING_CAP */ +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BALANCE_CAP | CLIPPING_CAP | \ + MONO_VOL_CAP | LIN_GAIN_CAP | MIC_GAIN_CAP) +AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 15, 8, (val - 2) * 15) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 15, 8, (val - 2) * 15) +AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 15, 2, val * 15 + 210) +#else +/* MAS3587F and MAS3539F handle clipping prevention internally so we do not + * need the prescaler -> CLIPPING_CAP */ +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BALANCE_CAP | CLIPPING_CAP | \ + MONO_VOL_CAP) +#endif /* MAS3587F && HAVE_RECORDING */ + /* I2C defines */ #define MAS_ADR 0x3c #define MAS_DEV_WRITE (MAS_ADR | 0x00) @@ -248,18 +282,7 @@ static const unsigned int prescale_table[] = #define MAS_D0_CRC_ERROR_COUNT 0xfd3 #endif -/* MAS3587F and MAS3539F handle clipping prevention internally so we do not need - * the prescaler -> CLIPPING_CAP - */ - -#define VOLUME_MIN -400 -#define VOLUME_MAX 600 -#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BALANCE_CAP | CLIPPING_CAP) - -#endif /* CONFIG_CODEC */ - /* Function prototypes */ -#if CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F extern void audiohw_set_loudness(int value); extern void audiohw_set_avc(int value); extern void audiohw_set_mdb_strength(int value); @@ -269,7 +292,9 @@ extern void audiohw_set_mdb_shape(int value); extern void audiohw_set_mdb_enable(int value); extern void audiohw_set_superbass(int value); extern void audiohw_set_balance(int val); -extern void audiohw_set_pitch(unsigned long val); -#endif +extern void audiohw_set_pitch(int32_t val); +extern int audiohw_get_pitch(void); + +#endif /* CONFIG_CODEC */ #endif /* _MAS35XX_H */ diff --git a/firmware/export/rk27xx_codec.h b/firmware/export/rk27xx_codec.h index 5fdf0a0061..5a6796d63c 100644 --- a/firmware/export/rk27xx_codec.h +++ b/firmware/export/rk27xx_codec.h @@ -26,10 +26,14 @@ #define VOLUME_MIN -330 #define VOLUME_MAX 40 -#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | LIN_GAIN_CAP | MIC_GAIN_CAP) -extern int tenthdb2master(int db); -extern void audiohw_set_master_vol(int vol_l, int vol_r); +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -34, 4, -25) +#ifdef HAVE_RECORDING /* disabled for now */ +AUDIOHW_SETTING(LEFT_GAIN, "dB", 2, 75, -1725, 3000, 0) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 2, 75, -1725, 3000, 0) +AUDIOHW_SETTING(MIC_GAIN, "dB", 0, 1, 0, 20, 20) +#endif /* HAVE_RECORDING */ #define CODEC_I2C_ADDR 0x4e diff --git a/firmware/export/sound.h b/firmware/export/sound.h index ebf728c7c7..fa76c67b1f 100644 --- a/firmware/export/sound.h +++ b/firmware/export/sound.h @@ -24,17 +24,6 @@ #include #include - -#if CONFIG_CODEC == SWCODEC -enum { - DSP_CALLBACK_SET_PRESCALE = 0, - DSP_CALLBACK_SET_BASS, - DSP_CALLBACK_SET_TREBLE, - DSP_CALLBACK_SET_CHANNEL_CONFIG, - DSP_CALLBACK_SET_STEREO_WIDTH, -}; -#endif - typedef void sound_set_type(int value); const char *sound_unit(int setting); @@ -45,7 +34,6 @@ int sound_max(int setting); int sound_default(int setting); sound_set_type* sound_get_fn(int setting); -void sound_set_dsp_callback(int (*func)(int, intptr_t)); void sound_set_volume(int value); void sound_set_balance(int value); void sound_set_bass(int value); @@ -130,10 +118,8 @@ void sound_set_superbass(int value); void sound_set(int setting, int value); int sound_val2phys(int setting, int value); -#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) void sound_set_pitch(int32_t pitch); int32_t sound_get_pitch(void); -#endif #ifdef HAVE_PITCHCONTROL /* precision of the pitch and speed variables */ diff --git a/firmware/export/tlv320.h b/firmware/export/tlv320.h index 66f4d5ca92..99359f72ce 100644 --- a/firmware/export/tlv320.h +++ b/firmware/export/tlv320.h @@ -25,15 +25,33 @@ #define VOLUME_MIN -730 #define VOLUME_MAX 60 -extern int tenthdb2master(int db); +#define AUDIOHW_CAPS (LIN_GAIN_CAP | MIC_GAIN_CAP) + +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -20) +#ifdef HAVE_RECORDING + /* (x - 23)/1.5 *10 */ +AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 31, 23, (val - 23) * 15) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 31, 23, (val - 23) * 15) +/* 0 or 20 dB */ +AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 1, 1, val * 200) +#endif /* HAVE_RECORDING */ + +static inline int _param_2_phys(int setting, int value) +{ + switch(setting) + { + default: return value; +#ifdef HAVE_RECORDING + case SOUND_LEFT_GAIN: + case SOUND_RIGHT_GAIN: return (value - 23) * 15; + case SOUND_MIC_GAIN: return value * 200; /* 0 or 20 dB */ +#endif + } +} /*** definitions ***/ -extern void audiohw_set_headphone_vol(int vol_l, int vol_r); - #define HEADPHONE_MUTE 0x30 /* 0110000 = -73db */ -/* ToDo: samplerates */ - /* registers */ /* REG_LLIV: Left line input channel volume control */ #define REG_LLIV 0x0 diff --git a/firmware/export/tsc2100.h b/firmware/export/tsc2100.h index 9566c588df..4e1e7d9287 100644 --- a/firmware/export/tsc2100.h +++ b/firmware/export/tsc2100.h @@ -21,6 +21,12 @@ #ifndef __TSC2100_H_ #define __TSC2100_H_ +/* volume/balance/treble/bass interdependency */ +#define VOLUME_MIN -630 +#define VOLUME_MAX 0 + +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -64, 0, -25) + void tsc2100_read_data(void); bool tsc2100_read_touch(short *x, short* y, short *z1, short *z2); bool tsc2100_read_volt(short *bat1, short *bat2, short *aux); @@ -139,7 +145,4 @@ void tsc2100_keyclick(void); #define TSAC5_PAGE 2 #define TSAC5_ADDRESS 0x1e -extern int tenthdb2master(int db); -extern void audiohw_set_master_vol(int vol_l, int vol_r); - #endif diff --git a/firmware/export/uda1341.h b/firmware/export/uda1341.h index a43d33a137..5641bd301f 100644 --- a/firmware/export/uda1341.h +++ b/firmware/export/uda1341.h @@ -26,13 +26,16 @@ #define VOLUME_MIN -840 #define VOLUME_MAX 0 -#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | MIC_GAIN_CAP | LIN_GAIN_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); +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -84, 0, -25) +AUDIOHW_SETTING(BASS, "dB", 0, 2, 0, 24, 0) +AUDIOHW_SETTING(TREBLE, "dB", 0, 2, 0, 6, 0) +#ifdef HAVE_RECORDING +AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1,-128, 96, 0) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1,-128, 96, 0) +AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1,-128, 108, 16) +#endif /* HAVE_RECORDING */ /* These are logical register numbers for driver */ enum uda_register { diff --git a/firmware/export/uda1380.h b/firmware/export/uda1380.h index e9292cf466..a2200967dd 100644 --- a/firmware/export/uda1380.h +++ b/firmware/export/uda1380.h @@ -26,13 +26,18 @@ #define VOLUME_MIN -840 #define VOLUME_MAX 0 -#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP) +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | \ + LIN_GAIN_CAP | MIC_GAIN_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); +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -85, 0, -25) +AUDIOHW_SETTING(BASS, "dB", 0, 2, 0, 24, 0) +AUDIOHW_SETTING(TREBLE, "dB", 0, 2, 0, 6, 0) +#ifdef HAVE_RECORDING + /* (1/2) * 10 */ +AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1,-128, 96, 0, val * 5) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1,-128, 96, 0, val * 5) +AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1,-128, 108, 16, val * 5) +#endif /* HAVE_RECORDING */ #define UDA1380_ADDR 0x30 diff --git a/firmware/export/wm8731.h b/firmware/export/wm8731.h index 28d4d3940d..086c847ee1 100644 --- a/firmware/export/wm8731.h +++ b/firmware/export/wm8731.h @@ -28,9 +28,16 @@ #define VOLUME_MIN -730 #define VOLUME_MAX 60 -extern int tenthdb2master(int db); +#define AUDIOHW_CAPS (LIN_GAIN_CAP | MIC_GAIN_CAP) -extern void audiohw_set_master_vol(int vol_l, int vol_r); +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -25) +#if defined(HAVE_WM8731) && defined(HAVE_RECORDING) +/* (x - 23)/1.5 *10 */ +AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 31, 23, (val - 23) * 15) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 31, 23, (val - 23) * 15) +/* 0 or 20 dB */ +AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 1, 0, val * 200) +#endif /* defined(HAVE_WM8731) && defined(HAVE_RECORDING) */ /* Common register bits */ #ifdef HAVE_WM8731 diff --git a/firmware/export/wm8751.h b/firmware/export/wm8751.h index 3bbf744463..6e7bb245dd 100644 --- a/firmware/export/wm8751.h +++ b/firmware/export/wm8751.h @@ -25,23 +25,36 @@ #define VOLUME_MIN -730 #define VOLUME_MAX 60 -#if defined(HAVE_WM8750) #define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | \ BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP | \ - DEPTH_3D_CAP) -#else + DEPTH_3D_CAP | LIN_GAIN_CAP | MIC_GAIN_CAP) -#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | \ - BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP) -#endif +#if defined(HAVE_WM8750) +AUDIOHW_SETTING(DEPTH_3D, "%", 0, 1, 0, 15, 0, (100 * val + 8) / 15) +#ifdef HAVE_RECORDING + /* PGA -17.25dB to 30.0dB in 0.75dB increments 64 steps + * digital gain 0dB to 30.0dB in 0.5dB increments + * we use 0.75dB fake steps through whole range + * + * This combined gives -17.25 to 60.0dB + */ +AUDIOHW_SETTING(LEFT_GAIN, "dB", 2, 75,-1725, 6000, 0, val * 5) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 2, 75,-1725, 6000, 0, val * 5) +AUDIOHW_SETTING(MIC_GAIN, "dB", 2, 75,-1725, 6000, 3000, val * 5) -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); -#if defined(HAVE_WM8750) && defined(HAVE_RECORDING) void audiohw_set_recsrc(int source, bool recording); -#endif +#endif /* HAVE_RECORDING */ +#else /* !HAVE_WM8750 */ +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | \ + BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP | \ + LINEOUT_CAP) +#endif /* HAVE_WM8750 */ + +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -25) +AUDIOHW_SETTING(BASS, "dB", 1, 15, -60, 90, 0) +AUDIOHW_SETTING(TREBLE, "dB", 1, 15, -60, 90, 0) +AUDIOHW_SETTING(BASS_CUTOFF, "Hz", 0, 70, 130, 200, 200) +AUDIOHW_SETTING(TREBLE_CUTOFF, "kHz", 0, 4, 4, 8, 4) /* Register addresses and bits */ #define OUTPUT_MUTED 0x2f @@ -348,4 +361,5 @@ void audiohw_set_recsrc(int source, bool recording); #define MONOOUT_MOZC (1 << 7) #define WM_NUM_REGS 0x2b + #endif /* _WM8751_H */ diff --git a/firmware/export/wm8758.h b/firmware/export/wm8758.h index ef5567e898..89b000cf8c 100644 --- a/firmware/export/wm8758.h +++ b/firmware/export/wm8758.h @@ -26,15 +26,22 @@ #define VOLUME_MIN -890 #define VOLUME_MAX 60 -#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP) +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP | \ + TREBLE_CUTOFF_CAP | LINEOUT_CAP | LIN_GAIN_CAP | \ + MIC_GAIN_CAP) -extern int tenthdb2master(int db); -extern int tenthdb2mixer(int db); +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -90, 6, -25) +AUDIOHW_SETTING(BASS, "dB", 0, 1, -12, 12, 0) +AUDIOHW_SETTING(TREBLE, "dB", 0, 1, -12, 12, 0) +AUDIOHW_SETTING(BASS_CUTOFF, "", 0, 1, 1, 4, 1) +AUDIOHW_SETTING(TREBLE_CUTOFF, "", 0, 1, 1, 4, 1) +#ifdef HAVE_RECORDING +AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 63, 16, ((val - 23) * 15) / 2 + 200) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 63, 16, ((val - 23) * 15) / 2 + 200) +AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 63, 16, ((val - 23) * 15) / 2 + 200) +#endif /* HAVE_RECORDING */ -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_enable_lineout(bool enable); +void audiohw_enable_lineout(bool enable); #define RESET 0x00 #define RESET_RESET 0x0 diff --git a/firmware/export/wm8975.h b/firmware/export/wm8975.h index c9d0bd1bbe..f4e0d203a1 100644 --- a/firmware/export/wm8975.h +++ b/firmware/export/wm8975.h @@ -26,13 +26,19 @@ #define VOLUME_MIN -730 #define VOLUME_MAX 60 -#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | LINEOUT_CAP | \ + LIN_GAIN_CAP | MIC_GAIN_CAP) -extern int tenthdb2master(int db); +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -25) +AUDIOHW_SETTING(BASS, "dB", 0, 1, -6, 9, 0) +AUDIOHW_SETTING(TREBLE, "dB", 0, 1, -6, 9, 0) +#ifdef HAVE_RECORDING +AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 63, 23, ((val - 23) * 15) / 2) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 63, 23, ((val - 23) * 15) / 2)) +AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 63, 0, ((val - 23) * 15) / 2 + 200) +#endif /* HAVE_RECORDING */ -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_enable_lineout(bool enable); +void audiohw_enable_lineout(bool enable); /* Register addresses and bits */ diff --git a/firmware/export/wm8978.h b/firmware/export/wm8978.h index f591c1b9fb..d5ed8f184c 100644 --- a/firmware/export/wm8978.h +++ b/firmware/export/wm8978.h @@ -23,10 +23,17 @@ #ifndef _WM8978_H #define _WM8978_H -#define VOLUME_MIN -900 +#define VOLUME_MIN -890 #define VOLUME_MAX 60 -#define AUDIOHW_CAPS (EQ_CAP | PRESCALER_CAP | DEPTH_3D_CAP) +#if 0 +#define AUDIOHW_CAPS (EQ_CAP | PRESCALER_CAP | DEPTH_3D_CAP | \ + LIN_GAIN_CAP | MIC_GAIN_CAP) +#else +#define AUDIOHW_CAPS (EQ_CAP | PRESCALER_CAP | DEPTH_3D_CAP | \ + LIN_GAIN_CAP) +#endif + /* Filter bitmask */ #define AUDIOHW_EQ_BAND_CAPS ((EQ_CAP << 0) | (EQ_CAP << 1) | \ (EQ_CAP << 2) | (EQ_CAP << 3) | \ @@ -39,8 +46,33 @@ #define AUDIOHW_EQ_WIDTH_CAPS ((EQ_CAP << 1) | (EQ_CAP << 2) | \ (EQ_CAP << 3)) -int tenthdb2master(int db); -void audiohw_set_headphone_vol(int vol_l, int vol_r); +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -90, 6, -25) +AUDIOHW_SETTING(EQ_BAND1_GAIN, "dB", 0, 1, -12, 12, 0) +AUDIOHW_SETTING(EQ_BAND2_GAIN, "dB", 0, 1, -12, 12, 0) +AUDIOHW_SETTING(EQ_BAND3_GAIN, "dB", 0, 1, -12, 12, 0) +AUDIOHW_SETTING(EQ_BAND4_GAIN, "dB", 0, 1, -12, 12, 0) +AUDIOHW_SETTING(EQ_BAND5_GAIN, "dB", 0, 1, -12, 12, 0) +AUDIOHW_SETTING(EQ_BAND1_FREQUENCY, "", 0, 1, 0, 3, 0) +AUDIOHW_SETTING(EQ_BAND2_FREQUENCY, "", 0, 1, 0, 3, 0) +AUDIOHW_SETTING(EQ_BAND3_FREQUENCY, "", 0, 1, 0, 3, 0) +AUDIOHW_SETTING(EQ_BAND4_FREQUENCY, "", 0, 1, 0, 3, 0) +AUDIOHW_SETTING(EQ_BAND5_FREQUENCY, "", 0, 1, 0, 3, 0) +AUDIOHW_SETTING(EQ_BAND2_WIDTH, "", 0, 1, 0, 1, 0) +AUDIOHW_SETTING(EQ_BAND3_WIDTH, "", 0, 1, 0, 1, 0) +AUDIOHW_SETTING(EQ_BAND4_WIDTH, "", 0, 1, 0, 1, 0) +AUDIOHW_SETTING(DEPTH_3D, "%", 0, 1, 0, 15, 0, (100*val + 8) / 15) +#ifdef HAVE_RECORDING + /* Digital: -119.0dB to +8.0dB in 0.5dB increments + * Analog: Relegated to volume control + * Circumstances unfortunately do not allow a great deal of positive + * gain. */ +AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1,-238, 16, 0, val * 5) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1,-238, 16, 0, val * 5) +#if 0 /* whenever it's needed - none on GBS */ +AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1,-238, 16, 0, val * 5) +#endif /* 0 */ +#endif /* HAVE_RECORDING */ + void audiohw_set_recsrc(int source, bool recording); void wmc_set(unsigned int reg, unsigned int bits); diff --git a/firmware/export/wm8985.h b/firmware/export/wm8985.h index 4538b5edc5..a5eb59f159 100644 --- a/firmware/export/wm8985.h +++ b/firmware/export/wm8985.h @@ -29,15 +29,25 @@ #ifdef COWON_D2 /* FIXME: somehow something was out of sync in the .lang, settings and caps. Keep the * cutoffs disabled until someone with the device works it out. */ -#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP) +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | LINEOUT_CAP | \ + LIN_GAIN_CAP | MIC_GAIN_CAP) #else -#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP) +#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP | \ + TREBLE_CUTOFF_CAP | LINEOUT_CAP | LIN_GAIN_CAP | \ + MIC_GAIN_CAP) +AUDIOHW_SETTING(BASS_CUTOFF, "", 0, 1, 1, 4, 1) +AUDIOHW_SETTING(TREBLE_CUTOFF, "", 0, 1, 1, 4, 1) #endif -extern int tenthdb2master(int db); +AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -90, 6, -25) +AUDIOHW_SETTING(BASS, "dB", 0, 1, -12, 12, 0) +AUDIOHW_SETTING(TREBLE, "dB", 0, 1, -12, 12, 0) +#ifdef HAVE_RECORDING +AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1,-128, 96, 0) +AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1,-128, 96, 0) +AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1,-128, 108, 16) +#endif /* HAVE_RECORDING */ -extern void audiohw_set_headphone_vol(int vol_l, int vol_r); -extern void audiohw_set_lineout_vol(int vol_l, int vol_r); -extern void audiohw_set_aux_vol(int vol_l, int vol_r); +void audiohw_set_aux_vol(int vol_l, int vol_r); #endif /* _WM8985_H */ diff --git a/firmware/include/fixedpoint.h b/firmware/include/fixedpoint.h index 3e14bdd68e..584bd58d84 100644 --- a/firmware/include/fixedpoint.h +++ b/firmware/include/fixedpoint.h @@ -102,6 +102,11 @@ unsigned long isqrt(unsigned long x); #define FP_INF (0x7fffffff) #define FP_NEGINF -(0x7fffffff) +/** FIXED POINT EXP10 + * Return 10^x as FP integer. Argument is FP integer. + */ +long fp_exp10(long x, unsigned int fracbits); + /* fracbits in range 12 - 22 work well. Higher is better for * calculating dB, lower is better for calculating factor. */ diff --git a/firmware/sound.c b/firmware/sound.c index 7c86b0bf05..4c390f4a5b 100644 --- a/firmware/sound.c +++ b/firmware/sound.c @@ -9,6 +9,7 @@ * * Copyright (C) 2005 by Linus Nielsen Feltzing * Copyright (C) 2007 by Christian Gmeiner + * Copyright (C) 2013 by Michael Sevakis * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,141 +20,95 @@ * KIND, either express or implied. * ****************************************************************************/ -#include -#include + /* Indicate it's the sound.c file which affects compilation of audiohw.h */ +#define AUDIOHW_IS_SOUND_C #include "config.h" -#include "sound.h" -#include "logf.h" #include "system.h" -#include "i2c.h" +#include "sound.h" +#include "fixedpoint.h" #ifdef HAVE_SW_VOLUME_CONTROL #include "pcm_sw_volume.h" #endif /* HAVE_SW_VOLUME_CONTROL */ -/* TODO - * find a nice way to handle 1.5db steps -> see wm8751 ifdef in sound_set_bass/treble -*/ +/* Define sound_setting_entries table */ +#define AUDIOHW_SOUND_SETTINGS_ENTRIES +#include "audiohw_settings.h" + +/* Implements sound_val2phys */ +#define AUDIOHW_SOUND_SETTINGS_VAL2PHYS +#include "audiohw_settings.h" extern bool audio_is_initialized; -const char *sound_unit(int setting) +static const struct sound_setting_entry * get_setting_entry(int setting) { - return audiohw_settings[setting].unit; + static const struct sound_settings_info default_info = + { "", 0, 0, 0, 0, 0 }; + + static const struct sound_setting_entry default_entry = + { &default_info, NULL }; + + if ((unsigned)setting >= ARRAYLEN(sound_setting_entries)) + return &default_entry; + + const struct sound_setting_entry *e = &sound_setting_entries[setting]; + return e->info ? e : &default_entry; /* setting valid but not in table? */ +} + +static const struct sound_settings_info * get_settings_info(int setting) +{ + return get_setting_entry(setting)->info; +} + +const char * sound_unit(int setting) +{ + return get_settings_info(setting)->unit; } int sound_numdecimals(int setting) { - return audiohw_settings[setting].numdecimals; + return get_settings_info(setting)->numdecimals; } int sound_steps(int setting) { - return audiohw_settings[setting].steps; + return get_settings_info(setting)->steps; } int sound_min(int setting) { - return audiohw_settings[setting].minval; + return get_settings_info(setting)->minval; } int sound_max(int setting) { - return audiohw_settings[setting].maxval; + return get_settings_info(setting)->maxval; } int sound_default(int setting) { - return audiohw_settings[setting].defaultval; + return get_settings_info(setting)->defaultval; } -static sound_set_type * const sound_set_fns[] = +sound_set_type * sound_get_fn(int setting) { - [0 ... SOUND_LAST_SETTING-1] = NULL, - [SOUND_VOLUME] = sound_set_volume, -#if defined(AUDIOHW_HAVE_BASS) - [SOUND_BASS] = sound_set_bass, -#endif -#if defined(AUDIOHW_HAVE_TREBLE) - [SOUND_TREBLE] = sound_set_treble, -#endif - [SOUND_BALANCE] = sound_set_balance, - [SOUND_CHANNELS] = sound_set_channels, - [SOUND_STEREO_WIDTH] = sound_set_stereo_width, -#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) - [SOUND_LOUDNESS] = sound_set_loudness, - [SOUND_AVC] = sound_set_avc, - [SOUND_MDB_STRENGTH] = sound_set_mdb_strength, - [SOUND_MDB_HARMONICS] = sound_set_mdb_harmonics, - [SOUND_MDB_CENTER] = sound_set_mdb_center, - [SOUND_MDB_SHAPE] = sound_set_mdb_shape, - [SOUND_MDB_ENABLE] = sound_set_mdb_enable, - [SOUND_SUPERBASS] = sound_set_superbass, -#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ -#if defined(AUDIOHW_HAVE_BASS_CUTOFF) - [SOUND_BASS_CUTOFF] = sound_set_bass_cutoff, -#endif -#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) - [SOUND_TREBLE_CUTOFF] = sound_set_treble_cutoff, -#endif -#if defined(AUDIOHW_HAVE_DEPTH_3D) - [SOUND_DEPTH_3D] = sound_set_depth_3d, -#endif -/* Hardware EQ tone controls */ -#if defined(AUDIOHW_HAVE_EQ) - [SOUND_EQ_BAND1_GAIN] = sound_set_hw_eq_band1_gain, -#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) - [SOUND_EQ_BAND1_FREQUENCY] = sound_set_hw_eq_band1_frequency, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND2) - [SOUND_EQ_BAND2_GAIN] = sound_set_hw_eq_band2_gain, -#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY) - [SOUND_EQ_BAND2_FREQUENCY] = sound_set_hw_eq_band2_frequency, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH) - [SOUND_EQ_BAND2_WIDTH] = sound_set_hw_eq_band2_width, -#endif -#endif /* AUDIOHW_HAVE_EQ_BAND2 */ -#if defined(AUDIOHW_HAVE_EQ_BAND3) - [SOUND_EQ_BAND3_GAIN] = sound_set_hw_eq_band3_gain, -#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY) - [SOUND_EQ_BAND3_FREQUENCY] = sound_set_hw_eq_band3_frequency, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) - [SOUND_EQ_BAND3_WIDTH] = sound_set_hw_eq_band3_width, -#endif -#endif /* AUDIOHW_HAVE_EQ_BAND3 */ -#if defined(AUDIOHW_HAVE_EQ_BAND4) - [SOUND_EQ_BAND4_GAIN] = sound_set_hw_eq_band4_gain, -#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY) - [SOUND_EQ_BAND4_FREQUENCY] = sound_set_hw_eq_band4_frequency, -#endif -#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH) - [SOUND_EQ_BAND4_WIDTH] = sound_set_hw_eq_band4_width, -#endif -#endif /* AUDIOHW_HAVE_EQ_BAND4 */ -#if defined(AUDIOHW_HAVE_EQ_BAND5) - [SOUND_EQ_BAND5_GAIN] = sound_set_hw_eq_band5_gain, -#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY) - [SOUND_EQ_BAND5_FREQUENCY] = sound_set_hw_eq_band5_frequency, -#endif -#endif /* AUDIOHW_HAVE_EQ_BAND5 */ -#endif /* AUDIOHW_HAVE_EQ */ -}; - -sound_set_type* sound_get_fn(int setting) -{ - return ((unsigned)setting >= ARRAYLEN(sound_set_fns)? - NULL : sound_set_fns[setting]); + return get_setting_entry(setting)->function; } -#if CONFIG_CODEC == SWCODEC -static int (*dsp_callback)(int, intptr_t) = NULL; - -void sound_set_dsp_callback(int (*func)(int, intptr_t)) +void sound_set(int setting, int value) { - dsp_callback = func; + sound_set_type *sound_set_val = sound_get_fn(setting); + + if (sound_set_val) + sound_set_val(value); +} + +/* Return the sound value scaled to centibels (tenth-decibels) */ +static int sound_value_to_cb(int setting, int value) +{ + long e = (1 - sound_numdecimals(setting)) << 16; + return fp_mul(value, fp_exp10(e, 16), 16); } -#endif #if !defined(AUDIOHW_HAVE_CLIPPING) /* @@ -165,39 +120,31 @@ void sound_set_dsp_callback(int (*func)(int, intptr_t)) * by 12 dB after processing. */ -/* all values in tenth of dB MAS3507D UDA1380 */ -static int current_volume = 0; /* -780..+180 -840.. 0 */ -static int current_balance = 0; /* -960..+960 -840..+840 */ +static int current_volume = 0; /* tenth dB */ +static int current_balance = 0; /* percent */ #ifdef AUDIOHW_HAVE_TREBLE -static int current_treble = 0; /* -150..+150 0.. +60 */ +static int current_treble = 0; /* tenth dB */ #endif #ifdef AUDIOHW_HAVE_BASS -static int current_bass = 0; /* -150..+150 0..+240 */ +static int current_bass = 0; /* tenth dB */ #endif #ifdef AUDIOHW_HAVE_EQ -static int current_eq_band_gain[AUDIOHW_EQ_BAND_NUM]; +static int current_eq_band_gain[AUDIOHW_EQ_BAND_NUM]; /* tenth dB */ #endif static void set_prescaled_volume(void) { int prescale = 0; - int l, r; -/* The codecs listed use HW tone controls but don't have suitable prescaler - * functionality, so we let the prescaler stay at 0 for these, unless - * SW tone controls are in use. This is to avoid needing the SW DSP just for - * the prescaling. - */ -#if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \ - || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \ - || defined(HAVE_WM8758) || defined(HAVE_WM8985) || defined(HAVE_UDA1341)) +#if defined(AUDIOHW_HAVE_BASS) || defined(AUDIOHW_HAVE_TREBLE) \ + || defined(AUDIOHW_HAVE_EQ) + /* Note: Having Tone + EQ isn't prohibited */ #if defined(AUDIOHW_HAVE_BASS) && defined(AUDIOHW_HAVE_TREBLE) prescale = MAX(current_bass, current_treble); #endif #if defined(AUDIOHW_HAVE_EQ) - int i; - for (i = 0; i < AUDIOHW_EQ_BAND_NUM; i++) + for (int i = 0; i < AUDIOHW_EQ_BAND_NUM; i++) prescale = MAX(current_eq_band_gain[i], prescale); #endif @@ -210,86 +157,65 @@ static void set_prescaled_volume(void) * instead (might cause clipping). */ if (current_volume + prescale > VOLUME_MAX) prescale = VOLUME_MAX - current_volume; -#endif -#if defined(AUDIOHW_HAVE_PRESCALER) audiohw_set_prescaler(prescale); -#else - dsp_callback(DSP_CALLBACK_SET_PRESCALE, prescale); -#endif - if (current_volume <= VOLUME_MIN) - prescale = 0; /* Make sure the chip gets muted at VOLUME_MIN */ + if (current_volume < VOLUME_MIN) + prescale = 0; /* Make sure the audio gets muted */ +#endif /* AUDIOHW_HAVE_BASS || AUDIOHW_HAVE_TREBLE || AUDIOHW_HAVE_EQ */ - l = r = current_volume + prescale; +#if defined(AUDIOHW_HAVE_MONO_VOLUME) + audiohw_set_volume(current_volume); +#else /* Stereo volume */ + int l = current_volume + prescale, r = l; /* Balance the channels scaled by the current volume and min volume. */ /* Subtract a dB from VOLUME_MIN to get it to a mute level */ - if (current_balance > 0) + int volshift = current_balance * VOLUME_RANGE / 100; /* tenth of dB */ + + if (volshift > 0) { - l -= ((l - (VOLUME_MIN - ONE_DB)) * current_balance) / VOLUME_RANGE; + l -= ((l - (VOLUME_MIN - ONE_DB)) * volshift) / VOLUME_RANGE; } - else if (current_balance < 0) + else if (volshift < 0) { - r += ((r - (VOLUME_MIN - ONE_DB)) * current_balance) / VOLUME_RANGE; + r += ((r - (VOLUME_MIN - ONE_DB)) * volshift) / VOLUME_RANGE; } -/* ypr0 with sdl has separate volume controls */ -#if defined(HAVE_SW_VOLUME_CONTROL) - audiohw_set_master_vol(l, r); -#elif !defined(HAVE_SDL_AUDIO) || defined(SAMSUNG_YPR0) -#if defined(HAVE_JZ4740_CODEC) - audiohw_set_master_vol(l, r); -#elif CONFIG_CODEC == MAS3507D - dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); -#elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \ - || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \ - || defined(HAVE_WM8750) || defined(HAVE_WM8751) || defined(HAVE_AS3514) \ - || defined(HAVE_TSC2100) || defined(HAVE_AK4537) || defined(HAVE_UDA1341) \ - || defined(HAVE_CS42L55) || defined(HAVE_RK27XX_CODEC) - audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r)); -#if defined(HAVE_WM8975) || defined(HAVE_WM8758) \ - || (defined(HAVE_WM8751) && defined(TOSHIBA_GIGABEAT_F)) \ - || defined(HAVE_WM8985) || defined(HAVE_CS42L55) - audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0)); -#endif + audiohw_set_volume(l, r); +#endif /* AUDIOHW_HAVE_MONO_VOLUME */ -#elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985) || defined(HAVE_IMX233_CODEC) || defined(HAVE_AIC3X) - audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r)); -#elif defined(HAVE_SDL_AUDIO) || defined(ANDROID) - audiohw_set_volume(current_volume); -#endif -#else /* HAVE_SDL_AUDIO */ - audiohw_set_volume(current_volume); -#endif /* !HAVE_SDL_AUDIO */ +#if defined(AUDIOHW_HAVE_LINEOUT) + /* For now, lineout stays at unity */ + audiohw_set_lineout_volume(0, 0); +#endif /* AUDIOHW_HAVE_LINEOUT */ + + (void)prescale; /* In case of no tone controls + mono volume */ } -#endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */ +#endif /* AUDIOIHW_HAVE_CLIPPING */ void sound_set_volume(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; #if defined(AUDIOHW_HAVE_CLIPPING) audiohw_set_volume(value); -#elif CONFIG_CPU == PNX0101 - int tmp = (60 - value * 4) & 0xff; - CODECVOL = tmp | (tmp << 8); #else - current_volume = value * 10; /* tenth of dB */ + current_volume = sound_value_to_cb(SOUND_VOLUME, value); set_prescaled_volume(); #endif } void sound_set_balance(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; -#ifdef AUDIOHW_HAVE_BALANCE +#if defined(AUDIOHW_HAVE_BALANCE) audiohw_set_balance(value); #else - current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ + current_balance = value; set_prescaled_volume(); #endif } @@ -297,24 +223,13 @@ void sound_set_balance(int value) #ifdef AUDIOHW_HAVE_BASS void sound_set_bass(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; -#if !defined(AUDIOHW_HAVE_CLIPPING) -#if defined(HAVE_WM8750) || defined(HAVE_WM8751) || defined(HAVE_CS42L55) - current_bass = value; -#else - current_bass = value * 10; -#endif -#endif - -#if defined(HAVE_SW_TONE_CONTROLS) - dsp_callback(DSP_CALLBACK_SET_BASS, current_bass); -#else audiohw_set_bass(value); -#endif #if !defined(AUDIOHW_HAVE_CLIPPING) + current_bass = sound_value_to_cb(SOUND_BASS, value); set_prescaled_volume(); #endif } @@ -323,24 +238,13 @@ void sound_set_bass(int value) #ifdef AUDIOHW_HAVE_TREBLE void sound_set_treble(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; -#if !defined(AUDIOHW_HAVE_CLIPPING) -#if defined(HAVE_WM8750) || defined(HAVE_WM8751) || defined(HAVE_CS42L55) - current_treble = value; -#else - current_treble = value * 10; -#endif -#endif - -#if defined(HAVE_SW_TONE_CONTROLS) - dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble); -#else audiohw_set_treble(value); -#endif #if !defined(AUDIOHW_HAVE_CLIPPING) + current_treble = sound_value_to_cb(SOUND_TREBLE, value); set_prescaled_volume(); #endif } @@ -349,7 +253,7 @@ void sound_set_treble(int value) #if defined(AUDIOHW_HAVE_BASS_CUTOFF) void sound_set_bass_cutoff(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_bass_cutoff(value); @@ -359,7 +263,7 @@ void sound_set_bass_cutoff(int value) #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) void sound_set_treble_cutoff(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_treble_cutoff(value); @@ -368,32 +272,24 @@ void sound_set_treble_cutoff(int value) void sound_set_channels(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; -#if CONFIG_CODEC == SWCODEC - dsp_callback(DSP_CALLBACK_SET_CHANNEL_CONFIG, value); -#else audiohw_set_channel(value); -#endif } void sound_set_stereo_width(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; -#if CONFIG_CODEC == SWCODEC - dsp_callback(DSP_CALLBACK_SET_STEREO_WIDTH, value); -#else audiohw_set_stereo_width(value); -#endif } #if defined(AUDIOHW_HAVE_DEPTH_3D) void sound_set_depth_3d(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_depth_3d(value); @@ -470,13 +366,11 @@ int sound_enum_hw_eq_band_setting(unsigned int band, static void sound_set_hw_eq_band_gain(unsigned int band, int value) { - int setting; - - if(!audio_is_initialized) + if (!audio_is_initialized) return; - setting = sound_enum_hw_eq_band_setting(band, AUDIOHW_EQ_GAIN); - current_eq_band_gain[band] = sound_val2phys(setting + 0x10000, value); + int setting = sound_enum_hw_eq_band_setting(band, AUDIOHW_EQ_GAIN); + current_eq_band_gain[band] = sound_value_to_cb(setting, value); audiohw_set_eq_band_gain(band, value); set_prescaled_volume(); @@ -518,7 +412,7 @@ void sound_set_hw_eq_band5_gain(int value) #if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) void sound_set_hw_eq_band1_frequency(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND1, value); @@ -528,7 +422,7 @@ void sound_set_hw_eq_band1_frequency(int value) #if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY) void sound_set_hw_eq_band2_frequency(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND2, value); @@ -538,7 +432,7 @@ void sound_set_hw_eq_band2_frequency(int value) #if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY) void sound_set_hw_eq_band3_frequency(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND3, value); @@ -548,7 +442,7 @@ void sound_set_hw_eq_band3_frequency(int value) #if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY) void sound_set_hw_eq_band4_frequency(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND4, value); @@ -558,7 +452,7 @@ void sound_set_hw_eq_band4_frequency(int value) #if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY) void sound_set_hw_eq_band5_frequency(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND5, value); @@ -568,7 +462,7 @@ void sound_set_hw_eq_band5_frequency(int value) #if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH) void sound_set_hw_eq_band2_width(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_eq_band_width(AUDIOHW_EQ_BAND2, value); @@ -578,7 +472,7 @@ void sound_set_hw_eq_band2_width(int value) #if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) void sound_set_hw_eq_band3_width(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_eq_band_width(AUDIOHW_EQ_BAND3, value); @@ -588,7 +482,7 @@ void sound_set_hw_eq_band3_width(int value) #if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH) void sound_set_hw_eq_band4_width(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_eq_band_width(AUDIOHW_EQ_BAND4, value); @@ -596,10 +490,10 @@ void sound_set_hw_eq_band4_width(int value) #endif #endif /* AUDIOHW_HAVE_EQ */ -#if ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)) +#if CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F void sound_set_loudness(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_loudness(value); @@ -607,7 +501,7 @@ void sound_set_loudness(int value) void sound_set_avc(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_avc(value); @@ -615,7 +509,7 @@ void sound_set_avc(int value) void sound_set_mdb_strength(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_mdb_strength(value); @@ -623,7 +517,7 @@ void sound_set_mdb_strength(int value) void sound_set_mdb_harmonics(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_mdb_harmonics(value); @@ -631,7 +525,7 @@ void sound_set_mdb_harmonics(int value) void sound_set_mdb_center(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_mdb_center(value); @@ -639,7 +533,7 @@ void sound_set_mdb_center(int value) void sound_set_mdb_shape(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_mdb_shape(value); @@ -647,7 +541,7 @@ void sound_set_mdb_shape(int value) void sound_set_mdb_enable(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_mdb_enable(value); @@ -655,158 +549,27 @@ void sound_set_mdb_enable(int value) void sound_set_superbass(int value) { - if(!audio_is_initialized) + if (!audio_is_initialized) return; audiohw_set_superbass(value); } -#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ - -void sound_set(int setting, int value) -{ - sound_set_type* sound_set_val = sound_get_fn(setting); - if (sound_set_val) - sound_set_val(value); -} - -#if (!defined(HAVE_AS3514) && !defined(HAVE_WM8975) \ - && !defined(HAVE_WM8758) && !defined(HAVE_TSC2100) \ - && !defined (HAVE_WM8711) && !defined (HAVE_WM8721) \ - && !defined (HAVE_WM8731) && !defined (HAVE_WM8978) \ - && !defined (HAVE_WM8750) && !defined (HAVE_WM8751) \ - && !defined(HAVE_AK4537)) || defined(SIMULATOR) -int sound_val2phys(int setting, int value) -{ -#if CONFIG_CODEC == MAS3587F - int result = 0; - - switch(setting) - { - case SOUND_LEFT_GAIN: - case SOUND_RIGHT_GAIN: - result = (value - 2) * 15; - break; - - case SOUND_MIC_GAIN: - result = value * 15 + 210; - break; - - default: - result = value; - break; - } - return result; -#elif defined(HAVE_UDA1380) - int result = 0; - - switch(setting) - { -#ifdef HAVE_RECORDING - case SOUND_LEFT_GAIN: - case SOUND_RIGHT_GAIN: - case SOUND_MIC_GAIN: - result = value * 5; /* (1/2) * 10 */ - break; -#endif - default: - result = value; - break; - } - return result; -#elif defined(HAVE_TLV320) || defined(HAVE_WM8711) \ - || defined(HAVE_WM8721) || defined(HAVE_WM8731) - int result = 0; - - switch(setting) - { -#ifdef HAVE_RECORDING - case SOUND_LEFT_GAIN: - case SOUND_RIGHT_GAIN: - result = (value - 23) * 15; /* (x - 23)/1.5 *10 */ - break; - - case SOUND_MIC_GAIN: - result = value * 200; /* 0 or 20 dB */ - break; -#endif - default: - result = value; - break; - } - return result; -#elif defined(HAVE_AS3514) - /* This is here for the sim only and the audio driver has its own */ - int result; - - switch(setting) - { -#ifdef HAVE_RECORDING - case SOUND_LEFT_GAIN: - case SOUND_RIGHT_GAIN: - case SOUND_MIC_GAIN: - result = (value - 23) * 15; - break; -#endif - default: - result = value; - break; - } - - return result; -#elif defined(HAVE_WM8978) || defined(HAVE_WM8750) || defined(HAVE_WM8751) - int result; - - switch (setting) - { -#ifdef HAVE_RECORDING - case SOUND_LEFT_GAIN: - case SOUND_RIGHT_GAIN: - case SOUND_MIC_GAIN: - result = value * 5; - break; -#endif -#ifdef AUDIOHW_HAVE_DEPTH_3D - case SOUND_DEPTH_3D: - result = (100 * value + 8) / 15; - break; -#endif - default: - result = value; - } - - return result; -#else - (void)setting; - return value; -#endif -} -#endif /* CONFIG_CODECs || PLATFORM_HOSTED */ - -#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) -/* This function works by telling the decoder that we have another - crystal frequency than we actually have. It will adjust its internal - parameters and the result is that the audio is played at another pitch. -*/ - -static int last_pitch = PITCH_SPEED_100; +#endif /* CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F */ +#ifdef HAVE_PITCHCONTROL void sound_set_pitch(int32_t pitch) { - unsigned long val; + if (!audio_is_initialized) + return; - if (pitch != last_pitch) - { - /* Calculate the new (bogus) frequency */ - val = 18432 * PITCH_SPEED_100 / pitch; - - audiohw_set_pitch(val); - - last_pitch = pitch; - } + audiohw_set_pitch(pitch); } int32_t sound_get_pitch(void) { - return last_pitch; + if (!audio_is_initialized) + return PITCH_SPEED_100; + + return audiohw_get_pitch(); } -#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ +#endif /* HAVE_PITCHCONTROL */ diff --git a/firmware/target/arm/pnx0101/pcm-pnx0101.c b/firmware/target/arm/pnx0101/pcm-pnx0101.c index bb11ad32fe..a2394bc355 100644 --- a/firmware/target/arm/pnx0101/pcm-pnx0101.c +++ b/firmware/target/arm/pnx0101/pcm-pnx0101.c @@ -209,3 +209,9 @@ const void * pcm_play_dma_get_peak_buffer(int *count) *count = cnt >> 2; return (void *)((addr + 2) & ~3); } + +void audiohw_set_volume(int value) +{ + int tmp = (60 - value * 4) & 0xff; + CODECVOL = tmp | (tmp << 8); +} diff --git a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c index 065433e12a..eae89cf78b 100644 --- a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c @@ -26,30 +26,6 @@ #include "system.h" #include "pcm_sw_volume.h" -/* TODO */ -const struct sound_settings_info audiohw_settings[] = { -#ifdef HAVE_SW_VOLUME_CONTROL - [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25}, -#else - [SOUND_VOLUME] = {"dB", 0, 1, 0, 6, 0}, -#endif - /* HAVE_SW_TONE_CONTROLS */ -#ifdef AUDIOHW_HAVE_BASS - [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, -#endif -#ifdef AUDIOHW_HAVE_TREBLE - [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, -#endif - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, -#ifdef HAVE_RECORDING - [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23}, - [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 1}, -#endif -}; - #if 0 static unsigned short codec_volume; static unsigned short codec_base_gain; diff --git a/lib/rbcodec/dsp/dsp_misc.c b/lib/rbcodec/dsp/dsp_misc.c index a8c9423cfb..672212b267 100644 --- a/lib/rbcodec/dsp/dsp_misc.c +++ b/lib/rbcodec/dsp/dsp_misc.c @@ -35,38 +35,6 @@ #endif #include -/** Firmware callback interface **/ - -/* 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: - tone_set_prescale(param); - break; - case DSP_CALLBACK_SET_BASS: - tone_set_bass(param); - break; - case DSP_CALLBACK_SET_TREBLE: - tone_set_treble(param); - break; -#endif /* HAVE_SW_TONE_CONTROLS */ - case DSP_CALLBACK_SET_CHANNEL_CONFIG: - channel_mode_set_config(param); - break; - case DSP_CALLBACK_SET_STEREO_WIDTH: - channel_mode_custom_set_width(param); - break; - default: - break; - } - - return 0; -} - /** Replaygain settings **/ static struct replaygain_settings current_settings; static struct dsp_replay_gains current_gains; @@ -153,12 +121,7 @@ static void dsp_pitch_update(struct dsp_config *dsp) (int64_t)pitch_ratio * data->format.codec_frequency / PITCH_SPEED_100; } -int32_t sound_get_pitch(void) -{ - return pitch_ratio; -} - -void sound_set_pitch(int32_t percent) +static void dsp_set_pitch(int32_t percent) { pitch_ratio = percent > 0 ? percent : PITCH_SPEED_100; struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO); @@ -167,6 +130,50 @@ void sound_set_pitch(int32_t percent) } #endif /* HAVE_PITCHCONTROL */ + +/** Firmware callback interface **/ + +/* Hook back from firmware/ part of audio, which can't/shouldn't call apps/ + * code directly. */ +int dsp_callback(int msg, intptr_t param) +{ + int retval = 0; + + switch (msg) + { +#ifdef HAVE_SW_TONE_CONTROLS + case DSP_CALLBACK_SET_PRESCALE: + tone_set_prescale(param); + break; + case DSP_CALLBACK_SET_BASS: + tone_set_bass(param); + break; + case DSP_CALLBACK_SET_TREBLE: + tone_set_treble(param); + break; +#endif /* HAVE_SW_TONE_CONTROLS */ + case DSP_CALLBACK_SET_CHANNEL_CONFIG: + channel_mode_set_config(param); + break; + case DSP_CALLBACK_SET_STEREO_WIDTH: + channel_mode_custom_set_width(param); + break; +#ifdef HAVE_PITCHCONTROL + case DSP_CALLBACK_SET_PITCH: + dsp_set_pitch(param); + break; + case DSP_CALLBACK_GET_PITCH: + retval = pitch_ratio; + break; +#endif /* HAVE_PITCHCONTROL */ + default: + break; + } + + return retval; +} + + /* This is a null-processing stage that monitors as an enabled stage but never * becomes active in processing samples. It only hooks messages. */ diff --git a/lib/rbcodec/dsp/dsp_misc.h b/lib/rbcodec/dsp/dsp_misc.h index d658374eaf..2583f495c3 100644 --- a/lib/rbcodec/dsp/dsp_misc.h +++ b/lib/rbcodec/dsp/dsp_misc.h @@ -54,12 +54,18 @@ struct dsp_replay_gains void dsp_replaygain_set_settings(const struct replaygain_settings *settings); -#ifdef HAVE_PITCHCONTROL -void sound_set_pitch(int32_t ratio); -int32_t sound_get_pitch(void); -#endif /* HAVE_PITCHCONTROL */ - /* Callback for firmware layers to interface */ +enum +{ + DSP_CALLBACK_SET_PRESCALE = 0, + DSP_CALLBACK_SET_BASS, + DSP_CALLBACK_SET_TREBLE, + DSP_CALLBACK_SET_CHANNEL_CONFIG, + DSP_CALLBACK_SET_STEREO_WIDTH, + DSP_CALLBACK_SET_PITCH, + DSP_CALLBACK_GET_PITCH, +}; + int dsp_callback(int msg, intptr_t param); #endif /* DSP_MISC_H */ diff --git a/lib/rbcodec/test/warble.c b/lib/rbcodec/test/warble.c index d5bc1c5aea..cd73a75542 100644 --- a/lib/rbcodec/test/warble.c +++ b/lib/rbcodec/test/warble.c @@ -354,7 +354,7 @@ static void perform_config(void) } else if (!strncmp(name, "offset=", 7)) { ci.id3->offset = atoi(val); } else if (!strncmp(name, "rate=", 5)) { - sound_set_pitch(atof(val) * PITCH_SPEED_100); + dsp_callback(DSP_CALLBACK_SET_PITCH, atof(val) * PITCH_SPEED_100); } else if (!strncmp(name, "seek=", 5)) { codec_action = CODEC_ACTION_SEEK_TIME; codec_action_param = atoi(val);