Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit df8aecfb authored by Dhananjay Kumar's avatar Dhananjay Kumar
Browse files

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
parent 908df1ab
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
/*
 * 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 @@ static struct fm_module fmmod = {
  .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,6 +83,7 @@ static int32_t fm_set_volume(struct audio_device *adev, float value)
        value = 1.0;
    }
    vol  = lrint((value * 0x2000) + 0.5);
    if (persist)
        fmmod.fm_volume = value;

    if (!fmmod.is_fm_running) {
@@ -202,7 +204,7 @@ static int32_t fm_start(struct audio_device *adev)
    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,10 +265,13 @@ void audio_extn_fm_set_parameters(struct audio_device *adev,
                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);
            }
       }
    }

    memset(value, 0, sizeof(value));
    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_FM_VOLUME,
@@ -278,7 +283,7 @@ void audio_extn_fm_set_parameters(struct audio_device *adev,
            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 @@ void audio_extn_fm_set_parameters(struct audio_device *adev,
            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: