diff options
author | Eric Laurent <elaurent@google.com> | 2012-05-08 09:31:34 -0700 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2012-05-10 12:14:48 -0700 |
commit | d895c946ca09a4fae551092b2ea0a24eba4702b5 (patch) | |
tree | 16d052150bdac021f7498bf851d5cab3fc32af88 | |
parent | c9d9f9c6db484a7d6487976ae8fdc837297c3dbd (diff) | |
download | device_samsung_tuna-d895c946ca09a4fae551092b2ea0a24eba4702b5.zip device_samsung_tuna-d895c946ca09a4fae551092b2ea0a24eba4702b5.tar.gz device_samsung_tuna-d895c946ca09a4fae551092b2ea0a24eba4702b5.tar.bz2 |
audio: fix media volume issues.
Fixed 2 issues with media volume:
1 - since we use mm port for music and tones port for other use cases
the digital volume should be applied to both "DL2 Tones Playback Volume"
and "DL2 Media Playback Volume".
2 - the total gain applied to audio originating from the AP is the
combination of digital gain in ABE and analog gain in codec. Some use cases
like telephony have a higher priority than media and apply a different (higher)
analog gain. As this analog gain is common to all sources, digital media gain
should be adjusted accordingly to avoid volume bursts while in call and playing
music. This is particularly important in speaker phone mode.
Change-Id: I90200282edca7098603edca2d56821290988cb20
-rw-r--r-- | audio/audio_hw.c | 112 |
1 files changed, 88 insertions, 24 deletions
diff --git a/audio/audio_hw.c b/audio/audio_hw.c index b507a59..b781b29 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -564,8 +564,11 @@ struct route_setting vx_ul_bt[] = { struct mixer_ctls { struct mixer_ctl *dl1_eq; + struct mixer_ctl *mm_dl1_volume; + struct mixer_ctl *tones_dl1_volume; struct mixer_ctl *mm_dl2_volume; struct mixer_ctl *vx_dl2_volume; + struct mixer_ctl *tones_dl2_volume; struct mixer_ctl *mm_dl1; struct mixer_ctl *mm_dl2; struct mixer_ctl *vx_dl1; @@ -932,7 +935,16 @@ static void set_output_volumes(struct tuna_audio_device *adev, bool tty_volume) int speaker_volume_overrange = MIXER_ABE_GAIN_0DB; int speaker_max_db = DB_FROM_SPEAKER_VOLUME(mixer_ctl_get_range_max(adev->mixer_ctls.speaker_volume)); - struct mixer_ctl *mixer_ctl_overrange = adev->mixer_ctls.mm_dl2_volume; + int normal_speaker_volume = toro ? NORMAL_SPEAKER_VOLUME_TORO : + NORMAL_SPEAKER_VOLUME_MAGURO; + int normal_headphone_volume = toro ? NORMAL_HEADPHONE_VOLUME_TORO : + NORMAL_HEADPHONE_VOLUME_MAGURO; + int normal_headset_volume = toro ? NORMAL_HEADSET_VOLUME_TORO : + NORMAL_HEADSET_VOLUME_MAGURO; + int normal_earpiece_volume = toro ? NORMAL_EARPIECE_VOLUME_TORO : + NORMAL_EARPIECE_VOLUME_MAGURO; + int dl1_volume_correction = 0; + int dl2_volume_correction = 0; if (adev->mode == AUDIO_MODE_IN_CALL) { /* Voice call */ @@ -942,7 +954,6 @@ static void set_output_volumes(struct tuna_audio_device *adev, bool tty_volume) VOICE_CALL_HEADSET_VOLUME_MAGURO; earpiece_volume = toro ? VOICE_CALL_EARPIECE_VOLUME_TORO : VOICE_CALL_EARPIECE_VOLUME_MAGURO; - mixer_ctl_overrange = adev->mixer_ctls.vx_dl2_volume; } else if (adev->mode == AUDIO_MODE_IN_COMMUNICATION) { /* VoIP */ speaker_volume = toro ? VOIP_SPEAKER_VOLUME_TORO : @@ -953,22 +964,32 @@ static void set_output_volumes(struct tuna_audio_device *adev, bool tty_volume) VOIP_EARPIECE_VOLUME_MAGURO; } else { /* Media */ - speaker_volume = toro ? NORMAL_SPEAKER_VOLUME_TORO : - NORMAL_SPEAKER_VOLUME_MAGURO; + speaker_volume = normal_speaker_volume; if (headphone_on) - headset_volume = toro ? NORMAL_HEADPHONE_VOLUME_TORO : - NORMAL_HEADPHONE_VOLUME_MAGURO; + headset_volume = normal_headphone_volume; else - headset_volume = toro ? NORMAL_HEADSET_VOLUME_TORO : - NORMAL_HEADSET_VOLUME_MAGURO; - earpiece_volume = toro ? NORMAL_EARPIECE_VOLUME_TORO : - NORMAL_EARPIECE_VOLUME_MAGURO; + headset_volume = normal_headset_volume; + earpiece_volume = normal_earpiece_volume; } + if (tty_volume) headset_volume = HEADPHONE_VOLUME_TTY; else if (adev->mode == AUDIO_MODE_RINGTONE) headset_volume += RINGTONE_HEADSET_VOLUME_OFFSET; + /* apply correction on digital volume to keep the overall volume consistent if the + * analog volume is not driven by media use case + */ + if (headphone_on) + dl1_volume_correction = normal_headphone_volume - headset_volume; + else if (adev->devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) + dl1_volume_correction = normal_headset_volume - headset_volume; + else + dl1_volume_correction = normal_earpiece_volume - earpiece_volume; + + if (speaker_on) + dl2_volume_correction = normal_speaker_volume - speaker_volume; + /* If we have run out of range in the codec (analog) speaker volume, we have to apply the remainder of the dB increase to the DL2 media/voice mixer volume, which is a digital gain */ @@ -983,10 +1004,34 @@ static void set_output_volumes(struct tuna_audio_device *adev, bool tty_volume) mixer_ctl_set_value(adev->mixer_ctls.headset_volume, channel, DB_TO_HEADSET_VOLUME(headset_volume)); } - if (speaker_on) - mixer_ctl_set_value(mixer_ctl_overrange, 0, speaker_volume_overrange); - else - mixer_ctl_set_value(mixer_ctl_overrange, 0, MIXER_ABE_GAIN_0DB); + + if (!speaker_on) + speaker_volume_overrange = MIXER_ABE_GAIN_0DB; + + if (adev->mode == AUDIO_MODE_IN_CALL) { + mixer_ctl_set_value(adev->mixer_ctls.tones_dl1_volume, 0, + MIXER_ABE_GAIN_0DB + dl1_volume_correction); + mixer_ctl_set_value(adev->mixer_ctls.vx_dl2_volume, 0, + speaker_volume_overrange); + mixer_ctl_set_value(adev->mixer_ctls.tones_dl2_volume, 0, + speaker_volume_overrange + dl2_volume_correction); + } else if (adev->mode == AUDIO_MODE_IN_COMMUNICATION) { + mixer_ctl_set_value(adev->mixer_ctls.tones_dl1_volume, 0, + MIXER_ABE_GAIN_0DB); + mixer_ctl_set_value(adev->mixer_ctls.tones_dl2_volume, 0, + speaker_volume_overrange); + } else { + mixer_ctl_set_value(adev->mixer_ctls.tones_dl1_volume, 0, + MIXER_ABE_GAIN_0DB + dl1_volume_correction); + mixer_ctl_set_value(adev->mixer_ctls.tones_dl2_volume, 0, + speaker_volume_overrange + dl2_volume_correction); + } + + mixer_ctl_set_value(adev->mixer_ctls.mm_dl1_volume, 0, + MIXER_ABE_GAIN_0DB + dl1_volume_correction); + mixer_ctl_set_value(adev->mixer_ctls.mm_dl2_volume, 0, + speaker_volume_overrange + dl2_volume_correction); + mixer_ctl_set_value(adev->mixer_ctls.earpiece_volume, 0, DB_TO_EARPIECE_VOLUME(earpiece_volume)); } @@ -3292,10 +3337,16 @@ static int adev_open(const hw_module_t* module, const char* name, adev->mixer_ctls.dl1_eq = mixer_get_ctl_by_name(adev->mixer, MIXER_DL1_EQUALIZER); + adev->mixer_ctls.mm_dl1_volume = mixer_get_ctl_by_name(adev->mixer, + MIXER_DL1_MEDIA_PLAYBACK_VOLUME); + adev->mixer_ctls.tones_dl1_volume = mixer_get_ctl_by_name(adev->mixer, + MIXER_DL1_TONES_PLAYBACK_VOLUME); adev->mixer_ctls.mm_dl2_volume = mixer_get_ctl_by_name(adev->mixer, MIXER_DL2_MEDIA_PLAYBACK_VOLUME); adev->mixer_ctls.vx_dl2_volume = mixer_get_ctl_by_name(adev->mixer, MIXER_DL2_VOICE_PLAYBACK_VOLUME); + adev->mixer_ctls.tones_dl2_volume = mixer_get_ctl_by_name(adev->mixer, + MIXER_DL2_TONES_PLAYBACK_VOLUME); adev->mixer_ctls.mm_dl1 = mixer_get_ctl_by_name(adev->mixer, MIXER_DL1_MIXER_MULTIMEDIA); adev->mixer_ctls.vx_dl1 = mixer_get_ctl_by_name(adev->mixer, @@ -3333,16 +3384,29 @@ static int adev_open(const hw_module_t* module, const char* name, adev->mixer_ctls.earpiece_volume = mixer_get_ctl_by_name(adev->mixer, MIXER_EARPHONE_PLAYBACK_VOLUME); - if (!adev->mixer_ctls.dl1_eq || !adev->mixer_ctls.vx_dl2_volume || - !adev->mixer_ctls.mm_dl2_volume || !adev->mixer_ctls.mm_dl1 || - !adev->mixer_ctls.vx_dl1 || !adev->mixer_ctls.tones_dl1 || - !adev->mixer_ctls.mm_dl2 || !adev->mixer_ctls.vx_dl2 || - !adev->mixer_ctls.tones_dl2 ||!adev->mixer_ctls.dl2_mono || - !adev->mixer_ctls.dl1_headset || !adev->mixer_ctls.dl1_bt || - !adev->mixer_ctls.earpiece_enable || !adev->mixer_ctls.left_capture || - !adev->mixer_ctls.right_capture || !adev->mixer_ctls.amic_ul_volume || - !adev->mixer_ctls.voice_ul_volume || !adev->mixer_ctls.sidetone_capture || - !adev->mixer_ctls.headset_volume || !adev->mixer_ctls.speaker_volume || + if (!adev->mixer_ctls.dl1_eq || + !adev->mixer_ctls.mm_dl1_volume || + !adev->mixer_ctls.tones_dl1_volume || + !adev->mixer_ctls.mm_dl2_volume || + !adev->mixer_ctls.vx_dl2_volume || + !adev->mixer_ctls.tones_dl2_volume || + !adev->mixer_ctls.mm_dl1 || + !adev->mixer_ctls.vx_dl1 || + !adev->mixer_ctls.tones_dl1 || + !adev->mixer_ctls.mm_dl2 || + !adev->mixer_ctls.vx_dl2 || + !adev->mixer_ctls.tones_dl2 || + !adev->mixer_ctls.dl2_mono || + !adev->mixer_ctls.dl1_headset || + !adev->mixer_ctls.dl1_bt || + !adev->mixer_ctls.earpiece_enable || + !adev->mixer_ctls.left_capture || + !adev->mixer_ctls.right_capture || + !adev->mixer_ctls.amic_ul_volume || + !adev->mixer_ctls.voice_ul_volume || + !adev->mixer_ctls.sidetone_capture || + !adev->mixer_ctls.headset_volume || + !adev->mixer_ctls.speaker_volume || !adev->mixer_ctls.earpiece_volume) { mixer_close(adev->mixer); free(adev); |