summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2012-05-08 09:31:34 -0700
committerEric Laurent <elaurent@google.com>2012-05-10 12:14:48 -0700
commitd6cc09e49a7d1a3ff90cedca041e040c245d4207 (patch)
tree752217d48581cc5e09fdaaa2a72ed36ef1d0b803 /audio
parent6db83b3cedbec73afd542f92cee390aa5879b27a (diff)
downloaddevice_samsung_tuna-d6cc09e49a7d1a3ff90cedca041e040c245d4207.zip
device_samsung_tuna-d6cc09e49a7d1a3ff90cedca041e040c245d4207.tar.gz
device_samsung_tuna-d6cc09e49a7d1a3ff90cedca041e040c245d4207.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
Diffstat (limited to 'audio')
-rw-r--r--audio/audio_hw.c112
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);