AudioMixer.cpp revision c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49
1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/* 2a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk** 3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** Copyright 2007, The Android Open Source Project 4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** 5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** Licensed under the Apache License, Version 2.0 (the "License"); 6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** you may not use this file except in compliance with the License. 7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** You may obtain a copy of the License at 8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** 9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** http://www.apache.org/licenses/LICENSE-2.0 10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** 11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** Unless required by applicable law or agreed to in writing, software 12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** distributed under the License is distributed on an "AS IS" BASIS, 13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** See the License for the specific language governing permissions and 15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams** limitations under the License. 16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams*/ 17326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 18326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#define LOG_TAG "AudioMixer" 19326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams//#define LOG_NDEBUG 0 205ae678f2e68e25bd74cdc408df354c3b6fe481bfMathias Agopian 21326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include "Configuration.h" 22158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams#include <stdint.h> 23158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams#include <string.h> 247bf29ddc35450d8064541c42c99a1f48be6cf0ddJason Sams#include <stdlib.h> 25158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams#include <sys/types.h> 2676371fff76412fd020e24ddb8bf1ddb5c75f0ed1Joe Onorato 2776371fff76412fd020e24ddb8bf1ddb5c75f0ed1Joe Onorato#include <utils/Errors.h> 28158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams#include <utils/Log.h> 298d957fa762eff6c03a93ddea9405d9575665f1ecJason Sams 308d957fa762eff6c03a93ddea9405d9575665f1ecJason Sams#include <cutils/bitops.h> 31158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams#include <cutils/compiler.h> 32326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <utils/Debug.h> 33326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 34326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <system/audio.h> 35fb03a22ad2adadc1ff50a8b50d43ad7fcc3fa6edJason Sams 36ca3f09c0924e9515901dfd47fa5f95385d53cf80Stephen Hines#include <audio_utils/primitives.h> 37326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <audio_utils/format.h> 38afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk#include <common_time/local_clock.h> 396b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams#include <common_time/cc_helper.h> 406b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams 414b3de47071d875faaa7d419d050a464b09538797Jason Sams#include <media/EffectsFactoryApi.h> 425c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams 4386d842a703da80b40eae5a482d4e26d8b2aae048Jason Sams#include "AudioMixer.h" 445c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams 456b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Samsnamespace android { 466b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams 476b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams// ---------------------------------------------------------------------------- 485c1c79a54c63b9de8c391f7ed890c02f280ec17fJason SamsAudioMixer::DownmixerBufferProvider::DownmixerBufferProvider() : AudioBufferProvider(), 49326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mTrackBufferProvider(NULL), mDownmixHandle(NULL) 50326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{ 51afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk} 524b3de47071d875faaa7d419d050a464b09538797Jason Sams 5333b6e3b91329080e5cdd0b8fdbcd3e6a906032aeJason SamsAudioMixer::DownmixerBufferProvider::~DownmixerBufferProvider() 5433b6e3b91329080e5cdd0b8fdbcd3e6a906032aeJason Sams{ 5560709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams ALOGV("AudioMixer deleting DownmixerBufferProvider (%p)", this); 5660709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams EffectRelease(mDownmixHandle); 57c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams} 58c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams 59c946b614ee6c983215cc3de7834a7a334f860d68Jason Samsstatus_t AudioMixer::DownmixerBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer, 60c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams int64_t pts) { 61c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams //ALOGV("DownmixerBufferProvider::getNextBuffer()"); 62c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams if (mTrackBufferProvider != NULL) { 63c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts); 6460709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams if (res == OK) { 6560709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams mDownmixConfig.inputCfg.buffer.frameCount = pBuffer->frameCount; 6660709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams mDownmixConfig.inputCfg.buffer.raw = pBuffer->raw; 67c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams mDownmixConfig.outputCfg.buffer.frameCount = pBuffer->frameCount; 68c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams mDownmixConfig.outputCfg.buffer.raw = mDownmixConfig.inputCfg.buffer.raw; 69c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams // in-place so overwrite the buffer contents, has been set in prepareTrackForDownmix() 70c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams //mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE; 71c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams 72c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams res = (*mDownmixHandle)->process(mDownmixHandle, 73c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams &mDownmixConfig.inputCfg.buffer, &mDownmixConfig.outputCfg.buffer); 7460709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams //ALOGV("getNextBuffer is downmixing"); 7560709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams } 7633b6e3b91329080e5cdd0b8fdbcd3e6a906032aeJason Sams return res; 77afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk } else { 7860709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams ALOGE("DownmixerBufferProvider::getNextBuffer() error: NULL track buffer provider"); 791030893d9b99b72468034da13df025bda479bb97Jason Sams return NO_INIT; 80c61346b91434307c5003029017b54ce9c49112beJason Sams } 81c9d43db4d216b01b13aebfdb31d5615909591b33Jason Sams} 821030893d9b99b72468034da13df025bda479bb97Jason Sams 831030893d9b99b72468034da13df025bda479bb97Jason Samsvoid AudioMixer::DownmixerBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) { 84afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk //ALOGV("DownmixerBufferProvider::releaseBuffer()"); 852dca84dd6c07992f78ad050177975f16486dd77eJason Sams if (mTrackBufferProvider != NULL) { 868c401effb0837155fc39ca0364f57a882d127d38Jason Sams mTrackBufferProvider->releaseBuffer(pBuffer); 872382aba4a55c6ae74789c478eead8fbd96593321Jason Sams } else { 88c61346b91434307c5003029017b54ce9c49112beJason Sams ALOGE("DownmixerBufferProvider::releaseBuffer() error: NULL track buffer provider"); 892382aba4a55c6ae74789c478eead8fbd96593321Jason Sams } 908cfdd24fec22080b72266d33f61befc4a98b77c6Jason Sams} 9124371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams 9224371d93cdb6999971c4058f78974da3c3d5fc64Jason Samstemplate <typename T> 93cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason SamsT min(const T& a, const T& b) 94afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk{ 95b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk return a < b ? a : b; 9624371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams} 9724371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams 9824371d93cdb6999971c4058f78974da3c3d5fc64Jason SamsAudioMixer::ReformatBufferProvider::ReformatBufferProvider(int32_t channels, 99b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk audio_format_t inputFormat, audio_format_t outputFormat) : 100b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk mTrackBufferProvider(NULL), 101b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk mChannels(channels), 10224371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mInputFormat(inputFormat), 103cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Sams mOutputFormat(outputFormat), 104afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk mInputFrameSize(channels * audio_bytes_per_sample(inputFormat)), 10524371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mOutputFrameSize(channels * audio_bytes_per_sample(outputFormat)), 10624371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mOutputData(NULL), 10724371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mOutputCount(0), 10824371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mConsumed(0) 109cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Sams{ 110afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk ALOGV("ReformatBufferProvider(%p)(%d, %#x, %#x)", this, channels, inputFormat, outputFormat); 11124371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams if (requiresInternalBuffers()) { 1121d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams mOutputCount = 256; 1131d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams (void)posix_memalign(&mOutputData, 32, mOutputCount * mOutputFrameSize); 11424371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams } 115c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk mBuffer.frameCount = 0; 116c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk} 117c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk 11824371d93cdb6999971c4058f78974da3c3d5fc64Jason SamsAudioMixer::ReformatBufferProvider::~ReformatBufferProvider() 11924371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams{ 12024371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams ALOGV("~ReformatBufferProvider(%p)", this); 121afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk if (mBuffer.frameCount != 0) { 1221d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams mTrackBufferProvider->releaseBuffer(&mBuffer); 1231d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams } 124c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk free(mOutputData); 125c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk} 126c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk 127c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchoukstatus_t AudioMixer::ReformatBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer, 128afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk int64_t pts) { 129c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk //ALOGV("ReformatBufferProvider(%p)::getNextBuffer(%p (%zu), %lld)", 130c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk // this, pBuffer, pBuffer->frameCount, pts); 131c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk if (!requiresInternalBuffers()) { 132c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts); 133c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk if (res == OK) { 1341d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams memcpy_by_audio_format(pBuffer->raw, mOutputFormat, pBuffer->raw, mInputFormat, 1351d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams pBuffer->frameCount * mChannels); 136afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk } 13724371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams return res; 13824371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams } 13924371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams if (mBuffer.frameCount == 0) { 14024371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mBuffer.frameCount = pBuffer->frameCount; 14124371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams status_t res = mTrackBufferProvider->getNextBuffer(&mBuffer, pts); 14224371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams // TODO: Track down a bug in the upstream provider 143afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk // LOG_ALWAYS_FATAL_IF(res == OK && mBuffer.frameCount == 0, 14424371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams // "ReformatBufferProvider::getNextBuffer():" 14524371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams // " Invalid zero framecount returned from getNextBuffer()"); 14624371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams if (res != OK || mBuffer.frameCount == 0) { 14724371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams pBuffer->raw = NULL; 1481d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams pBuffer->frameCount = 0; 1492dca84dd6c07992f78ad050177975f16486dd77eJason Sams return res; 1502dca84dd6c07992f78ad050177975f16486dd77eJason Sams } 1512dca84dd6c07992f78ad050177975f16486dd77eJason Sams } 15224371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams ALOG_ASSERT(mConsumed < mBuffer.frameCount); 1532dca84dd6c07992f78ad050177975f16486dd77eJason Sams size_t count = min(mOutputCount, mBuffer.frameCount - mConsumed); 1542dca84dd6c07992f78ad050177975f16486dd77eJason Sams count = min(count, pBuffer->frameCount); 15564cd98e83d33011950b88f229d013e06c62b36e9Alex Sakhartchouk pBuffer->raw = mOutputData; 1562dca84dd6c07992f78ad050177975f16486dd77eJason Sams pBuffer->frameCount = count; 1572dca84dd6c07992f78ad050177975f16486dd77eJason Sams //ALOGV("reformatting %d frames from %#x to %#x, %d chan", 1582dca84dd6c07992f78ad050177975f16486dd77eJason Sams // pBuffer->frameCount, mInputFormat, mOutputFormat, mChannels); 1592dca84dd6c07992f78ad050177975f16486dd77eJason Sams memcpy_by_audio_format(pBuffer->raw, mOutputFormat, 160c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk (uint8_t*)mBuffer.raw + mConsumed * mInputFrameSize, mInputFormat, 161c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk pBuffer->frameCount * mChannels); 1622dca84dd6c07992f78ad050177975f16486dd77eJason Sams return OK; 163326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 164326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 165afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid AudioMixer::ReformatBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) { 166900f1616bf33c7ba13cf2a737832a95bcd176388Jason Sams //ALOGV("ReformatBufferProvider(%p)::releaseBuffer(%p(%zu))", 167721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams // this, pBuffer, pBuffer->frameCount); 168c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk if (!requiresInternalBuffers()) { 169721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams mTrackBufferProvider->releaseBuffer(pBuffer); 170c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk return; 171c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk } 172a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams // LOG_ALWAYS_FATAL_IF(pBuffer->frameCount == 0, "Invalid framecount"); 173326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams mConsumed += pBuffer->frameCount; // TODO: update for efficiency to reuse existing content 174326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (mConsumed != 0 && mConsumed >= mBuffer.frameCount) { 175889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchouk mConsumed = 0; 176721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams mTrackBufferProvider->releaseBuffer(&mBuffer); 177889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchouk // ALOG_ASSERT(mBuffer.frameCount == 0); 178889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchouk } 179afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk pBuffer->raw = NULL; 18076371fff76412fd020e24ddb8bf1ddb5c75f0ed1Joe Onorato pBuffer->frameCount = 0; 1811fddd90849deaae89b546ff492c345d485bbce42Jason Sams} 18276371fff76412fd020e24ddb8bf1ddb5c75f0ed1Joe Onorato 18376371fff76412fd020e24ddb8bf1ddb5c75f0ed1Joe Onoratovoid AudioMixer::ReformatBufferProvider::reset() { 184326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (mBuffer.frameCount != 0) { 185afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk mTrackBufferProvider->releaseBuffer(&mBuffer); 1860cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk } 187c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk mConsumed = 0; 188ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk} 189ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk 19009c67356bbeee0a97a20a06c95b66756838cb541Alex Sakhartchouk// ---------------------------------------------------------------------------- 1910cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchoukbool AudioMixer::sIsMultichannelCapable = false; 1921809bde133e0d66f06cea65887d9ceb3c70f8b95Alex Sakhartchouk 1931809bde133e0d66f06cea65887d9ceb3c70f8b95Alex Sakhartchoukeffect_descriptor_t AudioMixer::sDwnmFxDesc; 19409c67356bbeee0a97a20a06c95b66756838cb541Alex Sakhartchouk 195ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk// Ensure mConfiguredNames bitmask is initialized properly on all architectures. 196c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk// The value of 1 << x is undefined in C when x >= 32. 1970cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk 19809c67356bbeee0a97a20a06c95b66756838cb541Alex SakhartchoukAudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks) 199c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk : mTrackNames(0), mConfiguredNames((maxNumTracks >= 32 ? 0 : 1 << maxNumTracks) - 1), 2000cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk mSampleRate(sampleRate) 2011809bde133e0d66f06cea65887d9ceb3c70f8b95Alex Sakhartchouk{ 202ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk // AudioMixer is not yet capable of multi-channel beyond stereo 2030cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk COMPILE_TIME_ASSERT_FUNCTION_SCOPE(2 == MAX_NUM_CHANNELS); 2040cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk 205afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u", 20683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams maxNumTracks, MAX_NUM_TRACKS); 207b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk 20883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // AudioMixer is not yet capable of more than 32 active track inputs 20983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams ALOG_ASSERT(32 >= MAX_NUM_TRACKS, "bad MAX_NUM_TRACKS %d", MAX_NUM_TRACKS); 21083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams 211b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk // AudioMixer is not yet capable of multi-channel output beyond stereo 21283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams ALOG_ASSERT(2 == MAX_NUM_CHANNELS, "bad MAX_NUM_CHANNELS %d", MAX_NUM_CHANNELS); 21383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams 21483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams pthread_once(&sOnceControl, &sInitRoutine); 21583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams 21683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams mState.enabledTracks= 0; 21783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams mState.needsChanged = 0; 21883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams mState.frameCount = frameCount; 21983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams mState.hook = process__nop; 22083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams mState.outputTemp = NULL; 221d3e7107c60ce06d637d83fa0db783ecdd0ad534cJason Sams mState.resampleTemp = NULL; 22283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams mState.mLog = &mDummyLog; 22383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // mState.reserved 22483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams 22583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // FIXME Most of the following initialization is probably redundant since 22683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0 22783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // and mTrackNames is initially 0. However, leave it here until that's verified. 228d3e7107c60ce06d637d83fa0db783ecdd0ad534cJason Sams track_t* t = mState.tracks; 229d3e7107c60ce06d637d83fa0db783ecdd0ad534cJason Sams for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) { 230d3e7107c60ce06d637d83fa0db783ecdd0ad534cJason Sams t->resampler = NULL; 231d3e7107c60ce06d637d83fa0db783ecdd0ad534cJason Sams t->downmixerBufferProvider = NULL; 232d3e7107c60ce06d637d83fa0db783ecdd0ad534cJason Sams t++; 23383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams } 23483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams 23583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams} 23683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams 23783c451a4ef4388e002482e383d488ca9b7b7600dJason SamsAudioMixer::~AudioMixer() 23883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams{ 23983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams track_t* t = mState.tracks; 24083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) { 24183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams delete t->resampler; 24283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams delete t->downmixerBufferProvider; 243c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk t++; 244da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk } 24583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams delete [] mState.outputTemp; 24683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams delete [] mState.resampleTemp; 24783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams} 24883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams 249e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Samsvoid AudioMixer::setLog(NBLog::Writer *log) 250e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams{ 251e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams mState.mLog = log; 25283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams} 253e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams 254e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Samsint AudioMixer::getTrackName(audio_channel_mask_t channelMask, 255dc314a172d48479053f258b485d7d0284b5b5b1fJason Sams audio_format_t format, int sessionId) 256dc314a172d48479053f258b485d7d0284b5b5b1fJason Sams{ 257dc314a172d48479053f258b485d7d0284b5b5b1fJason Sams if (!isValidPcmTrackFormat(format)) { 258dc314a172d48479053f258b485d7d0284b5b5b1fJason Sams ALOGE("AudioMixer::getTrackName invalid format (%#x)", format); 259dc314a172d48479053f258b485d7d0284b5b5b1fJason Sams return -1; 260e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams } 261e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams uint32_t names = (~mTrackNames) & mConfiguredNames; 262e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams if (names != 0) { 26383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams int n = __builtin_ctz(names); 2647257c7ee4b66f00c43d9235f3ac600061ae79968Alex Sakhartchouk ALOGV("add track (%d)", n); 26583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // assume default parameters for the track, except where noted below 26683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams track_t* t = &mState.tracks[n]; 267e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams t->needs = 0; 268e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams t->volume[0] = UNITY_GAIN_INT; 269dc314a172d48479053f258b485d7d0284b5b5b1fJason Sams t->volume[1] = UNITY_GAIN_INT; 27083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // no initialization needed 27183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // t->prevVolume[0] 27283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // t->prevVolume[1] 27383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->volumeInc[0] = 0; 27483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->volumeInc[1] = 0; 275e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams t->auxLevel = 0; 27683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->auxInc = 0; 27783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // no initialization needed 27883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // t->prevAuxLevel 27983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // t->frameCount 28083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->channelCount = audio_channel_count_from_out_mask(channelMask); 28183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->enabled = false; 282ca7c202abc3853e96d1d0d77b672789622eff99dJason Sams ALOGV_IF(channelMask != AUDIO_CHANNEL_OUT_STEREO, 283ca7c202abc3853e96d1d0d77b672789622eff99dJason Sams "Non-stereo channel mask: %d\n", channelMask); 28483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->channelMask = channelMask; 28583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->sessionId = sessionId; 28683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // setBufferProvider(name, AudioBufferProvider *) is required before enable(name) 28786d842a703da80b40eae5a482d4e26d8b2aae048Jason Sams t->bufferProvider = NULL; 28883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->buffer.raw = NULL; 28983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // no initialization needed 29083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // t->buffer.frameCount 29183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->hook = NULL; 29283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->in = NULL; 29383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->resampler = NULL; 29483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->sampleRate = mSampleRate; 29586d842a703da80b40eae5a482d4e26d8b2aae048Jason Sams // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name) 29683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams t->mainBuffer = NULL; 297326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams t->auxBuffer = NULL; 298326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams t->mInputBufferProvider = NULL; 299741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams t->mReformatBufferProvider = NULL; 300249d453869cca82dcb57123f6d1c8df3ca9f4372Jason Sams t->downmixerBufferProvider = NULL; 3012e8665de7c0eb4514c67baf8693d61c892e5303dJason Sams t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT; 302741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams t->mFormat = format; 303741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams t->mMixerInFormat = AUDIO_FORMAT_PCM_16_BIT; 304741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams if (t->mFormat != t->mMixerInFormat) { 305741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams prepareTrackForReformat(t, n); 306741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams } 307741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams status_t status = initTrackDownmix(&mState.tracks[n], n, channelMask); 308741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams if (status != OK) { 309741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask); 310741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams return -1; 311741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams } 312741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams mTrackNames |= 1 << n; 313741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams return TRACK0 + n; 314c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk } 315da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk ALOGE("AudioMixer::getTrackName out of available tracks"); 316741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams return -1; 317c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams} 318249d453869cca82dcb57123f6d1c8df3ca9f4372Jason Sams 319cf912de17f1e086ccea707d8607a3d2eda56b98fJason Samsvoid AudioMixer::invalidateState(uint32_t mask) 320741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams{ 321741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams if (mask != 0) { 3222382aba4a55c6ae74789c478eead8fbd96593321Jason Sams mState.needsChanged |= mask; 3232382aba4a55c6ae74789c478eead8fbd96593321Jason Sams mState.hook = process__validate; 324ee803446857b14d97f3e90a4f530604b6be9c867Jason Sams } 325ee803446857b14d97f3e90a4f530604b6be9c867Jason Sams } 326ee803446857b14d97f3e90a4f530604b6be9c867Jason Sams 327ee803446857b14d97f3e90a4f530604b6be9c867Jason Samsstatus_t AudioMixer::initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask) 328ee803446857b14d97f3e90a4f530604b6be9c867Jason Sams{ 329ee803446857b14d97f3e90a4f530604b6be9c867Jason Sams uint32_t channelCount = audio_channel_count_from_out_mask(mask); 3302382aba4a55c6ae74789c478eead8fbd96593321Jason Sams ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount); 3312382aba4a55c6ae74789c478eead8fbd96593321Jason Sams status_t status = OK; 3322382aba4a55c6ae74789c478eead8fbd96593321Jason Sams if (channelCount > MAX_NUM_CHANNELS) { 333afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk pTrack->channelMask = mask; 334158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams pTrack->channelCount = channelCount; 335158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams ALOGV("initTrackDownmix(track=%d, mask=0x%x) calls prepareTrackForDownmix()", 336158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams trackNum, mask); 337158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams status = prepareTrackForDownmix(pTrack, trackNum); 3382dca84dd6c07992f78ad050177975f16486dd77eJason Sams } else { 339158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams unprepareTrackForDownmix(pTrack, trackNum); 340158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams } 341158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams return status; 342158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams} 343158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams 344158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Samsvoid AudioMixer::unprepareTrackForDownmix(track_t* pTrack, int trackName __unused) { 345158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams ALOGV("AudioMixer::unprepareTrackForDownmix(%d)", trackName); 346158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams 347158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams if (pTrack->downmixerBufferProvider != NULL) { 3487bf29ddc35450d8064541c42c99a1f48be6cf0ddJason Sams // this track had previously been configured with a downmixer, delete it 349158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams ALOGV(" deleting old downmixer"); 350158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams delete pTrack->downmixerBufferProvider; 351158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams pTrack->downmixerBufferProvider = NULL; 352afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk reconfigureBufferProviders(pTrack); 3535c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams } else { 354326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams ALOGV(" nothing to do, no downmixer to delete"); 355326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 35686f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams} 357e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams 358a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Samsstatus_t AudioMixer::prepareTrackForDownmix(track_t* pTrack, int trackName) 359cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines{ 3607b3e9bd825901e33661e3c385e3e7c6f40ca6000Alex Sakhartchouk ALOGV("AudioMixer::prepareTrackForDownmix(%d) with mask 0x%x", trackName, pTrack->channelMask); 361b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk 36286c6b5fecb3e4e68668fdb5640770545501e778fStephen Hines // discard the previous downmixer if there was one 3635c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams unprepareTrackForDownmix(pTrack, trackName); 3645c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams 365afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk DownmixerBufferProvider* pDbp = new DownmixerBufferProvider(); 3665c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams int32_t status; 367b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk 3685c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams if (!sIsMultichannelCapable) { 3695c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams ALOGE("prepareTrackForDownmix(%d) fails: mixer doesn't support multichannel content", 3705c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams trackName); 3715c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams goto noDownmixForActiveTrack; 3725c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams } 3735c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams 3745c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams if (EffectCreate(&sDwnmFxDesc.uuid, 375b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk pTrack->sessionId /*sessionId*/, -2 /*ioId not relevant here, using random value*/, 376b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk &pDbp->mDownmixHandle/*pHandle*/) != 0) { 377b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGE("prepareTrackForDownmix(%d) fails: error creating downmixer effect", trackName); 378b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk goto noDownmixForActiveTrack; 379b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk } 380b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk 381afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk // channel input configuration will be overridden per-track 3825c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams pDbp->mDownmixConfig.inputCfg.channels = pTrack->channelMask; 3835c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams pDbp->mDownmixConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 3841a4efa363916977ef9aeab756725b3bdc880a15bJason Sams pDbp->mDownmixConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 3852382aba4a55c6ae74789c478eead8fbd96593321Jason Sams pDbp->mDownmixConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 3861a4efa363916977ef9aeab756725b3bdc880a15bJason Sams pDbp->mDownmixConfig.inputCfg.samplingRate = pTrack->sampleRate; 3875c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams pDbp->mDownmixConfig.outputCfg.samplingRate = pTrack->sampleRate; 3885c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams pDbp->mDownmixConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; 3896b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams pDbp->mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE; 3906b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams // input and output buffer provider, and frame count will not be used as the downmix effect 3916b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams // process() function is called directly (see DownmixerBufferProvider::getNextBuffer()) 3926b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams pDbp->mDownmixConfig.inputCfg.mask = EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | 3936b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams EFFECT_CONFIG_FORMAT | EFFECT_CONFIG_ACC_MODE; 394a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams pDbp->mDownmixConfig.outputCfg.mask = pDbp->mDownmixConfig.inputCfg.mask; 3956b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams 396326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams {// scope for local variables that are not used in goto label "noDownmixForActiveTrack" 397a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams int cmdStatus; 398a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams uint32_t replySize = sizeof(int); 399a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams 400fb03a22ad2adadc1ff50a8b50d43ad7fcc3fa6edJason Sams // Configure and enable downmixer 401fb03a22ad2adadc1ff50a8b50d43ad7fcc3fa6edJason Sams status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle, 402fb03a22ad2adadc1ff50a8b50d43ad7fcc3fa6edJason Sams EFFECT_CMD_SET_CONFIG /*cmdCode*/, sizeof(effect_config_t) /*cmdSize*/, 403e57691037aea219562ac686429b4b98202aab7bcJason Sams &pDbp->mDownmixConfig /*pCmdData*/, 404a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams &replySize /*replySize*/, &cmdStatus /*pReplyData*/); 405a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams if ((status != 0) || (cmdStatus != 0)) { 406a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams ALOGE("error %d while configuring downmixer for track %d", status, trackName); 4075c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams goto noDownmixForActiveTrack; 408a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams } 409a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams replySize = sizeof(int); 4107257c7ee4b66f00c43d9235f3ac600061ae79968Alex Sakhartchouk status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle, 411992a0b70d8fd7a14f0c57bc3c7e16c1f269a6609Jason Sams EFFECT_CMD_ENABLE /*cmdCode*/, 0 /*cmdSize*/, NULL /*pCmdData*/, 41224371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams &replySize /*replySize*/, &cmdStatus /*pReplyData*/); 413a891933b4c5ab1b63103add167269cfc404c2adfJason Sams if ((status != 0) || (cmdStatus != 0)) { 4145086938044e0a9b6b1138f915d0d252fe046e102Jason Sams ALOGE("error %d while enabling downmixer for track %d", status, trackName); 415a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams goto noDownmixForActiveTrack; 416326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 417326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 4185c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams // Set downmix type 4197bf29ddc35450d8064541c42c99a1f48be6cf0ddJason Sams // parameter size rounded for padding on 32bit boundary 420afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk const int psizePadded = ((sizeof(downmix_params_t) - 1)/sizeof(int) + 1) * sizeof(int); 421181334092f78273d0da2d854ebbe7b24508d3bfcJason Sams const int downmixParamSize = 422181334092f78273d0da2d854ebbe7b24508d3bfcJason Sams sizeof(effect_param_t) + psizePadded + sizeof(downmix_type_t); 423181334092f78273d0da2d854ebbe7b24508d3bfcJason Sams effect_param_t * const param = (effect_param_t *) malloc(downmixParamSize); 4245c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams param->psize = sizeof(downmix_params_t); 4252cfe51e7a9eef3dec091ce7c15d2a5a2216e9d3eJason Sams const downmix_params_t downmixParam = DOWNMIX_PARAM_TYPE; 4265c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams memcpy(param->data, &downmixParam, param->psize); 4275c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams const downmix_type_t downmixType = DOWNMIX_TYPE_FOLD; 4285c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams param->vsize = sizeof(downmix_type_t); 429a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams memcpy(param->data + psizePadded, &downmixType, param->vsize); 4305c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams 431326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle, 432326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams EFFECT_CMD_SET_PARAM /* cmdCode */, downmixParamSize/* cmdSize */, 433afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk param /*pCmndData*/, &replySize /*replySize*/, &cmdStatus /*pReplyData*/); 43486d842a703da80b40eae5a482d4e26d8b2aae048Jason Sams 435cf912de17f1e086ccea707d8607a3d2eda56b98fJason Sams free(param); 436b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk 437b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk if ((status != 0) || (cmdStatus != 0)) { 438b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGE("error %d while setting downmix type for track %d", status, trackName); 439b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk goto noDownmixForActiveTrack; 440b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk } else { 441b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGV("downmix type set to %d for track %d", (int) downmixType, trackName); 442326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 443b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk }// end of scope for local variables that are not used in goto label "noDownmixForActiveTrack" 444b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk 445326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams // initialization successful: 446b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk pTrack->downmixerBufferProvider = pDbp; 447b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk reconfigureBufferProviders(pTrack); 448b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk return NO_ERROR; 449249d453869cca82dcb57123f6d1c8df3ca9f4372Jason Sams 450b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex SakhartchouknoDownmixForActiveTrack: 451b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk delete pDbp; 452b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk pTrack->downmixerBufferProvider = NULL; 453b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk reconfigureBufferProviders(pTrack); 454b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk return NO_INIT; 455b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk} 456b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk 457326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsvoid AudioMixer::unprepareTrackForReformat(track_t* pTrack, int trackName __unused) { 45886d842a703da80b40eae5a482d4e26d8b2aae048Jason Sams ALOGV("AudioMixer::unprepareTrackForReformat(%d)", trackName); 459326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (pTrack->mReformatBufferProvider != NULL) { 460326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams delete pTrack->mReformatBufferProvider; 4617257c7ee4b66f00c43d9235f3ac600061ae79968Alex Sakhartchouk pTrack->mReformatBufferProvider = NULL; 4624820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams reconfigureBufferProviders(pTrack); 4634b3de47071d875faaa7d419d050a464b09538797Jason Sams } 464458f2dc26b7d34c2138c7bfbd95914240084e6bdJason Sams} 4657257c7ee4b66f00c43d9235f3ac600061ae79968Alex Sakhartchouk 4664b3de47071d875faaa7d419d050a464b09538797Jason Samsstatus_t AudioMixer::prepareTrackForReformat(track_t* pTrack, int trackName) 4674b3de47071d875faaa7d419d050a464b09538797Jason Sams{ 468613cad1702dbb76eb2a6ba0cfcb43b9fe207cebcJason Sams ALOGV("AudioMixer::prepareTrackForReformat(%d) with format %#x", trackName, pTrack->mFormat); 4694b3de47071d875faaa7d419d050a464b09538797Jason Sams // discard the previous reformatter if there was one 470771565f47fc44608444c00aa8fa3bda769ceaeceJason Sams unprepareTrackForReformat(pTrack, trackName); 471a544b6368d7ddae47985da92d6bcf86798b376c6Alex Sakhartchouk pTrack->mReformatBufferProvider = new ReformatBufferProvider( 472458f2dc26b7d34c2138c7bfbd95914240084e6bdJason Sams audio_channel_count_from_out_mask(pTrack->channelMask), 473458f2dc26b7d34c2138c7bfbd95914240084e6bdJason Sams pTrack->mFormat, pTrack->mMixerInFormat); 474458f2dc26b7d34c2138c7bfbd95914240084e6bdJason Sams reconfigureBufferProviders(pTrack); 475afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk return NO_ERROR; 4764820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams} 47786f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams 47886f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Samsvoid AudioMixer::reconfigureBufferProviders(track_t* pTrack) 47986f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams{ 480afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk pTrack->bufferProvider = pTrack->mInputBufferProvider; 4814820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams if (pTrack->mReformatBufferProvider) { 48286f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams pTrack->mReformatBufferProvider->mTrackBufferProvider = pTrack->bufferProvider; 48386f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams pTrack->bufferProvider = pTrack->mReformatBufferProvider; 48486f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams } 485afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk if (pTrack->downmixerBufferProvider) { 4864820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams pTrack->downmixerBufferProvider->mTrackBufferProvider = pTrack->bufferProvider; 487326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams pTrack->bufferProvider = pTrack->downmixerBufferProvider; 488326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 489326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 49060709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams 4914820e8bb83b1f78e6232ebe853221f737da2a1eaJason Samsvoid AudioMixer::deleteTrackName(int name) 4928ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams{ 4938ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams ALOGV("AudioMixer::deleteTrackName(%d)", name); 4948ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams name -= TRACK0; 4958ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); 4968ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams ALOGV("deleteTrackName(%d)", name); 497326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams track_t& track(mState.tracks[ name ]); 498326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (track.enabled) { 49960709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams track.enabled = false; 5004820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams invalidateState(1<<name); 5018ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams } 5028ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams // delete the resampler 5038ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams delete track.resampler; 5048ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams track.resampler = NULL; 5058ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams // delete the downmixer 506cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Sams unprepareTrackForDownmix(&mState.tracks[name], name); 507cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Sams // delete the reformatter 50860709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams unprepareTrackForReformat(&mState.tracks[name], name); 5094820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams 5105fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams mTrackNames &= ~(1<<name); 5115fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams} 5125fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams 5135fd09d847586f9680b4f495413b6ca5fbb69af6eJason Samsvoid AudioMixer::enable(int name) 5145fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams{ 5155fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams name -= TRACK0; 5165fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); 51760709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams track_t& track = mState.tracks[name]; 5184820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams 5198ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams if (!track.enabled) { 5208ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams track.enabled = true; 5218ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams ALOGV("enable(%d)", name); 5228ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams invalidateState(1 << name); 5238ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams } 524326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 525326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 526afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid AudioMixer::disable(int name) 527d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 528d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk name -= TRACK0; 529d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); 530d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk track_t& track = mState.tracks[name]; 531d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 532d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if (track.enabled) { 533d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk track.enabled = false; 534d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk ALOGV("disable(%d)", name); 535afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk invalidateState(1 << name); 536a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams } 537a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams} 538a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams 539a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams/* Sets the volume ramp variables for the AudioMixer. 540a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams * 541afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk * The volume ramp variables are used to transition between the previous 542afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk * volume to the target volume. The duration of the transition is 543a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams * set by ramp, which is either 0 for immediate, or typically one state 544a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams * framecount period. 545a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams * 546a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams * @param newFloatValue new volume target in float [0.0, 1.0]. 547a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams * @param ramp number of frames to increment over. ramp is 0 if the volume 548a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams * should be set immediately. 549a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams * @param volume reference to the U4.12 target volume, set on return. 5501a4efa363916977ef9aeab756725b3bdc880a15bJason Sams * @param prevVolume reference to the U4.27 previous volume, set on return. 5511a4efa363916977ef9aeab756725b3bdc880a15bJason Sams * @param volumeInc reference to the increment per output audio frame, set on return. 552aad4bc5231dd7059fc5148b34a951117d9b5f4adJason Sams * @return true if the volume has changed, false if volume is same. 553aad4bc5231dd7059fc5148b34a951117d9b5f4adJason Sams */ 5541a4efa363916977ef9aeab756725b3bdc880a15bJason Samsstatic inline bool setVolumeRampVariables(float newFloatValue, int32_t ramp, 5551a4efa363916977ef9aeab756725b3bdc880a15bJason Sams int16_t &volume, int32_t &prevVolume, int32_t &volumeInc) { 5568c401effb0837155fc39ca0364f57a882d127d38Jason Sams int32_t newValue = newFloatValue * AudioMixer::UNITY_GAIN_INT; 5578c401effb0837155fc39ca0364f57a882d127d38Jason Sams if (newValue > AudioMixer::UNITY_GAIN_INT) { 55887319de2b16a185cf360827c96a42cf1fcaae744Jason Sams newValue = AudioMixer::UNITY_GAIN_INT; 55987319de2b16a185cf360827c96a42cf1fcaae744Jason Sams } else if (newValue < 0) { 5601a4efa363916977ef9aeab756725b3bdc880a15bJason Sams ALOGE("negative volume %.7g", newFloatValue); 5611a4efa363916977ef9aeab756725b3bdc880a15bJason Sams newValue = 0; // should never happen, but for safety check. 5628c401effb0837155fc39ca0364f57a882d127d38Jason Sams } 5638c401effb0837155fc39ca0364f57a882d127d38Jason Sams if (newValue == volume) { 564afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk return false; 565afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk } 5668c401effb0837155fc39ca0364f57a882d127d38Jason Sams if (ramp != 0) { 5678c401effb0837155fc39ca0364f57a882d127d38Jason Sams volumeInc = ((newValue - volume) << 16) / ramp; 5688c401effb0837155fc39ca0364f57a882d127d38Jason Sams prevVolume = (volumeInc == 0 ? newValue : volume) << 16; 5698c401effb0837155fc39ca0364f57a882d127d38Jason Sams } else { 570afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk volumeInc = 0; 5711a4efa363916977ef9aeab756725b3bdc880a15bJason Sams prevVolume = newValue << 16; 5728c401effb0837155fc39ca0364f57a882d127d38Jason Sams } 5735086938044e0a9b6b1138f915d0d252fe046e102Jason Sams volume = newValue; 57487319de2b16a185cf360827c96a42cf1fcaae744Jason Sams return true; 575a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams} 576aad4bc5231dd7059fc5148b34a951117d9b5f4adJason Sams 577a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Samsvoid AudioMixer::setParameter(int name, int target, int param, void *value) 578a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams{ 579a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams name -= TRACK0; 580afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); 58113e2634a71a30d289ed8d821aef61c7d1687460eJason Sams track_t& track = mState.tracks[name]; 58213e2634a71a30d289ed8d821aef61c7d1687460eJason Sams 58313e2634a71a30d289ed8d821aef61c7d1687460eJason Sams int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value)); 58413e2634a71a30d289ed8d821aef61c7d1687460eJason Sams int32_t *valueBuf = reinterpret_cast<int32_t*>(value); 5856b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams 586b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk switch (target) { 58713e2634a71a30d289ed8d821aef61c7d1687460eJason Sams 588a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams case TRACK: 589326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams switch (param) { 590a44cb29164726cd9d812117819abdd7b60dfdd93Jason Sams case CHANNEL_MASK: { 591326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams audio_channel_mask_t mask = 592326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams static_cast<audio_channel_mask_t>(reinterpret_cast<uintptr_t>(value)); 593326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (track.channelMask != mask) { 594326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams uint32_t channelCount = audio_channel_count_from_out_mask(mask); 595afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount); 5968c88090e8cccab103eebe2ff569e116e9f5fb208Jason Sams track.channelMask = mask; 597326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams track.channelCount = channelCount; 598afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk // the mask has changed, does this track need a downmixer? 599326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams initTrackDownmix(&mState.tracks[name], name, mask); 600326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask); 601326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams invalidateState(1 << name); 602326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 603afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk } break; 604326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams case MAIN_BUFFER: 605326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (track.mainBuffer != valueBuf) { 606326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams track.mainBuffer = valueBuf; 607326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf); 608326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams invalidateState(1 << name); 609326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 610326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams break; 611326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams case AUX_BUFFER: 612326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (track.auxBuffer != valueBuf) { 613326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams track.auxBuffer = valueBuf; 614afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf); 615ccc010bb7c0f89e162bf60033968a20be90a903aJason Sams invalidateState(1 << name); 61660709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams } 617326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams break; 618326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams case FORMAT: { 619afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk audio_format_t format = static_cast<audio_format_t>(valueInt); 620326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (track.mFormat != format) { 62160709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format); 622326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams track.mFormat = format; 623326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams ALOGV("setParameter(TRACK, FORMAT, %#x)", format); 624afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk //if (track.mFormat != track.mMixerInFormat) 6255fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams { 62660709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams ALOGD("Reformatting!"); 6275fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams prepareTrackForReformat(&track, name); 6285fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams } 629afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk invalidateState(1 << name); 630326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 63160709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams } break; 632326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams // FIXME do we want to support setting the downmix type from AudioFlinger? 633326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams // for a specific track? or per mixer? 634afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk /* case DOWNMIX_TYPE: 635d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk break */ 636d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk case MIXER_FORMAT: { 637d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk audio_format_t format = static_cast<audio_format_t>(valueInt); 638d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if (track.mMixerFormat != format) { 639b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk track.mMixerFormat = format; 640a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format); 64170b83c111beceaf8fbb700580833e7fec99272cfAlex Sakhartchouk } 642a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams } break; 643326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams default: 644afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk LOG_ALWAYS_FATAL("setParameter track: bad param %d", param); 6452353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams } 646707aaf341a4b068e6ccadf923af85acdd85fd775Jason Sams break; 6479397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams 648707aaf341a4b068e6ccadf923af85acdd85fd775Jason Sams case RESAMPLE: 649707aaf341a4b068e6ccadf923af85acdd85fd775Jason Sams switch (param) { 650afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk case SAMPLE_RATE: 65186f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt); 65286f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams if (track.setResampler(uint32_t(valueInt), mSampleRate)) { 65386f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)", 654afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk uint32_t(valueInt)); 65586f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams invalidateState(1 << name); 65686f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams } 65786f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams break; 6587257c7ee4b66f00c43d9235f3ac600061ae79968Alex Sakhartchouk case RESET: 659fa4028663712dbb1a3d13c507c3bc13c6e4be80dMathias Agopian track.resetResampler(); 660613cad1702dbb76eb2a6ba0cfcb43b9fe207cebcJason Sams invalidateState(1 << name); 661613cad1702dbb76eb2a6ba0cfcb43b9fe207cebcJason Sams break; 662afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk case REMOVE: 663158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams delete track.resampler; 664458f2dc26b7d34c2138c7bfbd95914240084e6bdJason Sams track.resampler = NULL; 665458f2dc26b7d34c2138c7bfbd95914240084e6bdJason Sams track.sampleRate = mSampleRate; 666afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk invalidateState(1 << name); 667c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams break; 668c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams default: 669c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param); 670741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams } 671b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk break; 6721dcefab7178f0644b0e0a6998007b1acae5261cfJason Sams 6731dcefab7178f0644b0e0a6998007b1acae5261cfJason Sams case RAMP_VOLUME: 674c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams case VOLUME: 67586d842a703da80b40eae5a482d4e26d8b2aae048Jason Sams switch (param) { 676741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams case VOLUME0: 677741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams case VOLUME1: 67886d842a703da80b40eae5a482d4e26d8b2aae048Jason Sams if (setVolumeRampVariables(*reinterpret_cast<float*>(value), 679741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams target == RAMP_VOLUME ? mState.frameCount : 0, 680326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams track.volume[param - VOLUME0], track.prevVolume[param - VOLUME0], 681326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams track.volumeInc[param - VOLUME0])) { 682c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams ALOGV("setParameter(%s, VOLUME%d: %04x)", 683186e59154a0fb86e05e283e9c083b69878c06720Jason Sams target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0, 6841a4efa363916977ef9aeab756725b3bdc880a15bJason Sams track.volume[param - VOLUME0]); 6851a4efa363916977ef9aeab756725b3bdc880a15bJason Sams invalidateState(1 << name); 686aad4bc5231dd7059fc5148b34a951117d9b5f4adJason Sams } 687aad4bc5231dd7059fc5148b34a951117d9b5f4adJason Sams break; 688c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams case AUXLEVEL: 689186e59154a0fb86e05e283e9c083b69878c06720Jason Sams //ALOG_ASSERT(0 <= valueInt && valueInt <= MAX_GAIN_INT, "bad aux level %d", valueInt); 6901a4efa363916977ef9aeab756725b3bdc880a15bJason Sams if (setVolumeRampVariables(*reinterpret_cast<float*>(value), 691186e59154a0fb86e05e283e9c083b69878c06720Jason Sams target == RAMP_VOLUME ? mState.frameCount : 0, 692186e59154a0fb86e05e283e9c083b69878c06720Jason Sams track.auxLevel, track.prevAuxLevel, track.auxInc)) { 6931a4efa363916977ef9aeab756725b3bdc880a15bJason Sams ALOGV("setParameter(%s, AUXLEVEL: %04x)", 6948c401effb0837155fc39ca0364f57a882d127d38Jason Sams target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track.auxLevel); 6958c401effb0837155fc39ca0364f57a882d127d38Jason Sams invalidateState(1 << name); 696c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams } 6978c401effb0837155fc39ca0364f57a882d127d38Jason Sams break; 6988c401effb0837155fc39ca0364f57a882d127d38Jason Sams default: 6998c401effb0837155fc39ca0364f57a882d127d38Jason Sams LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param); 700c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams } 7018c401effb0837155fc39ca0364f57a882d127d38Jason Sams break; 7028c401effb0837155fc39ca0364f57a882d127d38Jason Sams 7038c401effb0837155fc39ca0364f57a882d127d38Jason Sams default: 704c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams LOG_ALWAYS_FATAL("setParameter: bad target %d", target); 705c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams } 706c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams} 707cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines 708cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hinesbool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate) 70986d842a703da80b40eae5a482d4e26d8b2aae048Jason Sams{ 710789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams if (value != devSampleRate || resampler != NULL) { 711789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams if (sampleRate != value) { 712cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines sampleRate = value; 713cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines if (resampler == NULL) { 714cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines ALOGV("creating resampler from track %d Hz to device %d Hz", value, devSampleRate); 715789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams AudioResampler::src_quality quality; 716789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams // force lowest quality level resampler if use case isn't music or video 717789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams // FIXME this is flawed for dynamic sample rates, as we choose the resampler 718789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams // quality level based on the initial ratio, but that could change later. 719cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines // Should have a way to distinguish tracks with static ratios vs. dynamic ratios. 720cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines if (!((value == 44100 && devSampleRate == 48000) || 72186d842a703da80b40eae5a482d4e26d8b2aae048Jason Sams (value == 48000 && devSampleRate == 44100))) { 722789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams quality = AudioResampler::DYN_LOW_QUALITY; 723789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams } else { 7249544f76195de22f655fd7a1894934667e7e55f6aJason Sams quality = AudioResampler::DEFAULT_QUALITY; 725cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines } 7269544f76195de22f655fd7a1894934667e7e55f6aJason Sams const int bits = mMixerInFormat == AUDIO_FORMAT_PCM_16_BIT ? 16 : /* FLOAT */ 32; 7279544f76195de22f655fd7a1894934667e7e55f6aJason Sams resampler = AudioResampler::create( 72886d842a703da80b40eae5a482d4e26d8b2aae048Jason Sams bits, 729789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams // the resampler sees the number of channels after the downmixer, if any 730789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams (int) (downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount), 731789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams devSampleRate, quality); 732dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk resampler->setLocalTimeFreq(sLocalTimeFreq); 733dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk } 734afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk return true; 735dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk } 736dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk } 737dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk return false; 738} 739 740inline 741void AudioMixer::track_t::adjustVolumeRamp(bool aux) 742{ 743 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) { 744 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) || 745 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) { 746 volumeInc[i] = 0; 747 prevVolume[i] = volume[i]<<16; 748 } 749 } 750 if (aux) { 751 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) || 752 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) { 753 auxInc = 0; 754 prevAuxLevel = auxLevel<<16; 755 } 756 } 757} 758 759size_t AudioMixer::getUnreleasedFrames(int name) const 760{ 761 name -= TRACK0; 762 if (uint32_t(name) < MAX_NUM_TRACKS) { 763 return mState.tracks[name].getUnreleasedFrames(); 764 } 765 return 0; 766} 767 768void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider) 769{ 770 name -= TRACK0; 771 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); 772 773 if (mState.tracks[name].mInputBufferProvider == bufferProvider) { 774 return; // don't reset any buffer providers if identical. 775 } 776 if (mState.tracks[name].mReformatBufferProvider != NULL) { 777 mState.tracks[name].mReformatBufferProvider->reset(); 778 } else if (mState.tracks[name].downmixerBufferProvider != NULL) { 779 } 780 781 mState.tracks[name].mInputBufferProvider = bufferProvider; 782 reconfigureBufferProviders(&mState.tracks[name]); 783} 784 785 786void AudioMixer::process(int64_t pts) 787{ 788 mState.hook(&mState, pts); 789} 790 791 792void AudioMixer::process__validate(state_t* state, int64_t pts) 793{ 794 ALOGW_IF(!state->needsChanged, 795 "in process__validate() but nothing's invalid"); 796 797 uint32_t changed = state->needsChanged; 798 state->needsChanged = 0; // clear the validation flag 799 800 // recompute which tracks are enabled / disabled 801 uint32_t enabled = 0; 802 uint32_t disabled = 0; 803 while (changed) { 804 const int i = 31 - __builtin_clz(changed); 805 const uint32_t mask = 1<<i; 806 changed &= ~mask; 807 track_t& t = state->tracks[i]; 808 (t.enabled ? enabled : disabled) |= mask; 809 } 810 state->enabledTracks &= ~disabled; 811 state->enabledTracks |= enabled; 812 813 // compute everything we need... 814 int countActiveTracks = 0; 815 bool all16BitsStereoNoResample = true; 816 bool resampling = false; 817 bool volumeRamp = false; 818 uint32_t en = state->enabledTracks; 819 while (en) { 820 const int i = 31 - __builtin_clz(en); 821 en &= ~(1<<i); 822 823 countActiveTracks++; 824 track_t& t = state->tracks[i]; 825 uint32_t n = 0; 826 // FIXME can overflow (mask is only 3 bits) 827 n |= NEEDS_CHANNEL_1 + t.channelCount - 1; 828 if (t.doesResample()) { 829 n |= NEEDS_RESAMPLE; 830 } 831 if (t.auxLevel != 0 && t.auxBuffer != NULL) { 832 n |= NEEDS_AUX; 833 } 834 835 if (t.volumeInc[0]|t.volumeInc[1]) { 836 volumeRamp = true; 837 } else if (!t.doesResample() && t.volumeRL == 0) { 838 n |= NEEDS_MUTE; 839 } 840 t.needs = n; 841 842 if (n & NEEDS_MUTE) { 843 t.hook = track__nop; 844 } else { 845 if (n & NEEDS_AUX) { 846 all16BitsStereoNoResample = false; 847 } 848 if (n & NEEDS_RESAMPLE) { 849 all16BitsStereoNoResample = false; 850 resampling = true; 851 t.hook = track__genericResample; 852 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2, 853 "Track %d needs downmix + resample", i); 854 } else { 855 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){ 856 t.hook = track__16BitsMono; 857 all16BitsStereoNoResample = false; 858 } 859 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){ 860 t.hook = track__16BitsStereo; 861 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2, 862 "Track %d needs downmix", i); 863 } 864 } 865 } 866 } 867 868 // select the processing hooks 869 state->hook = process__nop; 870 if (countActiveTracks > 0) { 871 if (resampling) { 872 if (!state->outputTemp) { 873 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount]; 874 } 875 if (!state->resampleTemp) { 876 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount]; 877 } 878 state->hook = process__genericResampling; 879 } else { 880 if (state->outputTemp) { 881 delete [] state->outputTemp; 882 state->outputTemp = NULL; 883 } 884 if (state->resampleTemp) { 885 delete [] state->resampleTemp; 886 state->resampleTemp = NULL; 887 } 888 state->hook = process__genericNoResampling; 889 if (all16BitsStereoNoResample && !volumeRamp) { 890 if (countActiveTracks == 1) { 891 state->hook = process__OneTrack16BitsStereoNoResampling; 892 } 893 } 894 } 895 } 896 897 ALOGV("mixer configuration change: %d activeTracks (%08x) " 898 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d", 899 countActiveTracks, state->enabledTracks, 900 all16BitsStereoNoResample, resampling, volumeRamp); 901 902 state->hook(state, pts); 903 904 // Now that the volume ramp has been done, set optimal state and 905 // track hooks for subsequent mixer process 906 if (countActiveTracks > 0) { 907 bool allMuted = true; 908 uint32_t en = state->enabledTracks; 909 while (en) { 910 const int i = 31 - __builtin_clz(en); 911 en &= ~(1<<i); 912 track_t& t = state->tracks[i]; 913 if (!t.doesResample() && t.volumeRL == 0) { 914 t.needs |= NEEDS_MUTE; 915 t.hook = track__nop; 916 } else { 917 allMuted = false; 918 } 919 } 920 if (allMuted) { 921 state->hook = process__nop; 922 } else if (all16BitsStereoNoResample) { 923 if (countActiveTracks == 1) { 924 state->hook = process__OneTrack16BitsStereoNoResampling; 925 } 926 } 927 } 928} 929 930 931void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, 932 int32_t* temp, int32_t* aux) 933{ 934 t->resampler->setSampleRate(t->sampleRate); 935 936 // ramp gain - resample to temp buffer and scale/mix in 2nd step 937 if (aux != NULL) { 938 // always resample with unity gain when sending to auxiliary buffer to be able 939 // to apply send level after resampling 940 // TODO: modify each resampler to support aux channel? 941 t->resampler->setVolume(UNITY_GAIN_INT, UNITY_GAIN_INT); 942 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t)); 943 t->resampler->resample(temp, outFrameCount, t->bufferProvider); 944 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) { 945 volumeRampStereo(t, out, outFrameCount, temp, aux); 946 } else { 947 volumeStereo(t, out, outFrameCount, temp, aux); 948 } 949 } else { 950 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) { 951 t->resampler->setVolume(UNITY_GAIN_INT, UNITY_GAIN_INT); 952 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t)); 953 t->resampler->resample(temp, outFrameCount, t->bufferProvider); 954 volumeRampStereo(t, out, outFrameCount, temp, aux); 955 } 956 957 // constant gain 958 else { 959 t->resampler->setVolume(t->volume[0], t->volume[1]); 960 t->resampler->resample(out, outFrameCount, t->bufferProvider); 961 } 962 } 963} 964 965void AudioMixer::track__nop(track_t* t __unused, int32_t* out __unused, 966 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused) 967{ 968} 969 970void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, 971 int32_t* aux) 972{ 973 int32_t vl = t->prevVolume[0]; 974 int32_t vr = t->prevVolume[1]; 975 const int32_t vlInc = t->volumeInc[0]; 976 const int32_t vrInc = t->volumeInc[1]; 977 978 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d", 979 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0], 980 // (vl + vlInc*frameCount)/65536.0f, frameCount); 981 982 // ramp volume 983 if (CC_UNLIKELY(aux != NULL)) { 984 int32_t va = t->prevAuxLevel; 985 const int32_t vaInc = t->auxInc; 986 int32_t l; 987 int32_t r; 988 989 do { 990 l = (*temp++ >> 12); 991 r = (*temp++ >> 12); 992 *out++ += (vl >> 16) * l; 993 *out++ += (vr >> 16) * r; 994 *aux++ += (va >> 17) * (l + r); 995 vl += vlInc; 996 vr += vrInc; 997 va += vaInc; 998 } while (--frameCount); 999 t->prevAuxLevel = va; 1000 } else { 1001 do { 1002 *out++ += (vl >> 16) * (*temp++ >> 12); 1003 *out++ += (vr >> 16) * (*temp++ >> 12); 1004 vl += vlInc; 1005 vr += vrInc; 1006 } while (--frameCount); 1007 } 1008 t->prevVolume[0] = vl; 1009 t->prevVolume[1] = vr; 1010 t->adjustVolumeRamp(aux != NULL); 1011} 1012 1013void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, 1014 int32_t* aux) 1015{ 1016 const int16_t vl = t->volume[0]; 1017 const int16_t vr = t->volume[1]; 1018 1019 if (CC_UNLIKELY(aux != NULL)) { 1020 const int16_t va = t->auxLevel; 1021 do { 1022 int16_t l = (int16_t)(*temp++ >> 12); 1023 int16_t r = (int16_t)(*temp++ >> 12); 1024 out[0] = mulAdd(l, vl, out[0]); 1025 int16_t a = (int16_t)(((int32_t)l + r) >> 1); 1026 out[1] = mulAdd(r, vr, out[1]); 1027 out += 2; 1028 aux[0] = mulAdd(a, va, aux[0]); 1029 aux++; 1030 } while (--frameCount); 1031 } else { 1032 do { 1033 int16_t l = (int16_t)(*temp++ >> 12); 1034 int16_t r = (int16_t)(*temp++ >> 12); 1035 out[0] = mulAdd(l, vl, out[0]); 1036 out[1] = mulAdd(r, vr, out[1]); 1037 out += 2; 1038 } while (--frameCount); 1039 } 1040} 1041 1042void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, 1043 int32_t* temp __unused, int32_t* aux) 1044{ 1045 const int16_t *in = static_cast<const int16_t *>(t->in); 1046 1047 if (CC_UNLIKELY(aux != NULL)) { 1048 int32_t l; 1049 int32_t r; 1050 // ramp gain 1051 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) { 1052 int32_t vl = t->prevVolume[0]; 1053 int32_t vr = t->prevVolume[1]; 1054 int32_t va = t->prevAuxLevel; 1055 const int32_t vlInc = t->volumeInc[0]; 1056 const int32_t vrInc = t->volumeInc[1]; 1057 const int32_t vaInc = t->auxInc; 1058 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d", 1059 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0], 1060 // (vl + vlInc*frameCount)/65536.0f, frameCount); 1061 1062 do { 1063 l = (int32_t)*in++; 1064 r = (int32_t)*in++; 1065 *out++ += (vl >> 16) * l; 1066 *out++ += (vr >> 16) * r; 1067 *aux++ += (va >> 17) * (l + r); 1068 vl += vlInc; 1069 vr += vrInc; 1070 va += vaInc; 1071 } while (--frameCount); 1072 1073 t->prevVolume[0] = vl; 1074 t->prevVolume[1] = vr; 1075 t->prevAuxLevel = va; 1076 t->adjustVolumeRamp(true); 1077 } 1078 1079 // constant gain 1080 else { 1081 const uint32_t vrl = t->volumeRL; 1082 const int16_t va = (int16_t)t->auxLevel; 1083 do { 1084 uint32_t rl = *reinterpret_cast<const uint32_t *>(in); 1085 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1); 1086 in += 2; 1087 out[0] = mulAddRL(1, rl, vrl, out[0]); 1088 out[1] = mulAddRL(0, rl, vrl, out[1]); 1089 out += 2; 1090 aux[0] = mulAdd(a, va, aux[0]); 1091 aux++; 1092 } while (--frameCount); 1093 } 1094 } else { 1095 // ramp gain 1096 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) { 1097 int32_t vl = t->prevVolume[0]; 1098 int32_t vr = t->prevVolume[1]; 1099 const int32_t vlInc = t->volumeInc[0]; 1100 const int32_t vrInc = t->volumeInc[1]; 1101 1102 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d", 1103 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0], 1104 // (vl + vlInc*frameCount)/65536.0f, frameCount); 1105 1106 do { 1107 *out++ += (vl >> 16) * (int32_t) *in++; 1108 *out++ += (vr >> 16) * (int32_t) *in++; 1109 vl += vlInc; 1110 vr += vrInc; 1111 } while (--frameCount); 1112 1113 t->prevVolume[0] = vl; 1114 t->prevVolume[1] = vr; 1115 t->adjustVolumeRamp(false); 1116 } 1117 1118 // constant gain 1119 else { 1120 const uint32_t vrl = t->volumeRL; 1121 do { 1122 uint32_t rl = *reinterpret_cast<const uint32_t *>(in); 1123 in += 2; 1124 out[0] = mulAddRL(1, rl, vrl, out[0]); 1125 out[1] = mulAddRL(0, rl, vrl, out[1]); 1126 out += 2; 1127 } while (--frameCount); 1128 } 1129 } 1130 t->in = in; 1131} 1132 1133void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, 1134 int32_t* temp __unused, int32_t* aux) 1135{ 1136 const int16_t *in = static_cast<int16_t const *>(t->in); 1137 1138 if (CC_UNLIKELY(aux != NULL)) { 1139 // ramp gain 1140 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) { 1141 int32_t vl = t->prevVolume[0]; 1142 int32_t vr = t->prevVolume[1]; 1143 int32_t va = t->prevAuxLevel; 1144 const int32_t vlInc = t->volumeInc[0]; 1145 const int32_t vrInc = t->volumeInc[1]; 1146 const int32_t vaInc = t->auxInc; 1147 1148 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d", 1149 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0], 1150 // (vl + vlInc*frameCount)/65536.0f, frameCount); 1151 1152 do { 1153 int32_t l = *in++; 1154 *out++ += (vl >> 16) * l; 1155 *out++ += (vr >> 16) * l; 1156 *aux++ += (va >> 16) * l; 1157 vl += vlInc; 1158 vr += vrInc; 1159 va += vaInc; 1160 } while (--frameCount); 1161 1162 t->prevVolume[0] = vl; 1163 t->prevVolume[1] = vr; 1164 t->prevAuxLevel = va; 1165 t->adjustVolumeRamp(true); 1166 } 1167 // constant gain 1168 else { 1169 const int16_t vl = t->volume[0]; 1170 const int16_t vr = t->volume[1]; 1171 const int16_t va = (int16_t)t->auxLevel; 1172 do { 1173 int16_t l = *in++; 1174 out[0] = mulAdd(l, vl, out[0]); 1175 out[1] = mulAdd(l, vr, out[1]); 1176 out += 2; 1177 aux[0] = mulAdd(l, va, aux[0]); 1178 aux++; 1179 } while (--frameCount); 1180 } 1181 } else { 1182 // ramp gain 1183 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) { 1184 int32_t vl = t->prevVolume[0]; 1185 int32_t vr = t->prevVolume[1]; 1186 const int32_t vlInc = t->volumeInc[0]; 1187 const int32_t vrInc = t->volumeInc[1]; 1188 1189 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d", 1190 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0], 1191 // (vl + vlInc*frameCount)/65536.0f, frameCount); 1192 1193 do { 1194 int32_t l = *in++; 1195 *out++ += (vl >> 16) * l; 1196 *out++ += (vr >> 16) * l; 1197 vl += vlInc; 1198 vr += vrInc; 1199 } while (--frameCount); 1200 1201 t->prevVolume[0] = vl; 1202 t->prevVolume[1] = vr; 1203 t->adjustVolumeRamp(false); 1204 } 1205 // constant gain 1206 else { 1207 const int16_t vl = t->volume[0]; 1208 const int16_t vr = t->volume[1]; 1209 do { 1210 int16_t l = *in++; 1211 out[0] = mulAdd(l, vl, out[0]); 1212 out[1] = mulAdd(l, vr, out[1]); 1213 out += 2; 1214 } while (--frameCount); 1215 } 1216 } 1217 t->in = in; 1218} 1219 1220// no-op case 1221void AudioMixer::process__nop(state_t* state, int64_t pts) 1222{ 1223 uint32_t e0 = state->enabledTracks; 1224 size_t sampleCount = state->frameCount * MAX_NUM_CHANNELS; 1225 while (e0) { 1226 // process by group of tracks with same output buffer to 1227 // avoid multiple memset() on same buffer 1228 uint32_t e1 = e0, e2 = e0; 1229 int i = 31 - __builtin_clz(e1); 1230 { 1231 track_t& t1 = state->tracks[i]; 1232 e2 &= ~(1<<i); 1233 while (e2) { 1234 i = 31 - __builtin_clz(e2); 1235 e2 &= ~(1<<i); 1236 track_t& t2 = state->tracks[i]; 1237 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) { 1238 e1 &= ~(1<<i); 1239 } 1240 } 1241 e0 &= ~(e1); 1242 1243 memset(t1.mainBuffer, 0, sampleCount 1244 * audio_bytes_per_sample(t1.mMixerFormat)); 1245 } 1246 1247 while (e1) { 1248 i = 31 - __builtin_clz(e1); 1249 e1 &= ~(1<<i); 1250 { 1251 track_t& t3 = state->tracks[i]; 1252 size_t outFrames = state->frameCount; 1253 while (outFrames) { 1254 t3.buffer.frameCount = outFrames; 1255 int64_t outputPTS = calculateOutputPTS( 1256 t3, pts, state->frameCount - outFrames); 1257 t3.bufferProvider->getNextBuffer(&t3.buffer, outputPTS); 1258 if (t3.buffer.raw == NULL) break; 1259 outFrames -= t3.buffer.frameCount; 1260 t3.bufferProvider->releaseBuffer(&t3.buffer); 1261 } 1262 } 1263 } 1264 } 1265} 1266 1267// generic code without resampling 1268void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts) 1269{ 1270 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32))); 1271 1272 // acquire each track's buffer 1273 uint32_t enabledTracks = state->enabledTracks; 1274 uint32_t e0 = enabledTracks; 1275 while (e0) { 1276 const int i = 31 - __builtin_clz(e0); 1277 e0 &= ~(1<<i); 1278 track_t& t = state->tracks[i]; 1279 t.buffer.frameCount = state->frameCount; 1280 t.bufferProvider->getNextBuffer(&t.buffer, pts); 1281 t.frameCount = t.buffer.frameCount; 1282 t.in = t.buffer.raw; 1283 } 1284 1285 e0 = enabledTracks; 1286 while (e0) { 1287 // process by group of tracks with same output buffer to 1288 // optimize cache use 1289 uint32_t e1 = e0, e2 = e0; 1290 int j = 31 - __builtin_clz(e1); 1291 track_t& t1 = state->tracks[j]; 1292 e2 &= ~(1<<j); 1293 while (e2) { 1294 j = 31 - __builtin_clz(e2); 1295 e2 &= ~(1<<j); 1296 track_t& t2 = state->tracks[j]; 1297 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) { 1298 e1 &= ~(1<<j); 1299 } 1300 } 1301 e0 &= ~(e1); 1302 // this assumes output 16 bits stereo, no resampling 1303 int32_t *out = t1.mainBuffer; 1304 size_t numFrames = 0; 1305 do { 1306 memset(outTemp, 0, sizeof(outTemp)); 1307 e2 = e1; 1308 while (e2) { 1309 const int i = 31 - __builtin_clz(e2); 1310 e2 &= ~(1<<i); 1311 track_t& t = state->tracks[i]; 1312 size_t outFrames = BLOCKSIZE; 1313 int32_t *aux = NULL; 1314 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) { 1315 aux = t.auxBuffer + numFrames; 1316 } 1317 while (outFrames) { 1318 // t.in == NULL can happen if the track was flushed just after having 1319 // been enabled for mixing. 1320 if (t.in == NULL) { 1321 enabledTracks &= ~(1<<i); 1322 e1 &= ~(1<<i); 1323 break; 1324 } 1325 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount; 1326 if (inFrames > 0) { 1327 t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, 1328 state->resampleTemp, aux); 1329 t.frameCount -= inFrames; 1330 outFrames -= inFrames; 1331 if (CC_UNLIKELY(aux != NULL)) { 1332 aux += inFrames; 1333 } 1334 } 1335 if (t.frameCount == 0 && outFrames) { 1336 t.bufferProvider->releaseBuffer(&t.buffer); 1337 t.buffer.frameCount = (state->frameCount - numFrames) - 1338 (BLOCKSIZE - outFrames); 1339 int64_t outputPTS = calculateOutputPTS( 1340 t, pts, numFrames + (BLOCKSIZE - outFrames)); 1341 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS); 1342 t.in = t.buffer.raw; 1343 if (t.in == NULL) { 1344 enabledTracks &= ~(1<<i); 1345 e1 &= ~(1<<i); 1346 break; 1347 } 1348 t.frameCount = t.buffer.frameCount; 1349 } 1350 } 1351 } 1352 switch (t1.mMixerFormat) { 1353 case AUDIO_FORMAT_PCM_FLOAT: 1354 memcpy_to_float_from_q4_27(reinterpret_cast<float *>(out), outTemp, BLOCKSIZE * 2); 1355 out += BLOCKSIZE * 2; // output is 2 floats/frame. 1356 break; 1357 case AUDIO_FORMAT_PCM_16_BIT: 1358 ditherAndClamp(out, outTemp, BLOCKSIZE); 1359 out += BLOCKSIZE; // output is 1 int32_t (2 int16_t samples)/frame 1360 break; 1361 default: 1362 LOG_ALWAYS_FATAL("bad mixer format: %d", t1.mMixerFormat); 1363 } 1364 numFrames += BLOCKSIZE; 1365 } while (numFrames < state->frameCount); 1366 } 1367 1368 // release each track's buffer 1369 e0 = enabledTracks; 1370 while (e0) { 1371 const int i = 31 - __builtin_clz(e0); 1372 e0 &= ~(1<<i); 1373 track_t& t = state->tracks[i]; 1374 t.bufferProvider->releaseBuffer(&t.buffer); 1375 } 1376} 1377 1378 1379// generic code with resampling 1380void AudioMixer::process__genericResampling(state_t* state, int64_t pts) 1381{ 1382 // this const just means that local variable outTemp doesn't change 1383 int32_t* const outTemp = state->outputTemp; 1384 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount; 1385 1386 size_t numFrames = state->frameCount; 1387 1388 uint32_t e0 = state->enabledTracks; 1389 while (e0) { 1390 // process by group of tracks with same output buffer 1391 // to optimize cache use 1392 uint32_t e1 = e0, e2 = e0; 1393 int j = 31 - __builtin_clz(e1); 1394 track_t& t1 = state->tracks[j]; 1395 e2 &= ~(1<<j); 1396 while (e2) { 1397 j = 31 - __builtin_clz(e2); 1398 e2 &= ~(1<<j); 1399 track_t& t2 = state->tracks[j]; 1400 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) { 1401 e1 &= ~(1<<j); 1402 } 1403 } 1404 e0 &= ~(e1); 1405 int32_t *out = t1.mainBuffer; 1406 memset(outTemp, 0, size); 1407 while (e1) { 1408 const int i = 31 - __builtin_clz(e1); 1409 e1 &= ~(1<<i); 1410 track_t& t = state->tracks[i]; 1411 int32_t *aux = NULL; 1412 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) { 1413 aux = t.auxBuffer; 1414 } 1415 1416 // this is a little goofy, on the resampling case we don't 1417 // acquire/release the buffers because it's done by 1418 // the resampler. 1419 if (t.needs & NEEDS_RESAMPLE) { 1420 t.resampler->setPTS(pts); 1421 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux); 1422 } else { 1423 1424 size_t outFrames = 0; 1425 1426 while (outFrames < numFrames) { 1427 t.buffer.frameCount = numFrames - outFrames; 1428 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames); 1429 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS); 1430 t.in = t.buffer.raw; 1431 // t.in == NULL can happen if the track was flushed just after having 1432 // been enabled for mixing. 1433 if (t.in == NULL) break; 1434 1435 if (CC_UNLIKELY(aux != NULL)) { 1436 aux += outFrames; 1437 } 1438 t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, 1439 state->resampleTemp, aux); 1440 outFrames += t.buffer.frameCount; 1441 t.bufferProvider->releaseBuffer(&t.buffer); 1442 } 1443 } 1444 } 1445 switch (t1.mMixerFormat) { 1446 case AUDIO_FORMAT_PCM_FLOAT: 1447 memcpy_to_float_from_q4_27(reinterpret_cast<float*>(out), outTemp, numFrames*2); 1448 break; 1449 case AUDIO_FORMAT_PCM_16_BIT: 1450 ditherAndClamp(out, outTemp, numFrames); 1451 break; 1452 default: 1453 LOG_ALWAYS_FATAL("bad mixer format: %d", t1.mMixerFormat); 1454 } 1455 } 1456} 1457 1458// one track, 16 bits stereo without resampling is the most common case 1459void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state, 1460 int64_t pts) 1461{ 1462 // This method is only called when state->enabledTracks has exactly 1463 // one bit set. The asserts below would verify this, but are commented out 1464 // since the whole point of this method is to optimize performance. 1465 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled"); 1466 const int i = 31 - __builtin_clz(state->enabledTracks); 1467 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled"); 1468 const track_t& t = state->tracks[i]; 1469 1470 AudioBufferProvider::Buffer& b(t.buffer); 1471 1472 int32_t* out = t.mainBuffer; 1473 float *fout = reinterpret_cast<float*>(out); 1474 size_t numFrames = state->frameCount; 1475 1476 const int16_t vl = t.volume[0]; 1477 const int16_t vr = t.volume[1]; 1478 const uint32_t vrl = t.volumeRL; 1479 while (numFrames) { 1480 b.frameCount = numFrames; 1481 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer); 1482 t.bufferProvider->getNextBuffer(&b, outputPTS); 1483 const int16_t *in = b.i16; 1484 1485 // in == NULL can happen if the track was flushed just after having 1486 // been enabled for mixing. 1487 if (in == NULL || (((uintptr_t)in) & 3)) { 1488 memset(out, 0, numFrames 1489 * MAX_NUM_CHANNELS * audio_bytes_per_sample(t.mMixerFormat)); 1490 ALOGE_IF((((uintptr_t)in) & 3), "process stereo track: input buffer alignment pb: " 1491 "buffer %p track %d, channels %d, needs %08x", 1492 in, i, t.channelCount, t.needs); 1493 return; 1494 } 1495 size_t outFrames = b.frameCount; 1496 1497 switch (t.mMixerFormat) { 1498 case AUDIO_FORMAT_PCM_FLOAT: 1499 do { 1500 uint32_t rl = *reinterpret_cast<const uint32_t *>(in); 1501 in += 2; 1502 int32_t l = mulRL(1, rl, vrl); 1503 int32_t r = mulRL(0, rl, vrl); 1504 *fout++ = float_from_q4_27(l); 1505 *fout++ = float_from_q4_27(r); 1506 // Note: In case of later int16_t sink output, 1507 // conversion and clamping is done by memcpy_to_i16_from_float(). 1508 } while (--outFrames); 1509 break; 1510 case AUDIO_FORMAT_PCM_16_BIT: 1511 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) { 1512 // volume is boosted, so we might need to clamp even though 1513 // we process only one track. 1514 do { 1515 uint32_t rl = *reinterpret_cast<const uint32_t *>(in); 1516 in += 2; 1517 int32_t l = mulRL(1, rl, vrl) >> 12; 1518 int32_t r = mulRL(0, rl, vrl) >> 12; 1519 // clamping... 1520 l = clamp16(l); 1521 r = clamp16(r); 1522 *out++ = (r<<16) | (l & 0xFFFF); 1523 } while (--outFrames); 1524 } else { 1525 do { 1526 uint32_t rl = *reinterpret_cast<const uint32_t *>(in); 1527 in += 2; 1528 int32_t l = mulRL(1, rl, vrl) >> 12; 1529 int32_t r = mulRL(0, rl, vrl) >> 12; 1530 *out++ = (r<<16) | (l & 0xFFFF); 1531 } while (--outFrames); 1532 } 1533 break; 1534 default: 1535 LOG_ALWAYS_FATAL("bad mixer format: %d", t.mMixerFormat); 1536 } 1537 numFrames -= b.frameCount; 1538 t.bufferProvider->releaseBuffer(&b); 1539 } 1540} 1541 1542#if 0 1543// 2 tracks is also a common case 1544// NEVER used in current implementation of process__validate() 1545// only use if the 2 tracks have the same output buffer 1546void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state, 1547 int64_t pts) 1548{ 1549 int i; 1550 uint32_t en = state->enabledTracks; 1551 1552 i = 31 - __builtin_clz(en); 1553 const track_t& t0 = state->tracks[i]; 1554 AudioBufferProvider::Buffer& b0(t0.buffer); 1555 1556 en &= ~(1<<i); 1557 i = 31 - __builtin_clz(en); 1558 const track_t& t1 = state->tracks[i]; 1559 AudioBufferProvider::Buffer& b1(t1.buffer); 1560 1561 const int16_t *in0; 1562 const int16_t vl0 = t0.volume[0]; 1563 const int16_t vr0 = t0.volume[1]; 1564 size_t frameCount0 = 0; 1565 1566 const int16_t *in1; 1567 const int16_t vl1 = t1.volume[0]; 1568 const int16_t vr1 = t1.volume[1]; 1569 size_t frameCount1 = 0; 1570 1571 //FIXME: only works if two tracks use same buffer 1572 int32_t* out = t0.mainBuffer; 1573 size_t numFrames = state->frameCount; 1574 const int16_t *buff = NULL; 1575 1576 1577 while (numFrames) { 1578 1579 if (frameCount0 == 0) { 1580 b0.frameCount = numFrames; 1581 int64_t outputPTS = calculateOutputPTS(t0, pts, 1582 out - t0.mainBuffer); 1583 t0.bufferProvider->getNextBuffer(&b0, outputPTS); 1584 if (b0.i16 == NULL) { 1585 if (buff == NULL) { 1586 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount]; 1587 } 1588 in0 = buff; 1589 b0.frameCount = numFrames; 1590 } else { 1591 in0 = b0.i16; 1592 } 1593 frameCount0 = b0.frameCount; 1594 } 1595 if (frameCount1 == 0) { 1596 b1.frameCount = numFrames; 1597 int64_t outputPTS = calculateOutputPTS(t1, pts, 1598 out - t0.mainBuffer); 1599 t1.bufferProvider->getNextBuffer(&b1, outputPTS); 1600 if (b1.i16 == NULL) { 1601 if (buff == NULL) { 1602 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount]; 1603 } 1604 in1 = buff; 1605 b1.frameCount = numFrames; 1606 } else { 1607 in1 = b1.i16; 1608 } 1609 frameCount1 = b1.frameCount; 1610 } 1611 1612 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1; 1613 1614 numFrames -= outFrames; 1615 frameCount0 -= outFrames; 1616 frameCount1 -= outFrames; 1617 1618 do { 1619 int32_t l0 = *in0++; 1620 int32_t r0 = *in0++; 1621 l0 = mul(l0, vl0); 1622 r0 = mul(r0, vr0); 1623 int32_t l = *in1++; 1624 int32_t r = *in1++; 1625 l = mulAdd(l, vl1, l0) >> 12; 1626 r = mulAdd(r, vr1, r0) >> 12; 1627 // clamping... 1628 l = clamp16(l); 1629 r = clamp16(r); 1630 *out++ = (r<<16) | (l & 0xFFFF); 1631 } while (--outFrames); 1632 1633 if (frameCount0 == 0) { 1634 t0.bufferProvider->releaseBuffer(&b0); 1635 } 1636 if (frameCount1 == 0) { 1637 t1.bufferProvider->releaseBuffer(&b1); 1638 } 1639 } 1640 1641 delete [] buff; 1642} 1643#endif 1644 1645int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS, 1646 int outputFrameIndex) 1647{ 1648 if (AudioBufferProvider::kInvalidPTS == basePTS) { 1649 return AudioBufferProvider::kInvalidPTS; 1650 } 1651 1652 return basePTS + ((outputFrameIndex * sLocalTimeFreq) / t.sampleRate); 1653} 1654 1655/*static*/ uint64_t AudioMixer::sLocalTimeFreq; 1656/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT; 1657 1658/*static*/ void AudioMixer::sInitRoutine() 1659{ 1660 LocalClock lc; 1661 sLocalTimeFreq = lc.getLocalFreq(); 1662 1663 // find multichannel downmix effect if we have to play multichannel content 1664 uint32_t numEffects = 0; 1665 int ret = EffectQueryNumberEffects(&numEffects); 1666 if (ret != 0) { 1667 ALOGE("AudioMixer() error %d querying number of effects", ret); 1668 return; 1669 } 1670 ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects); 1671 1672 for (uint32_t i = 0 ; i < numEffects ; i++) { 1673 if (EffectQueryEffect(i, &sDwnmFxDesc) == 0) { 1674 ALOGV("effect %d is called %s", i, sDwnmFxDesc.name); 1675 if (memcmp(&sDwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) { 1676 ALOGI("found effect \"%s\" from %s", 1677 sDwnmFxDesc.name, sDwnmFxDesc.implementor); 1678 sIsMultichannelCapable = true; 1679 break; 1680 } 1681 } 1682 } 1683 ALOGW_IF(!sIsMultichannelCapable, "unable to find downmix effect"); 1684} 1685 1686// ---------------------------------------------------------------------------- 1687}; // namespace android 1688