audioflinger: volume control to HAL for VoIP streams
Do not apply stream volume in software for special VoIP output
stream mixers but send it to the HAL instead.
Bug: 64392515.
Test: Fi calls
Change-Id: I698a1a0ad17d672d09187529dcbc5d259284e4af
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 49047af..510d5db 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1668,7 +1668,8 @@
mScreenState(AudioFlinger::mScreenState),
// index 0 is reserved for normal mixer's submix
mFastTrackAvailMask(((1 << FastMixerState::sMaxFastTracks) - 1) & ~1),
- mHwSupportsPause(false), mHwPaused(false), mFlushPending(false)
+ mHwSupportsPause(false), mHwPaused(false), mFlushPending(false),
+ mLeftVolFloat(-1.0), mRightVolFloat(-1.0)
{
snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id);
mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
@@ -4295,6 +4296,7 @@
param = AudioMixer::RAMP_VOLUME;
}
mAudioMixer->setParameter(name, AudioMixer::RESAMPLE, AudioMixer::RESET, NULL);
+ mLeftVolFloat = -1.0;
// FIXME should not make a decision based on mServer
} else if (cblk->mServer != 0) {
// If the track is stopped before the first frame was mixed,
@@ -4305,6 +4307,10 @@
// compute volume for this track
uint32_t vl, vr; // in U8.24 integer format
float vlf, vrf, vaf; // in [0.0, 1.0] float format
+ // read original volumes with volume control
+ float typeVolume = mStreamTypes[track->streamType()].volume;
+ float v = masterVolume * typeVolume;
+
if (track->isPausing() || mStreamTypes[track->streamType()].mute) {
vl = vr = 0;
vlf = vrf = vaf = 0.;
@@ -4312,10 +4318,6 @@
track->setPaused();
}
} else {
-
- // read original volumes with volume control
- float typeVolume = mStreamTypes[track->streamType()].volume;
- float v = masterVolume * typeVolume;
sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
gain_minifloat_packed_t vlr = proxy->getVolumeLR();
vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
@@ -4367,6 +4369,25 @@
track->mHasVolumeController = false;
}
+ // For dedicated VoIP outputs, let the HAL apply the stream volume. Track volume is
+ // still applied by the mixer.
+ if ((mOutput->flags & AUDIO_OUTPUT_FLAG_VOIP_RX) != 0) {
+ v = mStreamTypes[track->streamType()].mute ? 0.0f : v;
+ if (v != mLeftVolFloat) {
+ status_t result = mOutput->stream->setVolume(v, v);
+ ALOGE_IF(result != OK, "Error when setting output stream volume: %d", result);
+ if (result == OK) {
+ mLeftVolFloat = v;
+ }
+ }
+ // if stream volume was successfully sent to the HAL, mLeftVolFloat == v here and we
+ // remove stream volume contribution from software volume.
+ if (v != 0.0f && mLeftVolFloat == v) {
+ vlf = min(1.0f, vlf / v);
+ vrf = min(1.0f, vrf / v);
+ vaf = min(1.0f, vaf / v);
+ }
+ }
// XXX: these things DON'T need to be done each time
mAudioMixer->setBufferProvider(name, track);
mAudioMixer->enable(name);
@@ -4808,7 +4829,6 @@
AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device, bool systemReady)
: PlaybackThread(audioFlinger, output, id, device, DIRECT, systemReady)
- // mLeftVolFloat, mRightVolFloat
{
}
@@ -4816,7 +4836,6 @@
AudioStreamOut* output, audio_io_handle_t id, uint32_t device,
ThreadBase::type_t type, bool systemReady)
: PlaybackThread(audioFlinger, output, id, device, type, systemReady)
- // mLeftVolFloat, mRightVolFloat
, mVolumeShaperActive(false)
{
}
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 8d7bb1a..dd2b89b 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -999,6 +999,9 @@
bool mHwSupportsPause;
bool mHwPaused;
bool mFlushPending;
+ // volumes last sent to audio HAL with stream->setVolume()
+ float mLeftVolFloat;
+ float mRightVolFloat;
};
class MixerThread : public PlaybackThread {
@@ -1116,9 +1119,6 @@
virtual void onAddNewTrack_l();
- // volumes last sent to audio HAL with stream->set_volume()
- float mLeftVolFloat;
- float mRightVolFloat;
bool mVolumeShaperActive;
DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,