summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2021-04-08 23:58:49 -0400
committerSolomon Peachy <pizza@shaftnet.org>2021-04-08 23:58:49 -0400
commit1e2a9a651c26b7526530428b248132e02624bb84 (patch)
tree190d6e83db300c43481c62b94d2ff7d4cc59db08
parente86d90905be290ff24a774e9687eca3236953490 (diff)
downloadrockbox-1e2a9a651c26b7526530428b248132e02624bb84.tar.gz
rockbox-1e2a9a651c26b7526530428b248132e02624bb84.zip
erosq: Switch to 32-bit PCM output, and do volume scaling in driver
Should improve audio output quality, especially at lower volumes. Change-Id: I31c38f05fe4b554b092511f0fe7aaad9f346f6c5
-rw-r--r--firmware/drivers/audio/erosqlinux_codec.c19
-rw-r--r--firmware/export/config/aigoerosq.h3
-rw-r--r--firmware/export/erosqlinux_codec.h2
-rw-r--r--firmware/target/hosted/pcm-alsa.c2
4 files changed, 14 insertions, 12 deletions
diff --git a/firmware/drivers/audio/erosqlinux_codec.c b/firmware/drivers/audio/erosqlinux_codec.c
index b1c5aa0c4f..58104a61e6 100644
--- a/firmware/drivers/audio/erosqlinux_codec.c
+++ b/firmware/drivers/audio/erosqlinux_codec.c
@@ -169,6 +169,10 @@ void audiohw_set_frequency(int fsel)
169 (void)fsel; 169 (void)fsel;
170} 170}
171 171
172/* min/max for pcm volume */
173const int min_pcm = -430;
174const int max_pcm = 0;
175
172void audiohw_set_volume(int vol_l, int vol_r) 176void audiohw_set_volume(int vol_l, int vol_r)
173{ 177{
174 logf("hw vol %d %d", vol_l, vol_r); 178 logf("hw vol %d %d", vol_l, vol_r);
@@ -179,7 +183,7 @@ void audiohw_set_volume(int vol_l, int vol_r)
179 vol_r_hw = vol_r; 183 vol_r_hw = vol_r;
180 184
181 if (lineout_inserted()) { 185 if (lineout_inserted()) {
182 /* On the EROS Q/K hardware, line out is _very_ hot 186 /* On the EROS Q/K hardware, full scale line out is _very_ hot
183 at ~5.8Vpp. As the hardware provides no way to reduce 187 at ~5.8Vpp. As the hardware provides no way to reduce
184 output gain, we have to back off on the PCM signal 188 output gain, we have to back off on the PCM signal
185 to avoid blowing out the signal. 189 to avoid blowing out the signal.
@@ -190,10 +194,9 @@ void audiohw_set_volume(int vol_l, int vol_r)
190 r = vol_r_hw; 194 r = vol_r_hw;
191 } 195 }
192 196
193 /* SW volume for <= 1.0 gain, HW at unity, < -740 == MUTE */ 197 int sw_volume_l = l <= min_pcm ? min_pcm : MIN(l, max_pcm);
194 int sw_volume_l = l <= -740 ? PCM_MUTE_LEVEL : MIN(l, 0); 198 int sw_volume_r = r <= min_pcm ? min_pcm : MIN(r, max_pcm);
195 int sw_volume_r = r <= -740 ? PCM_MUTE_LEVEL : MIN(r, 0); 199 pcm_set_mixer_volume(sw_volume_l / 10, sw_volume_r / 10);
196 pcm_set_master_volume(sw_volume_l, sw_volume_r);
197} 200}
198 201
199void audiohw_set_lineout_volume(int vol_l, int vol_r) 202void audiohw_set_lineout_volume(int vol_l, int vol_r)
@@ -212,7 +215,7 @@ void audiohw_set_lineout_volume(int vol_l, int vol_r)
212 r = vol_r_hw; 215 r = vol_r_hw;
213 } 216 }
214 217
215 int sw_volume_l = l <= -740 ? PCM_MUTE_LEVEL : MIN(l, 0); 218 int sw_volume_l = l <= min_pcm ? min_pcm : MIN(l, max_pcm);
216 int sw_volume_r = r <= -740 ? PCM_MUTE_LEVEL : MIN(r, 0); 219 int sw_volume_r = r <= min_pcm ? min_pcm : MIN(r, max_pcm);
217 pcm_set_master_volume(sw_volume_l, sw_volume_r); 220 pcm_set_mixer_volume(sw_volume_l / 10, sw_volume_r / 10);
218} 221}
diff --git a/firmware/export/config/aigoerosq.h b/firmware/export/config/aigoerosq.h
index 6ae8ad049f..2d0f7a0cdf 100644
--- a/firmware/export/config/aigoerosq.h
+++ b/firmware/export/config/aigoerosq.h
@@ -36,8 +36,7 @@
36 36
37/* Audio codec */ 37/* Audio codec */
38#define HAVE_EROSQ_LINUX_CODEC 38#define HAVE_EROSQ_LINUX_CODEC
39/* Rockbox has to handle the volume level */ 39#define HAVE_ALSA_32BIT
40#define HAVE_SW_VOLUME_CONTROL
41 40
42/* We don't have hardware controls */ 41/* We don't have hardware controls */
43#define HAVE_SW_TONE_CONTROLS 42#define HAVE_SW_TONE_CONTROLS
diff --git a/firmware/export/erosqlinux_codec.h b/firmware/export/erosqlinux_codec.h
index 1dd9b7e6c6..c337bb78c7 100644
--- a/firmware/export/erosqlinux_codec.h
+++ b/firmware/export/erosqlinux_codec.h
@@ -3,7 +3,7 @@
3 3
4#define AUDIOHW_CAPS (LINEOUT_CAP) 4#define AUDIOHW_CAPS (LINEOUT_CAP)
5 5
6AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -74, 6, -25) 6AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -43, 0, -20)
7 7
8//#define AUDIOHW_NEEDS_INITIAL_UNMUTE 8//#define AUDIOHW_NEEDS_INITIAL_UNMUTE
9 9
diff --git a/firmware/target/hosted/pcm-alsa.c b/firmware/target/hosted/pcm-alsa.c
index 16f82bad5c..81c0a19a45 100644
--- a/firmware/target/hosted/pcm-alsa.c
+++ b/firmware/target/hosted/pcm-alsa.c
@@ -277,7 +277,7 @@ static int dig_vol_mult_r = 2 << 16; /* multiplicative factor to apply to each s
277void pcm_set_mixer_volume(int vol_db_l, int vol_db_r) 277void pcm_set_mixer_volume(int vol_db_l, int vol_db_r)
278{ 278{
279 if(vol_db_l > 0 || vol_db_r > 0 || vol_db_l < -43 || vol_db_r < -43) 279 if(vol_db_l > 0 || vol_db_r > 0 || vol_db_l < -43 || vol_db_r < -43)
280 panicf("invalid pcm alsa volume"); 280 panicf("invalid pcm alsa volume %d %d", vol_db_l, vol_db_r);
281 if(format != SND_PCM_FORMAT_S32_LE) 281 if(format != SND_PCM_FORMAT_S32_LE)
282 panicf("this function assumes 32-bit sample size"); 282 panicf("this function assumes 32-bit sample size");
283 vol_db_l += 48; /* -42dB .. 0dB => 5dB .. 48dB */ 283 vol_db_l += 48; /* -42dB .. 0dB => 5dB .. 48dB */