Add MMAP Audio Balance
Similar to adding Mono audio, this cl adds the audio balance settings
to MMAP Audio.
Bug:209521805
Test: Settings -> Accessibility -> Audio Adjustment -> Audio Balance
Use OboeTester and play outputs with various settings on the slider
Change-Id: I3269f6fe39b5f720da69739c49eb787e57f93b0a
diff --git a/media/libaaudio/src/client/AAudioFlowGraph.cpp b/media/libaaudio/src/client/AAudioFlowGraph.cpp
index d3e2912..5b46ae0 100644
--- a/media/libaaudio/src/client/AAudioFlowGraph.cpp
+++ b/media/libaaudio/src/client/AAudioFlowGraph.cpp
@@ -21,8 +21,10 @@
#include "AAudioFlowGraph.h"
#include <flowgraph/ClipToRange.h>
+#include <flowgraph/ManyToMultiConverter.h>
#include <flowgraph/MonoBlend.h>
#include <flowgraph/MonoToMultiConverter.h>
+#include <flowgraph/MultiToManyConverter.h>
#include <flowgraph/RampLinear.h>
#include <flowgraph/SinkFloat.h>
#include <flowgraph/SinkI16.h>
@@ -39,12 +41,15 @@
int32_t sourceChannelCount,
audio_format_t sinkFormat,
int32_t sinkChannelCount,
- bool useMonoBlend) {
+ bool useMonoBlend,
+ float audioBalance) {
FlowGraphPortFloatOutput *lastOutput = nullptr;
// TODO change back to ALOGD
- ALOGI("%s() source format = 0x%08x, channels = %d, sink format = 0x%08x, channels = %d",
- __func__, sourceFormat, sourceChannelCount, sinkFormat, sinkChannelCount);
+ ALOGI("%s() source format = 0x%08x, channels = %d, sink format = 0x%08x, channels = %d, "
+ "useMonoBlend = %d, audioBalance = %f",
+ __func__, sourceFormat, sourceChannelCount, sinkFormat, sinkChannelCount,
+ useMonoBlend, audioBalance);
switch (sourceFormat) {
case AUDIO_FORMAT_PCM_FLOAT:
@@ -65,10 +70,11 @@
}
lastOutput = &mSource->output;
- // Apply volume as a ramp to avoid pops.
- mVolumeRamp = std::make_unique<RampLinear>(sourceChannelCount);
- lastOutput->connect(&mVolumeRamp->input);
- lastOutput = &mVolumeRamp->output;
+ if (useMonoBlend) {
+ mMonoBlend = std::make_unique<MonoBlend>(sourceChannelCount);
+ lastOutput->connect(&mMonoBlend->input);
+ lastOutput = &mMonoBlend->output;
+ }
// For a pure float graph, there is chance that the data range may be very large.
// So we should clip to a reasonable value that allows a little headroom.
@@ -78,12 +84,6 @@
lastOutput = &mClipper->output;
}
- if (useMonoBlend) {
- mMonoBlend = std::make_unique<MonoBlend>(sourceChannelCount);
- lastOutput->connect(&mMonoBlend->input);
- lastOutput = &mMonoBlend->output;
- }
-
// Expand the number of channels if required.
if (sourceChannelCount == 1 && sinkChannelCount > 1) {
mChannelConverter = std::make_unique<MonoToMultiConverter>(sinkChannelCount);
@@ -94,6 +94,23 @@
return AAUDIO_ERROR_UNIMPLEMENTED;
}
+ // Apply volume ramps to set the left/right audio balance and target volumes.
+ // The signals will be decoupled, volume ramps will be applied, before the signals are
+ // combined again.
+ mMultiToManyConverter = std::make_unique<MultiToManyConverter>(sinkChannelCount);
+ mManyToMultiConverter = std::make_unique<ManyToMultiConverter>(sinkChannelCount);
+ lastOutput->connect(&mMultiToManyConverter->input);
+ for (int i = 0; i < sinkChannelCount; i++) {
+ mVolumeRamps.emplace_back(std::make_unique<RampLinear>(1));
+ mPanningVolumes.emplace_back(1.0f);
+ lastOutput = mMultiToManyConverter->outputs[i].get();
+ lastOutput->connect(&(mVolumeRamps[i].get()->input));
+ lastOutput = &(mVolumeRamps[i].get()->output);
+ lastOutput->connect(mManyToMultiConverter->inputs[i].get());
+ }
+ lastOutput = &mManyToMultiConverter->output;
+ setAudioBalance(audioBalance);
+
switch (sinkFormat) {
case AUDIO_FORMAT_PCM_FLOAT:
mSink = std::make_unique<SinkFloat>(sinkChannelCount);
@@ -125,9 +142,32 @@
* @param volume between 0.0 and 1.0
*/
void AAudioFlowGraph::setTargetVolume(float volume) {
- mVolumeRamp->setTarget(volume);
+ for (int i = 0; i < mVolumeRamps.size(); i++) {
+ mVolumeRamps[i]->setTarget(volume * mPanningVolumes[i]);
+ }
+ mTargetVolume = volume;
}
+/**
+ * @param audioBalance between -1.0 and 1.0
+ */
+void AAudioFlowGraph::setAudioBalance(float audioBalance) {
+ if (mPanningVolumes.size() >= 2) {
+ float leftMultiplier = 0;
+ float rightMultiplier = 0;
+ mBalance.computeStereoBalance(audioBalance, &leftMultiplier, &rightMultiplier);
+ mPanningVolumes[0] = leftMultiplier;
+ mPanningVolumes[1] = rightMultiplier;
+ mVolumeRamps[0]->setTarget(mTargetVolume * leftMultiplier);
+ mVolumeRamps[1]->setTarget(mTargetVolume * rightMultiplier);
+ }
+}
+
+/**
+ * @param numFrames to slowly adjust for volume changes
+ */
void AAudioFlowGraph::setRampLengthInFrames(int32_t numFrames) {
- mVolumeRamp->setLengthInFrames(numFrames);
+ for (auto& ramp : mVolumeRamps) {
+ ramp->setLengthInFrames(numFrames);
+ }
}