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

Commit 719a987e authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

APM: cap earpiece voice in call by voice volume

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
parent ddef08e7
Loading
Loading
Loading
Loading
+29 −0
Original line number Original line Diff line number Diff line
@@ -54,6 +54,11 @@ namespace android {
//FIXME: workaround for truncated touch sounds
//FIXME: workaround for truncated touch sounds
// to be removed when the problem is handled by system UI
// to be removed when the problem is handled by system UI
#define TOUCH_SOUND_FIXED_DELAY_MS 100
#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
// AudioPolicyInterface implementation
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
@@ -5348,6 +5353,30 @@ float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
        return ringVolumeDB - 4 > volumeDB ? ringVolumeDB - 4 : volumeDB;
        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
    // if a headset is connected, apply the following rules to ring tones and notifications
    // to avoid sound level bursts in user's ears:
    // to avoid sound level bursts in user's ears:
    // - always attenuate notifications volume by 6dB
    // - always attenuate notifications volume by 6dB