OSDN Git Service

APM: cap earpiece voice in call by voice volume
authorJean-Michel Trivi <jmtrivi@google.com>
Sat, 5 Aug 2017 20:51:35 +0000 (13:51 -0700)
committerJean-Michel Trivi <jmtrivi@google.com>
Mon, 7 Aug 2017 19:25:57 +0000 (12:25 -0700)
The volume curves between AUDIO_STREAM_VOICE_CALL and other streams
  used during a call on AUDIO_DEVICE_OUT_EARPIECE can vary greatly,
  particularly when the volume curve is used to tune the voice signal
  going to earpiece, not just to select a desired curve shape.
This can be problematic during a call as a sound playing on a different
  stream may be assigned a much louder attenuation value than that
  of voice.
The fix consists in comparing the attenuation computed for earpiece
  to the one for VOICE_CALL, and using the lowest value (with a 3dB
  headroom).

Test: see bug
Bug: 63395386
Bug: 63976807
Bug: 38194285

Change-Id: Ia55e05e2a1d6fc55d45147f4234b693a905714cc

services/audiopolicy/managerdefault/AudioPolicyManager.cpp

index 1a7db26..78f195d 100644 (file)
@@ -54,6 +54,11 @@ namespace android {
 //FIXME: workaround for truncated touch sounds
 // to be removed when the problem is handled by system UI
 #define TOUCH_SOUND_FIXED_DELAY_MS 100
+
+// Largest difference in dB on earpiece in call between the voice volume and another
+// media / notification / system volume.
+constexpr float IN_CALL_EARPIECE_HEADROOM_DB = 3.f;
+
 // ----------------------------------------------------------------------------
 // AudioPolicyInterface implementation
 // ----------------------------------------------------------------------------
@@ -5348,6 +5353,30 @@ float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
         return ringVolumeDB - 4 > volumeDB ? ringVolumeDB - 4 : volumeDB;
     }
 
+    // in-call: always cap earpiece volume by voice volume + some low headroom
+    if ((stream != AUDIO_STREAM_VOICE_CALL) && (device & AUDIO_DEVICE_OUT_EARPIECE) && isInCall()) {
+        switch (stream) {
+        case AUDIO_STREAM_SYSTEM:
+        case AUDIO_STREAM_RING:
+        case AUDIO_STREAM_MUSIC:
+        case AUDIO_STREAM_ALARM:
+        case AUDIO_STREAM_NOTIFICATION:
+        case AUDIO_STREAM_ENFORCED_AUDIBLE:
+        case AUDIO_STREAM_DTMF:
+        case AUDIO_STREAM_ACCESSIBILITY: {
+            const float maxVoiceVolDb = computeVolume(AUDIO_STREAM_VOICE_CALL, index, device)
+                    + IN_CALL_EARPIECE_HEADROOM_DB;
+            if (volumeDB > maxVoiceVolDb) {
+                ALOGV("computeVolume() stream %d at vol=%f overriden by stream %d at vol=%f",
+                        stream, volumeDB, AUDIO_STREAM_VOICE_CALL, maxVoiceVolDb);
+                volumeDB = maxVoiceVolDb;
+            }
+            } break;
+        default:
+            break;
+        }
+    }
+
     // if a headset is connected, apply the following rules to ring tones and notifications
     // to avoid sound level bursts in user's ears:
     // - always attenuate notifications volume by 6dB