summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/fixedpoint.c2
-rw-r--r--apps/settings.c2
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/drivers/audio/aic3x.c7
-rw-r--r--firmware/drivers/audio/ak4537.c27
-rw-r--r--firmware/drivers/audio/as3514.c42
-rw-r--r--firmware/drivers/audio/audiohw-swcodec.c76
-rw-r--r--firmware/drivers/audio/cs42l55.c30
-rw-r--r--firmware/drivers/audio/dac3550a.c9
-rw-r--r--firmware/drivers/audio/dummy_codec.c12
-rw-r--r--firmware/drivers/audio/imx233-codec.c26
-rw-r--r--firmware/drivers/audio/mas35xx.c71
-rw-r--r--firmware/drivers/audio/rk27xx_codec.c19
-rw-r--r--firmware/drivers/audio/sdl.c105
-rw-r--r--firmware/drivers/audio/tlv320.c9
-rw-r--r--firmware/drivers/audio/tsc2100.c41
-rw-r--r--firmware/drivers/audio/uda1341.c26
-rw-r--r--firmware/drivers/audio/uda1380.c37
-rw-r--r--firmware/drivers/audio/wm8731.c55
-rw-r--r--firmware/drivers/audio/wm8751.c75
-rw-r--r--firmware/drivers/audio/wm8758.c37
-rw-r--r--firmware/drivers/audio/wm8975.c51
-rw-r--r--firmware/drivers/audio/wm8978.c77
-rw-r--r--firmware/drivers/audio/wm8985.c46
-rw-r--r--firmware/export/aic3x.h6
-rw-r--r--firmware/export/ak4537.h4
-rw-r--r--firmware/export/as3514.h39
-rw-r--r--firmware/export/audiohw.h149
-rw-r--r--firmware/export/audiohw_settings.h143
-rw-r--r--firmware/export/cs42l55.h15
-rw-r--r--firmware/export/dac3550a.h1
-rw-r--r--firmware/export/dummy_codec.h2
-rw-r--r--firmware/export/hosted_codec.h30
-rw-r--r--firmware/export/imx233-codec.h15
-rw-r--r--firmware/export/jz4740-codec.h13
-rw-r--r--firmware/export/mas35xx.h59
-rw-r--r--firmware/export/rk27xx_codec.h12
-rw-r--r--firmware/export/sound.h14
-rw-r--r--firmware/export/tlv320.h28
-rw-r--r--firmware/export/tsc2100.h9
-rw-r--r--firmware/export/uda1341.h17
-rw-r--r--firmware/export/uda1380.h19
-rw-r--r--firmware/export/wm8731.h13
-rw-r--r--firmware/export/wm8751.h38
-rw-r--r--firmware/export/wm8758.h25
-rw-r--r--firmware/export/wm8975.h20
-rw-r--r--firmware/export/wm8978.h40
-rw-r--r--firmware/export/wm8985.h22
-rw-r--r--firmware/include/fixedpoint.h5
-rw-r--r--firmware/sound.c489
-rw-r--r--firmware/target/arm/pnx0101/pcm-pnx0101.c6
-rw-r--r--firmware/target/mips/ingenic_jz47xx/codec-jz4740.c24
-rw-r--r--lib/rbcodec/dsp/dsp_misc.c83
-rw-r--r--lib/rbcodec/dsp/dsp_misc.h16
-rw-r--r--lib/rbcodec/test/warble.c2
55 files changed, 1009 insertions, 1233 deletions
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, &reg, 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);
+
+ last_pitch = val;
+}
- mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
+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, &amp_l);
get_volume_params(vol_r, &dac_r, &amp_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, &amp_l);
- get_volume_params(vol_r, &dac_r, &amp_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, &amp_l);
+ get_volume_params(vol_r, &dac_r, &amp_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
+
+#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 */
-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);
+#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 <SDL_audio.h> 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)
-
-extern int tenthdb2master(int db);
-extern void audiohw_set_master_vol(int vol_l, int vol_r);
+#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | LIN_GAIN_CAP | MIC_GAIN_CAP)
+
+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 <inttypes.h>
#include <audiohw.h>
-
-#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)
-
-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);
+#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | MIC_GAIN_CAP | LIN_GAIN_CAP)
+
+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)
-
-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);
+#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | \
+ LIN_GAIN_CAP | MIC_GAIN_CAP)
+
+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);
-
-extern void audiohw_set_master_vol(int vol_l, int vol_r);
+#define AUDIOHW_CAPS (LIN_GAIN_CAP | MIC_GAIN_CAP)
+
+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
-
-extern int tenthdb2master(int db);
+#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 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)
-
-extern int tenthdb2master(int db);
-extern int tenthdb2mixer(int db);
-
-extern void audiohw_set_master_vol(int vol_l, int vol_r);
-extern void audiohw_set_lineout_vol(int vol_l, int vol_r);
-extern void audiohw_set_mixer_vol(int channel1, int channel2);
-extern void audiohw_enable_lineout(bool enable);
+#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BASS_CUTOFF_CAP | \
+ TREBLE_CUTOFF_CAP | LINEOUT_CAP | LIN_GAIN_CAP | \
+ MIC_GAIN_CAP)
+
+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 */
+
+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)
-
-extern int tenthdb2master(int db);
-
-extern void audiohw_set_master_vol(int vol_l, int vol_r);
-extern void audiohw_set_lineout_vol(int vol_l, int vol_r);
-extern void audiohw_enable_lineout(bool enable);
+#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | LINEOUT_CAP | \
+ LIN_GAIN_CAP | MIC_GAIN_CAP)
+
+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 */
+
+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 <stdbool.h>
-#include <stdio.h>
+ /* 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 */
-};
+ return get_setting_entry(setting)->function;
+}
-sound_set_type* sound_get_fn(int setting)
+void sound_set(int setting, int value)
{
- return ((unsigned)setting >= ARRAYLEN(sound_set_fns)?
- NULL : sound_set_fns[setting]);
-}
+ sound_set_type *sound_set_val = sound_get_fn(setting);
-#if CONFIG_CODEC == SWCODEC
-static int (*dsp_callback)(int, intptr_t) = NULL;
+ if (sound_set_val)
+ sound_set_val(value);
+}
-void sound_set_dsp_callback(int (*func)(int, intptr_t))
+/* Return the sound value scaled to centibels (tenth-decibels) */
+static int sound_value_to_cb(int setting, int value)
{
- dsp_callback = func;
+ 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 (pitch != last_pitch)
- {
- /* Calculate the new (bogus) frequency */
- val = 18432 * PITCH_SPEED_100 / pitch;
-
- audiohw_set_pitch(val);
+ if (!audio_is_initialized)
+ return;
- 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 <string.h>
-/** 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);