From 142729a64da8a7d05f3ec5bc927ec100e29075d9 Mon Sep 17 00:00:00 2001 From: Jakub Tyszkowski Date: Fri, 2 Sep 2022 09:18:26 +0000 Subject: [PATCH] LeAudio: Fix volume control The calculation formula is now set to be the inverse of the one used in VolumeControlService.java when calculating volume index from the BLE audio volume level. This also fixes not using the absolute volume for BLE audio stream, which could result with very low volume levels at the lower registers of the volume slider. It was caused by lowering the volume on both ends. Not transmitting the sound at the maximum volume level could also reduce the sound quality due to effective sound sample resolution being lower. Bug: 238587620 Bug: 241501978 Test: built and manually tested Tag: #feature Change-Id: I368c8978be5fbd94b0f62df2551fe179a9f203a0 Merged-In: I368c8978be5fbd94b0f62df2551fe179a9f203a0 (cherry picked from commit 51d75fbc69935531464e4adfbdefacc999cbb96c) --- media/java/android/media/AudioSystem.java | 8 ++++++++ .../android/server/audio/AudioService.java | 19 +++++++++++-------- .../server/audio/AudioServiceEvents.java | 2 +- .../com/android/server/audio/BtHelper.java | 5 ++--- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 650f360594952..7ccbe51bbd49a 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -2385,6 +2385,14 @@ public class AudioSystem return types.size() == 1 && types.contains(type); } + /** + * @hide + * Return true if the audio device type is a Bluetooth LE Audio device. + */ + public static boolean isLeAudioDeviceType(int type) { + return DEVICE_OUT_ALL_BLE_SET.contains(type); + } + /** @hide */ public static final int DEFAULT_MUTE_STREAMS_AFFECTED = (1 << STREAM_MUSIC) | diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 0a081bfbee969..2be95adb7aabe 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -3353,8 +3353,7 @@ public class AudioService extends IAudioService.Stub dispatchAbsoluteVolumeChanged(streamType, info, newIndex); } - if ((device == AudioSystem.DEVICE_OUT_BLE_HEADSET - || device == AudioSystem.DEVICE_OUT_BLE_BROADCAST) + if (AudioSystem.isLeAudioDeviceType(device) && streamType == getBluetoothContextualVolumeStream() && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { if (DEBUG_VOL) { @@ -4110,8 +4109,7 @@ public class AudioService extends IAudioService.Stub dispatchAbsoluteVolumeChanged(streamType, info, index); } - if ((device == AudioSystem.DEVICE_OUT_BLE_HEADSET - || device == AudioSystem.DEVICE_OUT_BLE_BROADCAST) + if (AudioSystem.isLeAudioDeviceType(device) && streamType == getBluetoothContextualVolumeStream() && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { if (DEBUG_VOL) { @@ -6950,7 +6948,8 @@ public class AudioService extends IAudioService.Stub return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE; } if (isAbsoluteVolumeDevice(audioSystemDeviceOut) - || isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut)) { + || isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut) + || AudioSystem.isLeAudioDeviceType(audioSystemDeviceOut)) { return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE; } return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE; @@ -7717,7 +7716,9 @@ public class AudioService extends IAudioService.Stub int index; if (isFullyMuted()) { index = 0; - } else if (isAbsoluteVolumeDevice(device) || isA2dpAbsoluteVolumeDevice(device)) { + } else if (isAbsoluteVolumeDevice(device) + || isA2dpAbsoluteVolumeDevice(device) + || AudioSystem.isLeAudioDeviceType(device)) { index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); } else if (isFullVolumeDevice(device)) { index = (mIndexMax + 5)/10; @@ -7739,7 +7740,8 @@ public class AudioService extends IAudioService.Stub if (isFullyMuted()) { index = 0; } else if (isAbsoluteVolumeDevice(device) - || isA2dpAbsoluteVolumeDevice(device)) { + || isA2dpAbsoluteVolumeDevice(device) + || AudioSystem.isLeAudioDeviceType(device)) { index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); } else if (isFullVolumeDevice(device)) { index = (mIndexMax + 5)/10; @@ -8160,7 +8162,8 @@ public class AudioService extends IAudioService.Stub int streamDevice = getDeviceForStream(streamType); if ((device != streamDevice) && (isAbsoluteVolumeDevice(device) - || isA2dpAbsoluteVolumeDevice(device))) { + || isA2dpAbsoluteVolumeDevice(device) + || AudioSystem.isLeAudioDeviceType(device))) { mStreamStates[streamType].applyDeviceVolume_syncVSS(device); } mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice); diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java index b5835ce0c8473..30a9e0a70e968 100644 --- a/services/core/java/com/android/server/audio/AudioServiceEvents.java +++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java @@ -433,7 +433,7 @@ public class AudioServiceEvents { case VOL_SET_LE_AUDIO_VOL: return new StringBuilder("setLeAudioVolume:") .append(" index:").append(mVal1) - .append(" gain dB:").append(mVal2) + .append(" maxIndex:").append(mVal2) .toString(); case VOL_SET_AVRCP_VOL: return new StringBuilder("setAvrcpVolume:") diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java index 9a7c6626aa24f..d0f5470a73040 100644 --- a/services/core/java/com/android/server/audio/BtHelper.java +++ b/services/core/java/com/android/server/audio/BtHelper.java @@ -412,9 +412,8 @@ public class BtHelper { } return; } - /* leaudio expect volume value in range 0 to 255 - */ - int volume = (index * (BT_LE_AUDIO_MAX_VOL - BT_LE_AUDIO_MIN_VOL)) / maxIndex ; + /* leaudio expect volume value in range 0 to 255 */ + int volume = (int) Math.round((double) index * BT_LE_AUDIO_MAX_VOL / maxIndex); if (AudioService.DEBUG_VOL) { Log.i(TAG, "setLeAudioVolume: calling mLeAudio.setVolume idx="