audio hal: Fix multichannel playback
Correctly operate on input and output buffers in DownmixerBufferProvider
Note that playback is a bit choppy, need to investigate further.
Change-Id: I350175dcc9cc7142a1935585a8bd5e9abb1b8eb6
Test: play back a 5.1 file
diff --git a/media/libaudioprocessing/BufferProviders.cpp b/media/libaudioprocessing/BufferProviders.cpp
index 8341a1e..862fef6 100644
--- a/media/libaudioprocessing/BufferProviders.cpp
+++ b/media/libaudioprocessing/BufferProviders.cpp
@@ -142,9 +142,9 @@
audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(outputChannelMask),
bufferFrameCount) // set bufferFrameCount to 0 to do in-place
{
- ALOGV("DownmixerBufferProvider(%p)(%#x, %#x, %#x %u %d)",
+ ALOGV("DownmixerBufferProvider(%p)(%#x, %#x, %#x %u %d %d)",
this, inputChannelMask, outputChannelMask, format,
- sampleRate, sessionId);
+ sampleRate, sessionId, (int)bufferFrameCount);
if (!sIsMultichannelCapable) {
ALOGE("DownmixerBufferProvider() error: not multichannel capable");
return;
@@ -178,11 +178,13 @@
EFFECT_CONFIG_FORMAT | EFFECT_CONFIG_ACC_MODE;
mDownmixConfig.outputCfg.mask = mDownmixConfig.inputCfg.mask;
+ mInFrameSize =
+ audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(inputChannelMask);
+ mOutFrameSize =
+ audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(outputChannelMask);
status_t status;
status = EffectBufferHalInterface::mirror(
- nullptr,
- audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(inputChannelMask),
- &mInBuffer);
+ nullptr, mInFrameSize * bufferFrameCount, &mInBuffer);
if (status != 0) {
ALOGE("DownmixerBufferProvider() error %d while creating input buffer", status);
mDownmixInterface.clear();
@@ -190,9 +192,7 @@
return;
}
status = EffectBufferHalInterface::mirror(
- nullptr,
- audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(outputChannelMask),
- &mOutBuffer);
+ nullptr, mOutFrameSize * bufferFrameCount, &mOutBuffer);
if (status != 0) {
ALOGE("DownmixerBufferProvider() error %d while creating output buffer", status);
mInBuffer.clear();
@@ -277,14 +277,18 @@
{
mInBuffer->setExternalData(const_cast<void*>(src));
mInBuffer->setFrameCount(frames);
- mInBuffer->update();
- mOutBuffer->setExternalData(dst);
+ mInBuffer->update(mInFrameSize * frames);
mOutBuffer->setFrameCount(frames);
- mOutBuffer->update();
+ mOutBuffer->setExternalData(dst);
+ if (dst != src) {
+ // Downmix may be accumulating, need to populate the output buffer
+ // with the dst data.
+ mOutBuffer->update(mOutFrameSize * frames);
+ }
// may be in-place if src == dst.
status_t res = mDownmixInterface->process();
if (res == OK) {
- mOutBuffer->commit();
+ mOutBuffer->commit(mOutFrameSize * frames);
} else {
ALOGE("DownmixBufferProvider error %d", res);
}