Implement volume control on default audio HAL

Implemented volume control based on setting audio port config.

Bug: 336370745
Test: atest VtsHalAudioCoreTargetTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:122597a5e96c873239540a53523caf67fe806d90)
Merged-In: Ia590974e61aa3a1c3f70afdb54ce87c85e9a1b3c
Change-Id: Ia590974e61aa3a1c3f70afdb54ce87c85e9a1b3c
This commit is contained in:
Weilin Xu
2024-10-02 17:16:42 +00:00
committed by Android Build Cherrypicker Worker
parent ad6288c8bc
commit a33bb5eaf5
10 changed files with 160 additions and 1 deletions

View File

@@ -47,6 +47,7 @@ using aidl::android::media::audio::common::AudioDevice;
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioFormatDescription;
using aidl::android::media::audio::common::AudioFormatType;
using aidl::android::media::audio::common::AudioGainConfig;
using aidl::android::media::audio::common::AudioInputFlags;
using aidl::android::media::audio::common::AudioIoFlags;
using aidl::android::media::audio::common::AudioMMapPolicy;
@@ -1200,7 +1201,9 @@ ndk::ScopedAStatus Module::setAudioPortConfigImpl(
}
if (in_requested.gain.has_value()) {
// Let's pretend that gain can always be applied.
if (!setAudioPortConfigGain(*portIt, in_requested.gain.value())) {
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
out_suggested->gain = in_requested.gain.value();
}
@@ -1242,6 +1245,52 @@ ndk::ScopedAStatus Module::setAudioPortConfigImpl(
return ndk::ScopedAStatus::ok();
}
bool Module::setAudioPortConfigGain(const AudioPort& port, const AudioGainConfig& gainRequested) {
auto& ports = getConfig().ports;
if (gainRequested.index < 0 || gainRequested.index >= (int)port.gains.size()) {
LOG(ERROR) << __func__ << ": gains for port " << port.id << " is undefined";
return false;
}
int stepValue = port.gains[gainRequested.index].stepValue;
if (stepValue == 0) {
LOG(ERROR) << __func__ << ": port gain step value is 0";
return false;
}
int minValue = port.gains[gainRequested.index].minValue;
int maxValue = port.gains[gainRequested.index].maxValue;
if (gainRequested.values[0] > maxValue || gainRequested.values[0] < minValue) {
LOG(ERROR) << __func__ << ": gain value " << gainRequested.values[0]
<< " out of range of min and max gain config";
return false;
}
int gainIndex = (gainRequested.values[0] - minValue) / stepValue;
int totalSteps = (maxValue - minValue) / stepValue;
if (totalSteps == 0) {
LOG(ERROR) << __func__ << ": difference between port gain min value " << minValue
<< " and max value " << maxValue << " is less than step value " << stepValue;
return false;
}
// Root-power quantities are used in curve:
// 10^((minMb / 100 + (maxMb / 100 - minMb / 100) * gainIndex / totalSteps) / (10 * 2))
// where 100 is the conversion from mB to dB, 10 comes from the log 10 conversion from power
// ratios, and 2 means are the square of amplitude.
float gain =
pow(10, (minValue + (maxValue - minValue) * (gainIndex / (float)totalSteps)) / 2000);
if (gain < 0) {
LOG(ERROR) << __func__ << ": gain " << gain << " is less than 0";
return false;
}
for (const auto& route : getConfig().routes) {
if (route.sinkPortId != port.id) {
continue;
}
for (const auto sourcePortId : route.sourcePortIds) {
mStreams.setGain(sourcePortId, gain);
}
}
return true;
}
ndk::ScopedAStatus Module::resetAudioPatch(int32_t in_patchId) {
auto& patches = getConfig().patches;
auto patchIt = findById<AudioPatch>(patches, in_patchId);