hal: audio_extn: fix pop noise when FM is interrupted by voice call
Minor pop is observed when FM playback is stopped, this is due to
derouting of loopback devices while they still have audible data.
This is causing pops even when FM is stopped after playback, but
this pop is more perceivable in case of interruption by voice call.
Fix the issue by draining unmuted data before derouting FM playback.
Change-Id: If92e43f3a15f0a9cfdf2819827c7f7a0ba852e3d
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index ed3776c..3e4b9ea 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -35,6 +35,7 @@
#define AUDIO_PARAMETER_KEY_HANDLE_FM "handle_fm"
#define AUDIO_PARAMETER_KEY_FM_VOLUME "fm_volume"
#define AUDIO_PARAMETER_KEY_REC_PLAY_CONC "rec_play_conc_on"
+#define FM_LOOPBACK_DRAIN_TIME_MS 2
static struct pcm_config pcm_config_fm = {
.channels = 2,
@@ -65,7 +66,7 @@
.scard_state = SND_CARD_STATE_ONLINE,
};
-static int32_t fm_set_volume(struct audio_device *adev, float value)
+static int32_t fm_set_volume(struct audio_device *adev, float value, bool persist)
{
int32_t vol, ret = 0;
struct mixer_ctl *ctl;
@@ -82,7 +83,8 @@
value = 1.0;
}
vol = lrint((value * 0x2000) + 0.5);
- fmmod.fm_volume = value;
+ if (persist)
+ fmmod.fm_volume = value;
if (!fmmod.is_fm_running) {
ALOGV("%s: FM not active, ignoring set_fm_volume call", __func__);
@@ -202,7 +204,7 @@
pcm_start(fmmod.fm_pcm_tx);
fmmod.is_fm_running = true;
- fm_set_volume(adev, fmmod.fm_volume);
+ fm_set_volume(adev, fmmod.fm_volume, false);
ALOGD("%s: exit: status(%d)", __func__, ret);
return 0;
@@ -263,8 +265,11 @@
adev->primary_output->devices = val & ~AUDIO_DEVICE_OUT_FM;
fm_start(adev);
} else if (!(val & AUDIO_DEVICE_OUT_FM)
- && fmmod.is_fm_running == true)
+ && fmmod.is_fm_running == true) {
+ fm_set_volume(adev, 0, false);
+ usleep(FM_LOOPBACK_DRAIN_TIME_MS*1000);
fm_stop(adev);
+ }
}
}
@@ -278,7 +283,7 @@
goto exit;
}
ALOGD("%s: set_fm_volume usecase", __func__);
- fm_set_volume(adev, vol);
+ fm_set_volume(adev, vol, true);
}
#ifdef RECORD_PLAY_CONCURRENCY
@@ -293,7 +298,7 @@
ALOGD("Record play concurrency OFF Forcing FM device reroute");
select_devices(adev, USECASE_AUDIO_PLAYBACK_FM);
- fm_set_volume(adev,fmmod.fm_volume);
+ fm_set_volume(adev, fmmod.fm_volume, false);
}
#endif
exit: