ErosQ Native: Add DC Offset to PCM data

A small negative offset seems to silence all
play/pause clicking on the PCM5102A.

Also adding PCM soft muting, and muting the headphone amp
when the headphones are detected as removed. This has been
tested to not cause any unintended side effects on the
line out.

Also confirmed the numerical dB values are (approx.) correct.

Change-Id: I689d68887c86add9cc5e0ccb0c7de01aaa69b4d9
This commit is contained in:
Dana Conrad 2021-07-31 10:15:12 -05:00 committed by Aidan MacDonald
parent 57293f1fd9
commit 16b0098256
3 changed files with 31 additions and 0 deletions

View File

@ -26,10 +26,14 @@
#include "audiohw.h"
#include "settings.h"
#include "pcm_sw_volume.h"
#include "gpio-x1000.h"
static long int vol_l_hw = 0;
static long int vol_r_hw = 0;
/* internal: mute the headphone amp. 0 - unmuted, 1 - muted */
void audiohw_mute_hp(int mute);
void pcm5102_set_outputs(void)
{
audiohw_set_volume(vol_l_hw, vol_r_hw);
@ -53,13 +57,33 @@ void audiohw_set_volume(int vol_l, int vol_r)
if (lineout_inserted() && !headphones_inserted())
{
l = r = global_settings.volume_limit * 10;
/* mute the headphone amp if not plugged in */
audiohw_mute_hp(1);
}
else
{
/* unmute the headphone amp when plugged in */
audiohw_mute_hp(0);
l = vol_l;
r = vol_r;
}
#endif
l = l <= PCM5102A_VOLUME_MIN ? PCM_MUTE_LEVEL : l;
r = r <= PCM5102A_VOLUME_MIN ? PCM_MUTE_LEVEL : r;
pcm_set_master_volume(l, r);
}
void audiohw_mute_hp(int mute)
{
if (mute == 0)
{
gpio_set_level(GPIO_MAX97220_SHDN, 1);
}
else
{
gpio_set_level(GPIO_MAX97220_SHDN, 0);
}
}

View File

@ -26,6 +26,9 @@
#define PCM5102A_VOLUME_MIN -740
#define PCM5102A_VOLUME_MAX 0
/* a small DC offset appears to prevent play/pause clicking */
#define PCM_DC_OFFSET_VALUE -1
AUDIOHW_SETTING(VOLUME, "dB", 0, 1, PCM5102A_VOLUME_MIN/10, PCM5102A_VOLUME_MAX/10, 0)
/* this just calls audiohw_set_volume() with the last (locally) known volume,

View File

@ -54,7 +54,11 @@ static typeof (memcpy) *pcm_scaling_fn = NULL;
/* Scale sample by PCM factor */
static inline int32_t pcm_scale_sample(PCM_F_T f, int32_t s)
{
#if defined(PCM_DC_OFFSET_VALUE)
return (f * s + PCM_DC_OFFSET_VALUE) >> PCM_SW_VOLUME_FRACBITS;
#else
return (f * s) >> PCM_SW_VOLUME_FRACBITS;
#endif
}
/* Both UNITY, use direct copy */