blob: dddca02dfacf9f2ac3affb5901ac69733c0da9b6 [file] [log] [blame]
Glenn Kasten99e53b82012-01-19 08:59:58 -08001/*
Mathias Agopian65ab4712010-07-14 17:59:35 -07002**
3** Copyright 2007, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "AudioMixer"
Glenn Kasten7f5d3352013-02-15 23:55:04 +000019//#define LOG_NDEBUG 0
Mathias Agopian65ab4712010-07-14 17:59:35 -070020
Glenn Kasten153b9fe2013-07-15 11:23:36 -070021#include "Configuration.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070022#include <stdint.h>
23#include <string.h>
24#include <stdlib.h>
Andy Hung5e58b0a2014-06-23 19:07:29 -070025#include <math.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070026#include <sys/types.h>
27
28#include <utils/Errors.h>
29#include <utils/Log.h>
30
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070031#include <cutils/bitops.h>
Glenn Kastenf6b16782011-12-15 09:51:17 -080032#include <cutils/compiler.h>
Glenn Kasten5798d4e2012-03-08 12:18:35 -080033#include <utils/Debug.h>
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070034
35#include <system/audio.h>
36
Glenn Kasten3b21c502011-12-15 09:52:39 -080037#include <audio_utils/primitives.h>
Andy Hungef7c7fb2014-05-12 16:51:41 -070038#include <audio_utils/format.h>
John Grossman4ff14ba2012-02-08 16:37:41 -080039#include <common_time/local_clock.h>
40#include <common_time/cc_helper.h>
Glenn Kasten3b21c502011-12-15 09:52:39 -080041
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070042#include <media/EffectsFactoryApi.h>
Andy Hung9a592762014-07-21 21:56:01 -070043#include <audio_effects/effect_downmix.h>
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070044
Andy Hung296b7412014-06-17 15:25:47 -070045#include "AudioMixerOps.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070046#include "AudioMixer.h"
47
Andy Hunge93b6b72014-07-17 21:30:53 -070048// The FCC_2 macro refers to the Fixed Channel Count of 2 for the legacy integer mixer.
Andy Hung296b7412014-06-17 15:25:47 -070049#ifndef FCC_2
50#define FCC_2 2
51#endif
52
Andy Hunge93b6b72014-07-17 21:30:53 -070053// Look for MONO_HACK for any Mono hack involving legacy mono channel to
54// stereo channel conversion.
55
Andy Hung296b7412014-06-17 15:25:47 -070056/* VERY_VERY_VERBOSE_LOGGING will show exactly which process hook and track hook is
57 * being used. This is a considerable amount of log spam, so don't enable unless you
58 * are verifying the hook based code.
59 */
60//#define VERY_VERY_VERBOSE_LOGGING
61#ifdef VERY_VERY_VERBOSE_LOGGING
62#define ALOGVV ALOGV
63//define ALOGVV printf // for test-mixer.cpp
64#else
65#define ALOGVV(a...) do { } while (0)
66#endif
67
Andy Hunga08810b2014-07-16 21:53:43 -070068#ifndef ARRAY_SIZE
69#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
70#endif
71
Andy Hung5b8fde72014-09-02 21:14:34 -070072// Set kUseNewMixer to true to use the new mixer engine always. Otherwise the
73// original code will be used for stereo sinks, the new mixer for multichannel.
74static const bool kUseNewMixer = true;
Andy Hung296b7412014-06-17 15:25:47 -070075
76// Set kUseFloat to true to allow floating input into the mixer engine.
77// If kUseNewMixer is false, this is ignored or may be overridden internally
78// because of downmix/upmix support.
79static const bool kUseFloat = true;
80
Andy Hung1b2fdcb2014-07-16 17:44:34 -070081// Set to default copy buffer size in frames for input processing.
82static const size_t kCopyBufferFrameCount = 256;
83
Mathias Agopian65ab4712010-07-14 17:59:35 -070084namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070085
86// ----------------------------------------------------------------------------
Andy Hung1b2fdcb2014-07-16 17:44:34 -070087
88template <typename T>
89T min(const T& a, const T& b)
90{
91 return a < b ? a : b;
92}
93
94AudioMixer::CopyBufferProvider::CopyBufferProvider(size_t inputFrameSize,
95 size_t outputFrameSize, size_t bufferFrameCount) :
96 mInputFrameSize(inputFrameSize),
97 mOutputFrameSize(outputFrameSize),
98 mLocalBufferFrameCount(bufferFrameCount),
99 mLocalBufferData(NULL),
100 mConsumed(0)
101{
102 ALOGV("CopyBufferProvider(%p)(%zu, %zu, %zu)", this,
103 inputFrameSize, outputFrameSize, bufferFrameCount);
104 LOG_ALWAYS_FATAL_IF(inputFrameSize < outputFrameSize && bufferFrameCount == 0,
Andy Hunge93b6b72014-07-17 21:30:53 -0700105 "Requires local buffer if inputFrameSize(%zu) < outputFrameSize(%zu)",
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700106 inputFrameSize, outputFrameSize);
107 if (mLocalBufferFrameCount) {
108 (void)posix_memalign(&mLocalBufferData, 32, mLocalBufferFrameCount * mOutputFrameSize);
109 }
110 mBuffer.frameCount = 0;
111}
112
113AudioMixer::CopyBufferProvider::~CopyBufferProvider()
114{
115 ALOGV("~CopyBufferProvider(%p)", this);
116 if (mBuffer.frameCount != 0) {
117 mTrackBufferProvider->releaseBuffer(&mBuffer);
118 }
119 free(mLocalBufferData);
120}
121
122status_t AudioMixer::CopyBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer,
123 int64_t pts)
124{
125 //ALOGV("CopyBufferProvider(%p)::getNextBuffer(%p (%zu), %lld)",
126 // this, pBuffer, pBuffer->frameCount, pts);
127 if (mLocalBufferFrameCount == 0) {
128 status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts);
129 if (res == OK) {
130 copyFrames(pBuffer->raw, pBuffer->raw, pBuffer->frameCount);
131 }
132 return res;
133 }
134 if (mBuffer.frameCount == 0) {
135 mBuffer.frameCount = pBuffer->frameCount;
136 status_t res = mTrackBufferProvider->getNextBuffer(&mBuffer, pts);
137 // At one time an upstream buffer provider had
138 // res == OK and mBuffer.frameCount == 0, doesn't seem to happen now 7/18/2014.
139 //
140 // By API spec, if res != OK, then mBuffer.frameCount == 0.
141 // but there may be improper implementations.
142 ALOG_ASSERT(res == OK || mBuffer.frameCount == 0);
143 if (res != OK || mBuffer.frameCount == 0) { // not needed by API spec, but to be safe.
144 pBuffer->raw = NULL;
145 pBuffer->frameCount = 0;
146 return res;
147 }
148 mConsumed = 0;
149 }
150 ALOG_ASSERT(mConsumed < mBuffer.frameCount);
151 size_t count = min(mLocalBufferFrameCount, mBuffer.frameCount - mConsumed);
152 count = min(count, pBuffer->frameCount);
153 pBuffer->raw = mLocalBufferData;
154 pBuffer->frameCount = count;
155 copyFrames(pBuffer->raw, (uint8_t*)mBuffer.raw + mConsumed * mInputFrameSize,
156 pBuffer->frameCount);
157 return OK;
158}
159
160void AudioMixer::CopyBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer)
161{
162 //ALOGV("CopyBufferProvider(%p)::releaseBuffer(%p(%zu))",
163 // this, pBuffer, pBuffer->frameCount);
164 if (mLocalBufferFrameCount == 0) {
165 mTrackBufferProvider->releaseBuffer(pBuffer);
166 return;
167 }
168 // LOG_ALWAYS_FATAL_IF(pBuffer->frameCount == 0, "Invalid framecount");
169 mConsumed += pBuffer->frameCount; // TODO: update for efficiency to reuse existing content
170 if (mConsumed != 0 && mConsumed >= mBuffer.frameCount) {
171 mTrackBufferProvider->releaseBuffer(&mBuffer);
172 ALOG_ASSERT(mBuffer.frameCount == 0);
173 }
174 pBuffer->raw = NULL;
175 pBuffer->frameCount = 0;
176}
177
178void AudioMixer::CopyBufferProvider::reset()
179{
180 if (mBuffer.frameCount != 0) {
181 mTrackBufferProvider->releaseBuffer(&mBuffer);
182 }
183 mConsumed = 0;
184}
185
Andy Hung34803d52014-07-16 21:41:35 -0700186AudioMixer::DownmixerBufferProvider::DownmixerBufferProvider(
187 audio_channel_mask_t inputChannelMask,
188 audio_channel_mask_t outputChannelMask, audio_format_t format,
189 uint32_t sampleRate, int32_t sessionId, size_t bufferFrameCount) :
190 CopyBufferProvider(
191 audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(inputChannelMask),
192 audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(outputChannelMask),
193 bufferFrameCount) // set bufferFrameCount to 0 to do in-place
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700194{
Andy Hung34803d52014-07-16 21:41:35 -0700195 ALOGV("DownmixerBufferProvider(%p)(%#x, %#x, %#x %u %d)",
196 this, inputChannelMask, outputChannelMask, format,
197 sampleRate, sessionId);
198 if (!sIsMultichannelCapable
199 || EffectCreate(&sDwnmFxDesc.uuid,
200 sessionId,
201 SESSION_ID_INVALID_AND_IGNORED,
202 &mDownmixHandle) != 0) {
203 ALOGE("DownmixerBufferProvider() error creating downmixer effect");
204 mDownmixHandle = NULL;
205 return;
206 }
207 // channel input configuration will be overridden per-track
208 mDownmixConfig.inputCfg.channels = inputChannelMask; // FIXME: Should be bits
209 mDownmixConfig.outputCfg.channels = outputChannelMask; // FIXME: should be bits
210 mDownmixConfig.inputCfg.format = format;
211 mDownmixConfig.outputCfg.format = format;
212 mDownmixConfig.inputCfg.samplingRate = sampleRate;
213 mDownmixConfig.outputCfg.samplingRate = sampleRate;
214 mDownmixConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
215 mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
216 // input and output buffer provider, and frame count will not be used as the downmix effect
217 // process() function is called directly (see DownmixerBufferProvider::getNextBuffer())
218 mDownmixConfig.inputCfg.mask = EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS |
219 EFFECT_CONFIG_FORMAT | EFFECT_CONFIG_ACC_MODE;
220 mDownmixConfig.outputCfg.mask = mDownmixConfig.inputCfg.mask;
221
222 int cmdStatus;
223 uint32_t replySize = sizeof(int);
224
225 // Configure downmixer
226 status_t status = (*mDownmixHandle)->command(mDownmixHandle,
227 EFFECT_CMD_SET_CONFIG /*cmdCode*/, sizeof(effect_config_t) /*cmdSize*/,
228 &mDownmixConfig /*pCmdData*/,
229 &replySize, &cmdStatus /*pReplyData*/);
230 if (status != 0 || cmdStatus != 0) {
231 ALOGE("DownmixerBufferProvider() error %d cmdStatus %d while configuring downmixer",
232 status, cmdStatus);
233 EffectRelease(mDownmixHandle);
234 mDownmixHandle = NULL;
235 return;
236 }
237
238 // Enable downmixer
239 replySize = sizeof(int);
240 status = (*mDownmixHandle)->command(mDownmixHandle,
241 EFFECT_CMD_ENABLE /*cmdCode*/, 0 /*cmdSize*/, NULL /*pCmdData*/,
242 &replySize, &cmdStatus /*pReplyData*/);
243 if (status != 0 || cmdStatus != 0) {
244 ALOGE("DownmixerBufferProvider() error %d cmdStatus %d while enabling downmixer",
245 status, cmdStatus);
246 EffectRelease(mDownmixHandle);
247 mDownmixHandle = NULL;
248 return;
249 }
250
251 // Set downmix type
252 // parameter size rounded for padding on 32bit boundary
253 const int psizePadded = ((sizeof(downmix_params_t) - 1)/sizeof(int) + 1) * sizeof(int);
254 const int downmixParamSize =
255 sizeof(effect_param_t) + psizePadded + sizeof(downmix_type_t);
256 effect_param_t * const param = (effect_param_t *) malloc(downmixParamSize);
257 param->psize = sizeof(downmix_params_t);
258 const downmix_params_t downmixParam = DOWNMIX_PARAM_TYPE;
259 memcpy(param->data, &downmixParam, param->psize);
260 const downmix_type_t downmixType = DOWNMIX_TYPE_FOLD;
261 param->vsize = sizeof(downmix_type_t);
262 memcpy(param->data + psizePadded, &downmixType, param->vsize);
263 replySize = sizeof(int);
264 status = (*mDownmixHandle)->command(mDownmixHandle,
265 EFFECT_CMD_SET_PARAM /* cmdCode */, downmixParamSize /* cmdSize */,
266 param /*pCmdData*/, &replySize, &cmdStatus /*pReplyData*/);
267 free(param);
268 if (status != 0 || cmdStatus != 0) {
269 ALOGE("DownmixerBufferProvider() error %d cmdStatus %d while setting downmix type",
270 status, cmdStatus);
271 EffectRelease(mDownmixHandle);
272 mDownmixHandle = NULL;
273 return;
274 }
275 ALOGV("DownmixerBufferProvider() downmix type set to %d", (int) downmixType);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700276}
277
278AudioMixer::DownmixerBufferProvider::~DownmixerBufferProvider()
279{
Andy Hung34803d52014-07-16 21:41:35 -0700280 ALOGV("~DownmixerBufferProvider (%p)", this);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700281 EffectRelease(mDownmixHandle);
Andy Hung34803d52014-07-16 21:41:35 -0700282 mDownmixHandle = NULL;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700283}
284
Andy Hung34803d52014-07-16 21:41:35 -0700285void AudioMixer::DownmixerBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
286{
287 mDownmixConfig.inputCfg.buffer.frameCount = frames;
288 mDownmixConfig.inputCfg.buffer.raw = const_cast<void *>(src);
289 mDownmixConfig.outputCfg.buffer.frameCount = frames;
290 mDownmixConfig.outputCfg.buffer.raw = dst;
291 // may be in-place if src == dst.
292 status_t res = (*mDownmixHandle)->process(mDownmixHandle,
293 &mDownmixConfig.inputCfg.buffer, &mDownmixConfig.outputCfg.buffer);
294 ALOGE_IF(res != OK, "DownmixBufferProvider error %d", res);
295}
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700296
Andy Hung34803d52014-07-16 21:41:35 -0700297/* call once in a pthread_once handler. */
298/*static*/ status_t AudioMixer::DownmixerBufferProvider::init()
299{
300 // find multichannel downmix effect if we have to play multichannel content
301 uint32_t numEffects = 0;
302 int ret = EffectQueryNumberEffects(&numEffects);
303 if (ret != 0) {
304 ALOGE("AudioMixer() error %d querying number of effects", ret);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700305 return NO_INIT;
306 }
Andy Hung34803d52014-07-16 21:41:35 -0700307 ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects);
308
309 for (uint32_t i = 0 ; i < numEffects ; i++) {
310 if (EffectQueryEffect(i, &sDwnmFxDesc) == 0) {
311 ALOGV("effect %d is called %s", i, sDwnmFxDesc.name);
312 if (memcmp(&sDwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) {
313 ALOGI("found effect \"%s\" from %s",
314 sDwnmFxDesc.name, sDwnmFxDesc.implementor);
315 sIsMultichannelCapable = true;
316 break;
317 }
318 }
319 }
320 ALOGW_IF(!sIsMultichannelCapable, "unable to find downmix effect");
321 return NO_INIT;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700322}
323
Andy Hung34803d52014-07-16 21:41:35 -0700324/*static*/ bool AudioMixer::DownmixerBufferProvider::sIsMultichannelCapable = false;
325/*static*/ effect_descriptor_t AudioMixer::DownmixerBufferProvider::sDwnmFxDesc;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700326
Andy Hunga08810b2014-07-16 21:53:43 -0700327AudioMixer::RemixBufferProvider::RemixBufferProvider(audio_channel_mask_t inputChannelMask,
328 audio_channel_mask_t outputChannelMask, audio_format_t format,
329 size_t bufferFrameCount) :
330 CopyBufferProvider(
331 audio_bytes_per_sample(format)
332 * audio_channel_count_from_out_mask(inputChannelMask),
333 audio_bytes_per_sample(format)
334 * audio_channel_count_from_out_mask(outputChannelMask),
335 bufferFrameCount),
336 mFormat(format),
337 mSampleSize(audio_bytes_per_sample(format)),
338 mInputChannels(audio_channel_count_from_out_mask(inputChannelMask)),
339 mOutputChannels(audio_channel_count_from_out_mask(outputChannelMask))
340{
Andy Hunge93b6b72014-07-17 21:30:53 -0700341 ALOGV("RemixBufferProvider(%p)(%#x, %#x, %#x) %zu %zu",
Andy Hunga08810b2014-07-16 21:53:43 -0700342 this, format, inputChannelMask, outputChannelMask,
343 mInputChannels, mOutputChannels);
Andy Hung650ceb92015-01-29 13:31:12 -0800344
345 const audio_channel_representation_t inputRepresentation =
346 audio_channel_mask_get_representation(inputChannelMask);
347 const audio_channel_representation_t outputRepresentation =
348 audio_channel_mask_get_representation(outputChannelMask);
349 const uint32_t inputBits = audio_channel_mask_get_bits(inputChannelMask);
350 const uint32_t outputBits = audio_channel_mask_get_bits(outputChannelMask);
351
352 switch (inputRepresentation) {
353 case AUDIO_CHANNEL_REPRESENTATION_POSITION:
354 switch (outputRepresentation) {
355 case AUDIO_CHANNEL_REPRESENTATION_POSITION:
356 memcpy_by_index_array_initialization(mIdxAry, ARRAY_SIZE(mIdxAry),
357 outputBits, inputBits);
358 return;
359 case AUDIO_CHANNEL_REPRESENTATION_INDEX:
360 // TODO: output channel index mask not currently allowed
361 // fall through
362 default:
363 break;
364 }
365 break;
366 case AUDIO_CHANNEL_REPRESENTATION_INDEX:
367 switch (outputRepresentation) {
368 case AUDIO_CHANNEL_REPRESENTATION_POSITION:
369 memcpy_by_index_array_initialization_src_index(mIdxAry, ARRAY_SIZE(mIdxAry),
370 outputBits, inputBits);
371 return;
372 case AUDIO_CHANNEL_REPRESENTATION_INDEX:
373 // TODO: output channel index mask not currently allowed
374 // fall through
375 default:
376 break;
377 }
378 break;
379 default:
380 break;
381 }
382 LOG_ALWAYS_FATAL("invalid channel mask conversion from %#x to %#x",
383 inputChannelMask, outputChannelMask);
Andy Hunga08810b2014-07-16 21:53:43 -0700384}
385
386void AudioMixer::RemixBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
387{
388 memcpy_by_index_array(dst, mOutputChannels,
389 src, mInputChannels, mIdxAry, mSampleSize, frames);
390}
391
Andy Hungef7c7fb2014-05-12 16:51:41 -0700392AudioMixer::ReformatBufferProvider::ReformatBufferProvider(int32_t channels,
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700393 audio_format_t inputFormat, audio_format_t outputFormat,
394 size_t bufferFrameCount) :
395 CopyBufferProvider(
396 channels * audio_bytes_per_sample(inputFormat),
397 channels * audio_bytes_per_sample(outputFormat),
398 bufferFrameCount),
Andy Hungef7c7fb2014-05-12 16:51:41 -0700399 mChannels(channels),
400 mInputFormat(inputFormat),
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700401 mOutputFormat(outputFormat)
Andy Hungef7c7fb2014-05-12 16:51:41 -0700402{
403 ALOGV("ReformatBufferProvider(%p)(%d, %#x, %#x)", this, channels, inputFormat, outputFormat);
Andy Hungef7c7fb2014-05-12 16:51:41 -0700404}
405
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700406void AudioMixer::ReformatBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
Andy Hungef7c7fb2014-05-12 16:51:41 -0700407{
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700408 memcpy_by_audio_format(dst, mOutputFormat, src, mInputFormat, frames * mChannels);
Andy Hungef7c7fb2014-05-12 16:51:41 -0700409}
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700410
411// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -0700412
Paul Lind3c0a0e82012-08-01 18:49:49 -0700413// Ensure mConfiguredNames bitmask is initialized properly on all architectures.
414// The value of 1 << x is undefined in C when x >= 32.
415
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700416AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks)
Paul Lind3c0a0e82012-08-01 18:49:49 -0700417 : mTrackNames(0), mConfiguredNames((maxNumTracks >= 32 ? 0 : 1 << maxNumTracks) - 1),
Glenn Kasten7f5d3352013-02-15 23:55:04 +0000418 mSampleRate(sampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700419{
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700420 ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u",
421 maxNumTracks, MAX_NUM_TRACKS);
422
Glenn Kasten599fabc2012-03-08 12:33:37 -0800423 // AudioMixer is not yet capable of more than 32 active track inputs
424 ALOG_ASSERT(32 >= MAX_NUM_TRACKS, "bad MAX_NUM_TRACKS %d", MAX_NUM_TRACKS);
425
Glenn Kasten52008f82012-03-18 09:34:41 -0700426 pthread_once(&sOnceControl, &sInitRoutine);
427
Mathias Agopian65ab4712010-07-14 17:59:35 -0700428 mState.enabledTracks= 0;
429 mState.needsChanged = 0;
430 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800431 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -0800432 mState.outputTemp = NULL;
433 mState.resampleTemp = NULL;
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800434 mState.mLog = &mDummyLog;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800435 // mState.reserved
Glenn Kasten17a736c2012-02-14 08:52:15 -0800436
437 // FIXME Most of the following initialization is probably redundant since
438 // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0
439 // and mTrackNames is initially 0. However, leave it here until that's verified.
Mathias Agopian65ab4712010-07-14 17:59:35 -0700440 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800441 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Eric Laurenta5e82142012-04-16 13:47:17 -0700442 t->resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700443 t->downmixerBufferProvider = NULL;
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700444 t->mReformatBufferProvider = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700445 t++;
446 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700447
Mathias Agopian65ab4712010-07-14 17:59:35 -0700448}
449
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800450AudioMixer::~AudioMixer()
451{
452 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800453 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800454 delete t->resampler;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700455 delete t->downmixerBufferProvider;
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700456 delete t->mReformatBufferProvider;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800457 t++;
458 }
459 delete [] mState.outputTemp;
460 delete [] mState.resampleTemp;
461}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700462
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800463void AudioMixer::setLog(NBLog::Writer *log)
464{
465 mState.mLog = log;
466}
467
Andy Hung7f475492014-08-25 16:36:37 -0700468static inline audio_format_t selectMixerInFormat(audio_format_t inputFormat __unused) {
469 return kUseFloat && kUseNewMixer ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
470}
471
Andy Hunge8a1ced2014-05-09 15:02:21 -0700472int AudioMixer::getTrackName(audio_channel_mask_t channelMask,
473 audio_format_t format, int sessionId)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800474{
Andy Hunge8a1ced2014-05-09 15:02:21 -0700475 if (!isValidPcmTrackFormat(format)) {
476 ALOGE("AudioMixer::getTrackName invalid format (%#x)", format);
477 return -1;
478 }
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700479 uint32_t names = (~mTrackNames) & mConfiguredNames;
Glenn Kasten98dd5422011-12-15 14:38:29 -0800480 if (names != 0) {
481 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100482 ALOGV("add track (%d)", n);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700483 // assume default parameters for the track, except where noted below
484 track_t* t = &mState.tracks[n];
485 t->needs = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700486
487 // Integer volume.
488 // Currently integer volume is kept for the legacy integer mixer.
489 // Will be removed when the legacy mixer path is removed.
Andy Hung97ae8242014-05-30 10:35:47 -0700490 t->volume[0] = UNITY_GAIN_INT;
491 t->volume[1] = UNITY_GAIN_INT;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700492 t->prevVolume[0] = UNITY_GAIN_INT << 16;
493 t->prevVolume[1] = UNITY_GAIN_INT << 16;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700494 t->volumeInc[0] = 0;
495 t->volumeInc[1] = 0;
496 t->auxLevel = 0;
497 t->auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700498 t->prevAuxLevel = 0;
499
500 // Floating point volume.
501 t->mVolume[0] = UNITY_GAIN_FLOAT;
502 t->mVolume[1] = UNITY_GAIN_FLOAT;
503 t->mPrevVolume[0] = UNITY_GAIN_FLOAT;
504 t->mPrevVolume[1] = UNITY_GAIN_FLOAT;
505 t->mVolumeInc[0] = 0.;
506 t->mVolumeInc[1] = 0.;
507 t->mAuxLevel = 0.;
508 t->mAuxInc = 0.;
509 t->mPrevAuxLevel = 0.;
510
Glenn Kastendeeb1282012-03-25 11:59:31 -0700511 // no initialization needed
Glenn Kastendeeb1282012-03-25 11:59:31 -0700512 // t->frameCount
Andy Hung68112fc2014-05-14 14:13:23 -0700513 t->channelCount = audio_channel_count_from_out_mask(channelMask);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700514 t->enabled = false;
Andy Hunge93b6b72014-07-17 21:30:53 -0700515 ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
Andy Hungef7c7fb2014-05-12 16:51:41 -0700516 "Non-stereo channel mask: %d\n", channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700517 t->channelMask = channelMask;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700518 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700519 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
520 t->bufferProvider = NULL;
521 t->buffer.raw = NULL;
522 // no initialization needed
523 // t->buffer.frameCount
524 t->hook = NULL;
525 t->in = NULL;
526 t->resampler = NULL;
527 t->sampleRate = mSampleRate;
528 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
529 t->mainBuffer = NULL;
530 t->auxBuffer = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700531 t->mInputBufferProvider = NULL;
532 t->mReformatBufferProvider = NULL;
Glenn Kasten52008f82012-03-18 09:34:41 -0700533 t->downmixerBufferProvider = NULL;
Andy Hung7f475492014-08-25 16:36:37 -0700534 t->mPostDownmixReformatBufferProvider = NULL;
Andy Hung78820702014-02-28 16:23:02 -0800535 t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
Andy Hunge8a1ced2014-05-09 15:02:21 -0700536 t->mFormat = format;
Andy Hung7f475492014-08-25 16:36:37 -0700537 t->mMixerInFormat = selectMixerInFormat(format);
538 t->mDownmixRequiresFormat = AUDIO_FORMAT_INVALID; // no format required
Andy Hunge93b6b72014-07-17 21:30:53 -0700539 t->mMixerChannelMask = audio_channel_mask_from_representation_and_bits(
540 AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
541 t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
Andy Hung296b7412014-06-17 15:25:47 -0700542 // Check the downmixing (or upmixing) requirements.
Andy Hung0f451e92014-08-04 21:28:47 -0700543 status_t status = t->prepareForDownmix();
Andy Hung68112fc2014-05-14 14:13:23 -0700544 if (status != OK) {
545 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
546 return -1;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700547 }
Andy Hung7f475492014-08-25 16:36:37 -0700548 // prepareForDownmix() may change mDownmixRequiresFormat
Andy Hung296b7412014-06-17 15:25:47 -0700549 ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
Andy Hung0f451e92014-08-04 21:28:47 -0700550 t->prepareForReformat();
Andy Hung68112fc2014-05-14 14:13:23 -0700551 mTrackNames |= 1 << n;
552 return TRACK0 + n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700553 }
Andy Hung68112fc2014-05-14 14:13:23 -0700554 ALOGE("AudioMixer::getTrackName out of available tracks");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700555 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800556}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700557
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800558void AudioMixer::invalidateState(uint32_t mask)
559{
Glenn Kasten34fca342013-08-13 09:48:14 -0700560 if (mask != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700561 mState.needsChanged |= mask;
562 mState.hook = process__validate;
563 }
564 }
565
Andy Hunge93b6b72014-07-17 21:30:53 -0700566// Called when channel masks have changed for a track name
Andy Hung7f475492014-08-25 16:36:37 -0700567// TODO: Fix DownmixerBufferProvider not to (possibly) change mixer input format,
Andy Hunge93b6b72014-07-17 21:30:53 -0700568// which will simplify this logic.
569bool AudioMixer::setChannelMasks(int name,
570 audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) {
571 track_t &track = mState.tracks[name];
572
573 if (trackChannelMask == track.channelMask
574 && mixerChannelMask == track.mMixerChannelMask) {
575 return false; // no need to change
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700576 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700577 // always recompute for both channel masks even if only one has changed.
578 const uint32_t trackChannelCount = audio_channel_count_from_out_mask(trackChannelMask);
579 const uint32_t mixerChannelCount = audio_channel_count_from_out_mask(mixerChannelMask);
580 const bool mixerChannelCountChanged = track.mMixerChannelCount != mixerChannelCount;
581
582 ALOG_ASSERT((trackChannelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX)
583 && trackChannelCount
584 && mixerChannelCount);
585 track.channelMask = trackChannelMask;
586 track.channelCount = trackChannelCount;
587 track.mMixerChannelMask = mixerChannelMask;
588 track.mMixerChannelCount = mixerChannelCount;
589
590 // channel masks have changed, does this track need a downmixer?
591 // update to try using our desired format (if we aren't already using it)
Andy Hung7f475492014-08-25 16:36:37 -0700592 const audio_format_t prevDownmixerFormat = track.mDownmixRequiresFormat;
Andy Hung0f451e92014-08-04 21:28:47 -0700593 const status_t status = mState.tracks[name].prepareForDownmix();
Andy Hunge93b6b72014-07-17 21:30:53 -0700594 ALOGE_IF(status != OK,
Andy Hung0f451e92014-08-04 21:28:47 -0700595 "prepareForDownmix error %d, track channel mask %#x, mixer channel mask %#x",
Andy Hunge93b6b72014-07-17 21:30:53 -0700596 status, track.channelMask, track.mMixerChannelMask);
597
Andy Hung7f475492014-08-25 16:36:37 -0700598 if (prevDownmixerFormat != track.mDownmixRequiresFormat) {
Andy Hung0f451e92014-08-04 21:28:47 -0700599 track.prepareForReformat(); // because of downmixer, track format may change!
Andy Hunge93b6b72014-07-17 21:30:53 -0700600 }
601
Andy Hung7f475492014-08-25 16:36:37 -0700602 if (track.resampler && mixerChannelCountChanged) {
603 // resampler channels may have changed.
Andy Hunge93b6b72014-07-17 21:30:53 -0700604 const uint32_t resetToSampleRate = track.sampleRate;
605 delete track.resampler;
606 track.resampler = NULL;
607 track.sampleRate = mSampleRate; // without resampler, track rate is device sample rate.
608 // recreate the resampler with updated format, channels, saved sampleRate.
609 track.setResampler(resetToSampleRate /*trackSampleRate*/, mSampleRate /*devSampleRate*/);
610 }
611 return true;
612}
613
Andy Hung0f451e92014-08-04 21:28:47 -0700614void AudioMixer::track_t::unprepareForDownmix() {
615 ALOGV("AudioMixer::unprepareForDownmix(%p)", this);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700616
Andy Hung7f475492014-08-25 16:36:37 -0700617 mDownmixRequiresFormat = AUDIO_FORMAT_INVALID;
Andy Hung0f451e92014-08-04 21:28:47 -0700618 if (downmixerBufferProvider != NULL) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700619 // this track had previously been configured with a downmixer, delete it
620 ALOGV(" deleting old downmixer");
Andy Hung0f451e92014-08-04 21:28:47 -0700621 delete downmixerBufferProvider;
622 downmixerBufferProvider = NULL;
623 reconfigureBufferProviders();
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700624 } else {
625 ALOGV(" nothing to do, no downmixer to delete");
626 }
627}
628
Andy Hung0f451e92014-08-04 21:28:47 -0700629status_t AudioMixer::track_t::prepareForDownmix()
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700630{
Andy Hung0f451e92014-08-04 21:28:47 -0700631 ALOGV("AudioMixer::prepareForDownmix(%p) with mask 0x%x",
632 this, channelMask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700633
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700634 // discard the previous downmixer if there was one
Andy Hung0f451e92014-08-04 21:28:47 -0700635 unprepareForDownmix();
636 // Only remix (upmix or downmix) if the track and mixer/device channel masks
637 // are not the same and not handled internally, as mono -> stereo currently is.
638 if (channelMask == mMixerChannelMask
639 || (channelMask == AUDIO_CHANNEL_OUT_MONO
640 && mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO)) {
641 return NO_ERROR;
642 }
Andy Hung650ceb92015-01-29 13:31:12 -0800643 // DownmixerBufferProvider is only used for position masks.
644 if (audio_channel_mask_get_representation(channelMask)
645 == AUDIO_CHANNEL_REPRESENTATION_POSITION
646 && DownmixerBufferProvider::isMultichannelCapable()) {
Andy Hung0f451e92014-08-04 21:28:47 -0700647 DownmixerBufferProvider* pDbp = new DownmixerBufferProvider(channelMask,
648 mMixerChannelMask,
649 AUDIO_FORMAT_PCM_16_BIT /* TODO: use mMixerInFormat, now only PCM 16 */,
650 sampleRate, sessionId, kCopyBufferFrameCount);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700651
Andy Hung34803d52014-07-16 21:41:35 -0700652 if (pDbp->isValid()) { // if constructor completed properly
Andy Hung7f475492014-08-25 16:36:37 -0700653 mDownmixRequiresFormat = AUDIO_FORMAT_PCM_16_BIT; // PCM 16 bit required for downmix
Andy Hung0f451e92014-08-04 21:28:47 -0700654 downmixerBufferProvider = pDbp;
655 reconfigureBufferProviders();
Andy Hung34803d52014-07-16 21:41:35 -0700656 return NO_ERROR;
657 }
658 delete pDbp;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700659 }
Andy Hunge93b6b72014-07-17 21:30:53 -0700660
661 // Effect downmixer does not accept the channel conversion. Let's use our remixer.
Andy Hung0f451e92014-08-04 21:28:47 -0700662 RemixBufferProvider* pRbp = new RemixBufferProvider(channelMask,
663 mMixerChannelMask, mMixerInFormat, kCopyBufferFrameCount);
Andy Hunge93b6b72014-07-17 21:30:53 -0700664 // Remix always finds a conversion whereas Downmixer effect above may fail.
Andy Hung0f451e92014-08-04 21:28:47 -0700665 downmixerBufferProvider = pRbp;
666 reconfigureBufferProviders();
Andy Hunge93b6b72014-07-17 21:30:53 -0700667 return NO_ERROR;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700668}
669
Andy Hung0f451e92014-08-04 21:28:47 -0700670void AudioMixer::track_t::unprepareForReformat() {
671 ALOGV("AudioMixer::unprepareForReformat(%p)", this);
Andy Hung7f475492014-08-25 16:36:37 -0700672 bool requiresReconfigure = false;
Andy Hung0f451e92014-08-04 21:28:47 -0700673 if (mReformatBufferProvider != NULL) {
674 delete mReformatBufferProvider;
675 mReformatBufferProvider = NULL;
Andy Hung7f475492014-08-25 16:36:37 -0700676 requiresReconfigure = true;
677 }
678 if (mPostDownmixReformatBufferProvider != NULL) {
679 delete mPostDownmixReformatBufferProvider;
680 mPostDownmixReformatBufferProvider = NULL;
681 requiresReconfigure = true;
682 }
683 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700684 reconfigureBufferProviders();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700685 }
686}
687
Andy Hung0f451e92014-08-04 21:28:47 -0700688status_t AudioMixer::track_t::prepareForReformat()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700689{
Andy Hung0f451e92014-08-04 21:28:47 -0700690 ALOGV("AudioMixer::prepareForReformat(%p) with format %#x", this, mFormat);
Andy Hung7f475492014-08-25 16:36:37 -0700691 // discard previous reformatters
Andy Hung0f451e92014-08-04 21:28:47 -0700692 unprepareForReformat();
Andy Hung7f475492014-08-25 16:36:37 -0700693 // only configure reformatters as needed
694 const audio_format_t targetFormat = mDownmixRequiresFormat != AUDIO_FORMAT_INVALID
695 ? mDownmixRequiresFormat : mMixerInFormat;
696 bool requiresReconfigure = false;
697 if (mFormat != targetFormat) {
Andy Hung0f451e92014-08-04 21:28:47 -0700698 mReformatBufferProvider = new ReformatBufferProvider(
699 audio_channel_count_from_out_mask(channelMask),
Andy Hung7f475492014-08-25 16:36:37 -0700700 mFormat,
701 targetFormat,
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700702 kCopyBufferFrameCount);
Andy Hung7f475492014-08-25 16:36:37 -0700703 requiresReconfigure = true;
704 }
705 if (targetFormat != mMixerInFormat) {
706 mPostDownmixReformatBufferProvider = new ReformatBufferProvider(
707 audio_channel_count_from_out_mask(mMixerChannelMask),
708 targetFormat,
709 mMixerInFormat,
710 kCopyBufferFrameCount);
711 requiresReconfigure = true;
712 }
713 if (requiresReconfigure) {
Andy Hung0f451e92014-08-04 21:28:47 -0700714 reconfigureBufferProviders();
Andy Hung296b7412014-06-17 15:25:47 -0700715 }
716 return NO_ERROR;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700717}
718
Andy Hung0f451e92014-08-04 21:28:47 -0700719void AudioMixer::track_t::reconfigureBufferProviders()
Andy Hungef7c7fb2014-05-12 16:51:41 -0700720{
Andy Hung0f451e92014-08-04 21:28:47 -0700721 bufferProvider = mInputBufferProvider;
722 if (mReformatBufferProvider) {
723 mReformatBufferProvider->setBufferProvider(bufferProvider);
724 bufferProvider = mReformatBufferProvider;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700725 }
Andy Hung0f451e92014-08-04 21:28:47 -0700726 if (downmixerBufferProvider) {
727 downmixerBufferProvider->setBufferProvider(bufferProvider);
728 bufferProvider = downmixerBufferProvider;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700729 }
Andy Hung7f475492014-08-25 16:36:37 -0700730 if (mPostDownmixReformatBufferProvider) {
731 mPostDownmixReformatBufferProvider->setBufferProvider(bufferProvider);
732 bufferProvider = mPostDownmixReformatBufferProvider;
733 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700734}
735
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800736void AudioMixer::deleteTrackName(int name)
737{
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700738 ALOGV("AudioMixer::deleteTrackName(%d)", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700739 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800740 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800741 ALOGV("deleteTrackName(%d)", name);
742 track_t& track(mState.tracks[ name ]);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800743 if (track.enabled) {
744 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800745 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700746 }
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700747 // delete the resampler
748 delete track.resampler;
749 track.resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700750 // delete the downmixer
Andy Hung0f451e92014-08-04 21:28:47 -0700751 mState.tracks[name].unprepareForDownmix();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700752 // delete the reformatter
Andy Hung0f451e92014-08-04 21:28:47 -0700753 mState.tracks[name].unprepareForReformat();
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700754
Glenn Kasten237a6242011-12-15 15:32:27 -0800755 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800756}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700757
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800758void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700759{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800760 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800761 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800762 track_t& track = mState.tracks[name];
763
Glenn Kasten4c340c62012-01-27 12:33:54 -0800764 if (!track.enabled) {
765 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800766 ALOGV("enable(%d)", name);
767 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700768 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700769}
770
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800771void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700772{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800773 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800774 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800775 track_t& track = mState.tracks[name];
776
Glenn Kasten4c340c62012-01-27 12:33:54 -0800777 if (track.enabled) {
778 track.enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800779 ALOGV("disable(%d)", name);
780 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700781 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700782}
783
Andy Hung5866a3b2014-05-29 21:33:13 -0700784/* Sets the volume ramp variables for the AudioMixer.
785 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700786 * The volume ramp variables are used to transition from the previous
787 * volume to the set volume. ramp controls the duration of the transition.
788 * Its value is typically one state framecount period, but may also be 0,
789 * meaning "immediate."
Andy Hung5866a3b2014-05-29 21:33:13 -0700790 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700791 * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
792 * even if there is a nonzero floating point increment (in that case, the volume
793 * change is immediate). This restriction should be changed when the legacy mixer
794 * is removed (see #2).
795 * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
796 * when no longer needed.
797 *
798 * @param newVolume set volume target in floating point [0.0, 1.0].
799 * @param ramp number of frames to increment over. if ramp is 0, the volume
800 * should be set immediately. Currently ramp should not exceed 65535 (frames).
801 * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
802 * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
803 * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
804 * @param pSetVolume pointer to the float target volume, set on return.
805 * @param pPrevVolume pointer to the float previous volume, set on return.
806 * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
Andy Hung5866a3b2014-05-29 21:33:13 -0700807 * @return true if the volume has changed, false if volume is same.
808 */
Andy Hung5e58b0a2014-06-23 19:07:29 -0700809static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
810 int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
811 float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
812 if (newVolume == *pSetVolume) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700813 return false;
814 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700815 /* set the floating point volume variables */
Andy Hung5866a3b2014-05-29 21:33:13 -0700816 if (ramp != 0) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700817 *pVolumeInc = (newVolume - *pSetVolume) / ramp;
818 *pPrevVolume = *pSetVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700819 } else {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700820 *pVolumeInc = 0;
821 *pPrevVolume = newVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700822 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700823 *pSetVolume = newVolume;
824
825 /* set the legacy integer volume variables */
826 int32_t intVolume = newVolume * AudioMixer::UNITY_GAIN_INT;
827 if (intVolume > AudioMixer::UNITY_GAIN_INT) {
828 intVolume = AudioMixer::UNITY_GAIN_INT;
829 } else if (intVolume < 0) {
830 ALOGE("negative volume %.7g", newVolume);
831 intVolume = 0; // should never happen, but for safety check.
832 }
833 if (intVolume == *pIntSetVolume) {
834 *pIntVolumeInc = 0;
835 /* TODO: integer/float workaround: ignore floating volume ramp */
836 *pVolumeInc = 0;
837 *pPrevVolume = newVolume;
838 return true;
839 }
840 if (ramp != 0) {
841 *pIntVolumeInc = ((intVolume - *pIntSetVolume) << 16) / ramp;
842 *pIntPrevVolume = (*pIntVolumeInc == 0 ? intVolume : *pIntSetVolume) << 16;
843 } else {
844 *pIntVolumeInc = 0;
845 *pIntPrevVolume = intVolume << 16;
846 }
847 *pIntSetVolume = intVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700848 return true;
849}
850
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800851void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700852{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800853 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800854 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800855 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700856
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000857 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
858 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700859
860 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700861
Mathias Agopian65ab4712010-07-14 17:59:35 -0700862 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800863 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700864 case CHANNEL_MASK: {
Andy Hunge93b6b72014-07-17 21:30:53 -0700865 const audio_channel_mask_t trackChannelMask =
866 static_cast<audio_channel_mask_t>(valueInt);
867 if (setChannelMasks(name, trackChannelMask, track.mMixerChannelMask)) {
868 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800869 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700870 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700871 } break;
872 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800873 if (track.mainBuffer != valueBuf) {
874 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100875 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800876 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700877 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700878 break;
879 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800880 if (track.auxBuffer != valueBuf) {
881 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100882 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800883 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700884 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700885 break;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700886 case FORMAT: {
887 audio_format_t format = static_cast<audio_format_t>(valueInt);
888 if (track.mFormat != format) {
889 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
890 track.mFormat = format;
891 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
Andy Hung0f451e92014-08-04 21:28:47 -0700892 track.prepareForReformat();
Andy Hungef7c7fb2014-05-12 16:51:41 -0700893 invalidateState(1 << name);
894 }
895 } break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700896 // FIXME do we want to support setting the downmix type from AudioFlinger?
897 // for a specific track? or per mixer?
898 /* case DOWNMIX_TYPE:
899 break */
Andy Hung78820702014-02-28 16:23:02 -0800900 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800901 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung78820702014-02-28 16:23:02 -0800902 if (track.mMixerFormat != format) {
903 track.mMixerFormat = format;
904 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800905 }
906 } break;
Andy Hunge93b6b72014-07-17 21:30:53 -0700907 case MIXER_CHANNEL_MASK: {
908 const audio_channel_mask_t mixerChannelMask =
909 static_cast<audio_channel_mask_t>(valueInt);
910 if (setChannelMasks(name, track.channelMask, mixerChannelMask)) {
911 ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);
912 invalidateState(1 << name);
913 }
914 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700915 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800916 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700917 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700918 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700919
Mathias Agopian65ab4712010-07-14 17:59:35 -0700920 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800921 switch (param) {
922 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800923 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700924 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
925 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
926 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800927 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700928 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800929 break;
930 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800931 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800932 invalidateState(1 << name);
933 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700934 case REMOVE:
935 delete track.resampler;
936 track.resampler = NULL;
937 track.sampleRate = mSampleRate;
938 invalidateState(1 << name);
939 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700940 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800941 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800942 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700943 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700944
Mathias Agopian65ab4712010-07-14 17:59:35 -0700945 case RAMP_VOLUME:
946 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800947 switch (param) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800948 case AUXLEVEL:
Andy Hung6be49402014-05-30 10:42:03 -0700949 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung5866a3b2014-05-29 21:33:13 -0700950 target == RAMP_VOLUME ? mState.frameCount : 0,
Andy Hung5e58b0a2014-06-23 19:07:29 -0700951 &track.auxLevel, &track.prevAuxLevel, &track.auxInc,
952 &track.mAuxLevel, &track.mPrevAuxLevel, &track.mAuxInc)) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700953 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
Andy Hung6be49402014-05-30 10:42:03 -0700954 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track.auxLevel);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800955 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700956 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800957 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700958 default:
Andy Hunge93b6b72014-07-17 21:30:53 -0700959 if ((unsigned)param >= VOLUME0 && (unsigned)param < VOLUME0 + MAX_NUM_VOLUMES) {
960 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
961 target == RAMP_VOLUME ? mState.frameCount : 0,
962 &track.volume[param - VOLUME0], &track.prevVolume[param - VOLUME0],
963 &track.volumeInc[param - VOLUME0],
964 &track.mVolume[param - VOLUME0], &track.mPrevVolume[param - VOLUME0],
965 &track.mVolumeInc[param - VOLUME0])) {
966 ALOGV("setParameter(%s, VOLUME%d: %04x)",
967 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
968 track.volume[param - VOLUME0]);
969 invalidateState(1 << name);
970 }
971 } else {
972 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
973 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700974 }
975 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700976
977 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800978 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700979 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700980}
981
Andy Hunge93b6b72014-07-17 21:30:53 -0700982bool AudioMixer::track_t::setResampler(uint32_t trackSampleRate, uint32_t devSampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700983{
Andy Hunge93b6b72014-07-17 21:30:53 -0700984 if (trackSampleRate != devSampleRate || resampler != NULL) {
985 if (sampleRate != trackSampleRate) {
986 sampleRate = trackSampleRate;
Glenn Kastene0feee32011-12-13 11:53:26 -0800987 if (resampler == NULL) {
Andy Hunge93b6b72014-07-17 21:30:53 -0700988 ALOGV("Creating resampler from track %d Hz to device %d Hz",
989 trackSampleRate, devSampleRate);
Glenn Kastenac602052012-10-01 14:04:31 -0700990 AudioResampler::src_quality quality;
991 // force lowest quality level resampler if use case isn't music or video
992 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
993 // quality level based on the initial ratio, but that could change later.
994 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
Andy Hunge93b6b72014-07-17 21:30:53 -0700995 if (!((trackSampleRate == 44100 && devSampleRate == 48000) ||
996 (trackSampleRate == 48000 && devSampleRate == 44100))) {
Andy Hung9e0308c2014-01-30 14:32:31 -0800997 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700998 } else {
999 quality = AudioResampler::DEFAULT_QUALITY;
1000 }
Andy Hung296b7412014-06-17 15:25:47 -07001001
Andy Hunge93b6b72014-07-17 21:30:53 -07001002 // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
1003 // but if none exists, it is the channel count (1 for mono).
1004 const int resamplerChannelCount = downmixerBufferProvider != NULL
1005 ? mMixerChannelCount : channelCount;
Andy Hung9a592762014-07-21 21:56:01 -07001006 ALOGVV("Creating resampler:"
1007 " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
1008 mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001009 resampler = AudioResampler::create(
Andy Hung3348e362014-07-07 10:21:44 -07001010 mMixerInFormat,
Andy Hunge93b6b72014-07-17 21:30:53 -07001011 resamplerChannelCount,
Glenn Kastenac602052012-10-01 14:04:31 -07001012 devSampleRate, quality);
Glenn Kasten52008f82012-03-18 09:34:41 -07001013 resampler->setLocalTimeFreq(sLocalTimeFreq);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001014 }
1015 return true;
1016 }
1017 }
1018 return false;
1019}
1020
Andy Hung5e58b0a2014-06-23 19:07:29 -07001021/* Checks to see if the volume ramp has completed and clears the increment
1022 * variables appropriately.
1023 *
1024 * FIXME: There is code to handle int/float ramp variable switchover should it not
1025 * complete within a mixer buffer processing call, but it is preferred to avoid switchover
1026 * due to precision issues. The switchover code is included for legacy code purposes
1027 * and can be removed once the integer volume is removed.
1028 *
1029 * It is not sufficient to clear only the volumeInc integer variable because
1030 * if one channel requires ramping, all channels are ramped.
1031 *
1032 * There is a bit of duplicated code here, but it keeps backward compatibility.
1033 */
1034inline void AudioMixer::track_t::adjustVolumeRamp(bool aux, bool useFloat)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001035{
Andy Hung5e58b0a2014-06-23 19:07:29 -07001036 if (useFloat) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001037 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001038 if (mVolumeInc[i] != 0 && fabs(mVolume[i] - mPrevVolume[i]) <= fabs(mVolumeInc[i])) {
1039 volumeInc[i] = 0;
1040 prevVolume[i] = volume[i] << 16;
1041 mVolumeInc[i] = 0.;
1042 mPrevVolume[i] = mVolume[i];
Andy Hung5e58b0a2014-06-23 19:07:29 -07001043 } else {
1044 //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
1045 prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
1046 }
1047 }
1048 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -07001049 for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001050 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
1051 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
1052 volumeInc[i] = 0;
1053 prevVolume[i] = volume[i] << 16;
1054 mVolumeInc[i] = 0.;
1055 mPrevVolume[i] = mVolume[i];
1056 } else {
1057 //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
1058 mPrevVolume[i] = float_from_u4_28(prevVolume[i]);
1059 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001060 }
1061 }
Andy Hung5e58b0a2014-06-23 19:07:29 -07001062 /* TODO: aux is always integer regardless of output buffer type */
Mathias Agopian65ab4712010-07-14 17:59:35 -07001063 if (aux) {
1064 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
Andy Hung5e58b0a2014-06-23 19:07:29 -07001065 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001066 auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -07001067 prevAuxLevel = auxLevel << 16;
1068 mAuxInc = 0.;
1069 mPrevAuxLevel = mAuxLevel;
1070 } else {
1071 //ALOGV("aux ramp: %d %d %d", auxLevel << 16, prevAuxLevel, auxInc);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001072 }
1073 }
1074}
1075
Glenn Kastenc59c0042012-02-02 14:06:11 -08001076size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -08001077{
1078 name -= TRACK0;
1079 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -08001080 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -08001081 }
1082 return 0;
1083}
Mathias Agopian65ab4712010-07-14 17:59:35 -07001084
Glenn Kasten01c4ebf2012-02-22 10:47:35 -08001085void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001086{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -08001087 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001088 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001089
Andy Hung1d26ddf2014-05-29 15:53:09 -07001090 if (mState.tracks[name].mInputBufferProvider == bufferProvider) {
1091 return; // don't reset any buffer providers if identical.
1092 }
Andy Hungef7c7fb2014-05-12 16:51:41 -07001093 if (mState.tracks[name].mReformatBufferProvider != NULL) {
1094 mState.tracks[name].mReformatBufferProvider->reset();
1095 } else if (mState.tracks[name].downmixerBufferProvider != NULL) {
Andy Hung7f475492014-08-25 16:36:37 -07001096 mState.tracks[name].downmixerBufferProvider->reset();
1097 } else if (mState.tracks[name].mPostDownmixReformatBufferProvider != NULL) {
1098 mState.tracks[name].mPostDownmixReformatBufferProvider->reset();
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001099 }
Andy Hungef7c7fb2014-05-12 16:51:41 -07001100
1101 mState.tracks[name].mInputBufferProvider = bufferProvider;
Andy Hung0f451e92014-08-04 21:28:47 -07001102 mState.tracks[name].reconfigureBufferProviders();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001103}
1104
1105
John Grossman4ff14ba2012-02-08 16:37:41 -08001106void AudioMixer::process(int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001107{
John Grossman4ff14ba2012-02-08 16:37:41 -08001108 mState.hook(&mState, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001109}
1110
1111
John Grossman4ff14ba2012-02-08 16:37:41 -08001112void AudioMixer::process__validate(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001113{
Steve Block5ff1dd52012-01-05 23:22:43 +00001114 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -07001115 "in process__validate() but nothing's invalid");
1116
1117 uint32_t changed = state->needsChanged;
1118 state->needsChanged = 0; // clear the validation flag
1119
1120 // recompute which tracks are enabled / disabled
1121 uint32_t enabled = 0;
1122 uint32_t disabled = 0;
1123 while (changed) {
1124 const int i = 31 - __builtin_clz(changed);
1125 const uint32_t mask = 1<<i;
1126 changed &= ~mask;
1127 track_t& t = state->tracks[i];
1128 (t.enabled ? enabled : disabled) |= mask;
1129 }
1130 state->enabledTracks &= ~disabled;
1131 state->enabledTracks |= enabled;
1132
1133 // compute everything we need...
1134 int countActiveTracks = 0;
Andy Hung395db4b2014-08-25 17:15:29 -07001135 // TODO: fix all16BitsStereNoResample logic to
1136 // either properly handle muted tracks (it should ignore them)
1137 // or remove altogether as an obsolete optimization.
Glenn Kasten4c340c62012-01-27 12:33:54 -08001138 bool all16BitsStereoNoResample = true;
1139 bool resampling = false;
1140 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001141 uint32_t en = state->enabledTracks;
1142 while (en) {
1143 const int i = 31 - __builtin_clz(en);
1144 en &= ~(1<<i);
1145
1146 countActiveTracks++;
1147 track_t& t = state->tracks[i];
1148 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001149 // FIXME can overflow (mask is only 3 bits)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001150 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001151 if (t.doesResample()) {
1152 n |= NEEDS_RESAMPLE;
1153 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001154 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001155 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001156 }
1157
1158 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001159 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001160 } else if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001161 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001162 }
1163 t.needs = n;
1164
Glenn Kastend6fadf02013-10-30 14:37:29 -07001165 if (n & NEEDS_MUTE) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001166 t.hook = track__nop;
1167 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001168 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001169 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001170 }
Glenn Kastend6fadf02013-10-30 14:37:29 -07001171 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001172 all16BitsStereoNoResample = false;
1173 resampling = true;
Andy Hunge93b6b72014-07-17 21:30:53 -07001174 t.hook = getTrackHook(TRACKTYPE_RESAMPLE, t.mMixerChannelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001175 t.mMixerInFormat, t.mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001176 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -07001177 "Track %d needs downmix + resample", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001178 } else {
1179 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
Andy Hunge93b6b72014-07-17 21:30:53 -07001180 t.hook = getTrackHook(
1181 t.mMixerChannelCount == 2 // TODO: MONO_HACK.
1182 ? TRACKTYPE_NORESAMPLEMONO : TRACKTYPE_NORESAMPLE,
1183 t.mMixerChannelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001184 t.mMixerInFormat, t.mMixerFormat);
Glenn Kasten4c340c62012-01-27 12:33:54 -08001185 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001186 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001187 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Andy Hunge93b6b72014-07-17 21:30:53 -07001188 t.hook = getTrackHook(TRACKTYPE_NORESAMPLE, t.mMixerChannelCount,
Andy Hung296b7412014-06-17 15:25:47 -07001189 t.mMixerInFormat, t.mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001190 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -07001191 "Track %d needs downmix", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001192 }
1193 }
1194 }
1195 }
1196
1197 // select the processing hooks
1198 state->hook = process__nop;
Glenn Kasten34fca342013-08-13 09:48:14 -07001199 if (countActiveTracks > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001200 if (resampling) {
1201 if (!state->outputTemp) {
1202 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
1203 }
1204 if (!state->resampleTemp) {
1205 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
1206 }
1207 state->hook = process__genericResampling;
1208 } else {
1209 if (state->outputTemp) {
1210 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -08001211 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001212 }
1213 if (state->resampleTemp) {
1214 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -08001215 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001216 }
1217 state->hook = process__genericNoResampling;
1218 if (all16BitsStereoNoResample && !volumeRamp) {
1219 if (countActiveTracks == 1) {
Andy Hung296b7412014-06-17 15:25:47 -07001220 const int i = 31 - __builtin_clz(state->enabledTracks);
1221 track_t& t = state->tracks[i];
Andy Hung395db4b2014-08-25 17:15:29 -07001222 if ((t.needs & NEEDS_MUTE) == 0) {
1223 // The check prevents a muted track from acquiring a process hook.
1224 //
1225 // This is dangerous if the track is MONO as that requires
1226 // special case handling due to implicit channel duplication.
1227 // Stereo or Multichannel should actually be fine here.
1228 state->hook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
1229 t.mMixerChannelCount, t.mMixerInFormat, t.mMixerFormat);
1230 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001231 }
1232 }
1233 }
1234 }
1235
Steve Block3856b092011-10-20 11:56:00 +01001236 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001237 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
1238 countActiveTracks, state->enabledTracks,
1239 all16BitsStereoNoResample, resampling, volumeRamp);
1240
John Grossman4ff14ba2012-02-08 16:37:41 -08001241 state->hook(state, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001242
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001243 // Now that the volume ramp has been done, set optimal state and
1244 // track hooks for subsequent mixer process
Glenn Kasten34fca342013-08-13 09:48:14 -07001245 if (countActiveTracks > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001246 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001247 uint32_t en = state->enabledTracks;
1248 while (en) {
1249 const int i = 31 - __builtin_clz(en);
1250 en &= ~(1<<i);
1251 track_t& t = state->tracks[i];
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001252 if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001253 t.needs |= NEEDS_MUTE;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001254 t.hook = track__nop;
1255 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001256 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001257 }
1258 }
1259 if (allMuted) {
1260 state->hook = process__nop;
1261 } else if (all16BitsStereoNoResample) {
1262 if (countActiveTracks == 1) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001263 const int i = 31 - __builtin_clz(state->enabledTracks);
1264 track_t& t = state->tracks[i];
Andy Hung395db4b2014-08-25 17:15:29 -07001265 // Muted single tracks handled by allMuted above.
Andy Hunge93b6b72014-07-17 21:30:53 -07001266 state->hook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
1267 t.mMixerChannelCount, t.mMixerInFormat, t.mMixerFormat);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001268 }
1269 }
1270 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001271}
1272
Mathias Agopian65ab4712010-07-14 17:59:35 -07001273
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001274void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount,
1275 int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001276{
Andy Hung296b7412014-06-17 15:25:47 -07001277 ALOGVV("track__genericResample\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001278 t->resampler->setSampleRate(t->sampleRate);
1279
1280 // ramp gain - resample to temp buffer and scale/mix in 2nd step
1281 if (aux != NULL) {
1282 // always resample with unity gain when sending to auxiliary buffer to be able
1283 // to apply send level after resampling
Andy Hung5e58b0a2014-06-23 19:07:29 -07001284 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Andy Hunge93b6b72014-07-17 21:30:53 -07001285 memset(temp, 0, outFrameCount * t->mMixerChannelCount * sizeof(int32_t));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001286 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -08001287 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001288 volumeRampStereo(t, out, outFrameCount, temp, aux);
1289 } else {
1290 volumeStereo(t, out, outFrameCount, temp, aux);
1291 }
1292 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -08001293 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001294 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001295 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
1296 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
1297 volumeRampStereo(t, out, outFrameCount, temp, aux);
1298 }
1299
1300 // constant gain
1301 else {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001302 t->resampler->setVolume(t->mVolume[0], t->mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001303 t->resampler->resample(out, outFrameCount, t->bufferProvider);
1304 }
1305 }
1306}
1307
Andy Hungee931ff2014-01-28 13:44:14 -08001308void AudioMixer::track__nop(track_t* t __unused, int32_t* out __unused,
1309 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001310{
1311}
1312
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001313void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1314 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001315{
1316 int32_t vl = t->prevVolume[0];
1317 int32_t vr = t->prevVolume[1];
1318 const int32_t vlInc = t->volumeInc[0];
1319 const int32_t vrInc = t->volumeInc[1];
1320
Steve Blockb8a80522011-12-20 16:23:08 +00001321 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001322 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1323 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1324
1325 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -08001326 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001327 int32_t va = t->prevAuxLevel;
1328 const int32_t vaInc = t->auxInc;
1329 int32_t l;
1330 int32_t r;
1331
1332 do {
1333 l = (*temp++ >> 12);
1334 r = (*temp++ >> 12);
1335 *out++ += (vl >> 16) * l;
1336 *out++ += (vr >> 16) * r;
1337 *aux++ += (va >> 17) * (l + r);
1338 vl += vlInc;
1339 vr += vrInc;
1340 va += vaInc;
1341 } while (--frameCount);
1342 t->prevAuxLevel = va;
1343 } else {
1344 do {
1345 *out++ += (vl >> 16) * (*temp++ >> 12);
1346 *out++ += (vr >> 16) * (*temp++ >> 12);
1347 vl += vlInc;
1348 vr += vrInc;
1349 } while (--frameCount);
1350 }
1351 t->prevVolume[0] = vl;
1352 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -08001353 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001354}
1355
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001356void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1357 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001358{
1359 const int16_t vl = t->volume[0];
1360 const int16_t vr = t->volume[1];
1361
Glenn Kastenf6b16782011-12-15 09:51:17 -08001362 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -08001363 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001364 do {
1365 int16_t l = (int16_t)(*temp++ >> 12);
1366 int16_t r = (int16_t)(*temp++ >> 12);
1367 out[0] = mulAdd(l, vl, out[0]);
1368 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
1369 out[1] = mulAdd(r, vr, out[1]);
1370 out += 2;
1371 aux[0] = mulAdd(a, va, aux[0]);
1372 aux++;
1373 } while (--frameCount);
1374 } else {
1375 do {
1376 int16_t l = (int16_t)(*temp++ >> 12);
1377 int16_t r = (int16_t)(*temp++ >> 12);
1378 out[0] = mulAdd(l, vl, out[0]);
1379 out[1] = mulAdd(r, vr, out[1]);
1380 out += 2;
1381 } while (--frameCount);
1382 }
1383}
1384
Andy Hungee931ff2014-01-28 13:44:14 -08001385void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount,
1386 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001387{
Andy Hung296b7412014-06-17 15:25:47 -07001388 ALOGVV("track__16BitsStereo\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001389 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001390
Glenn Kastenf6b16782011-12-15 09:51:17 -08001391 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001392 int32_t l;
1393 int32_t r;
1394 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001395 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001396 int32_t vl = t->prevVolume[0];
1397 int32_t vr = t->prevVolume[1];
1398 int32_t va = t->prevAuxLevel;
1399 const int32_t vlInc = t->volumeInc[0];
1400 const int32_t vrInc = t->volumeInc[1];
1401 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +00001402 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001403 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1404 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1405
1406 do {
1407 l = (int32_t)*in++;
1408 r = (int32_t)*in++;
1409 *out++ += (vl >> 16) * l;
1410 *out++ += (vr >> 16) * r;
1411 *aux++ += (va >> 17) * (l + r);
1412 vl += vlInc;
1413 vr += vrInc;
1414 va += vaInc;
1415 } while (--frameCount);
1416
1417 t->prevVolume[0] = vl;
1418 t->prevVolume[1] = vr;
1419 t->prevAuxLevel = va;
1420 t->adjustVolumeRamp(true);
1421 }
1422
1423 // constant gain
1424 else {
1425 const uint32_t vrl = t->volumeRL;
1426 const int16_t va = (int16_t)t->auxLevel;
1427 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001428 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001429 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
1430 in += 2;
1431 out[0] = mulAddRL(1, rl, vrl, out[0]);
1432 out[1] = mulAddRL(0, rl, vrl, out[1]);
1433 out += 2;
1434 aux[0] = mulAdd(a, va, aux[0]);
1435 aux++;
1436 } while (--frameCount);
1437 }
1438 } else {
1439 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001440 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001441 int32_t vl = t->prevVolume[0];
1442 int32_t vr = t->prevVolume[1];
1443 const int32_t vlInc = t->volumeInc[0];
1444 const int32_t vrInc = t->volumeInc[1];
1445
Steve Blockb8a80522011-12-20 16:23:08 +00001446 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001447 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1448 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1449
1450 do {
1451 *out++ += (vl >> 16) * (int32_t) *in++;
1452 *out++ += (vr >> 16) * (int32_t) *in++;
1453 vl += vlInc;
1454 vr += vrInc;
1455 } while (--frameCount);
1456
1457 t->prevVolume[0] = vl;
1458 t->prevVolume[1] = vr;
1459 t->adjustVolumeRamp(false);
1460 }
1461
1462 // constant gain
1463 else {
1464 const uint32_t vrl = t->volumeRL;
1465 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001466 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001467 in += 2;
1468 out[0] = mulAddRL(1, rl, vrl, out[0]);
1469 out[1] = mulAddRL(0, rl, vrl, out[1]);
1470 out += 2;
1471 } while (--frameCount);
1472 }
1473 }
1474 t->in = in;
1475}
1476
Andy Hungee931ff2014-01-28 13:44:14 -08001477void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount,
1478 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001479{
Andy Hung296b7412014-06-17 15:25:47 -07001480 ALOGVV("track__16BitsMono\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001481 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001482
Glenn Kastenf6b16782011-12-15 09:51:17 -08001483 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001484 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001485 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001486 int32_t vl = t->prevVolume[0];
1487 int32_t vr = t->prevVolume[1];
1488 int32_t va = t->prevAuxLevel;
1489 const int32_t vlInc = t->volumeInc[0];
1490 const int32_t vrInc = t->volumeInc[1];
1491 const int32_t vaInc = t->auxInc;
1492
Steve Blockb8a80522011-12-20 16:23:08 +00001493 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001494 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1495 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1496
1497 do {
1498 int32_t l = *in++;
1499 *out++ += (vl >> 16) * l;
1500 *out++ += (vr >> 16) * l;
1501 *aux++ += (va >> 16) * l;
1502 vl += vlInc;
1503 vr += vrInc;
1504 va += vaInc;
1505 } while (--frameCount);
1506
1507 t->prevVolume[0] = vl;
1508 t->prevVolume[1] = vr;
1509 t->prevAuxLevel = va;
1510 t->adjustVolumeRamp(true);
1511 }
1512 // constant gain
1513 else {
1514 const int16_t vl = t->volume[0];
1515 const int16_t vr = t->volume[1];
1516 const int16_t va = (int16_t)t->auxLevel;
1517 do {
1518 int16_t l = *in++;
1519 out[0] = mulAdd(l, vl, out[0]);
1520 out[1] = mulAdd(l, vr, out[1]);
1521 out += 2;
1522 aux[0] = mulAdd(l, va, aux[0]);
1523 aux++;
1524 } while (--frameCount);
1525 }
1526 } else {
1527 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001528 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001529 int32_t vl = t->prevVolume[0];
1530 int32_t vr = t->prevVolume[1];
1531 const int32_t vlInc = t->volumeInc[0];
1532 const int32_t vrInc = t->volumeInc[1];
1533
Steve Blockb8a80522011-12-20 16:23:08 +00001534 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001535 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1536 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1537
1538 do {
1539 int32_t l = *in++;
1540 *out++ += (vl >> 16) * l;
1541 *out++ += (vr >> 16) * l;
1542 vl += vlInc;
1543 vr += vrInc;
1544 } while (--frameCount);
1545
1546 t->prevVolume[0] = vl;
1547 t->prevVolume[1] = vr;
1548 t->adjustVolumeRamp(false);
1549 }
1550 // constant gain
1551 else {
1552 const int16_t vl = t->volume[0];
1553 const int16_t vr = t->volume[1];
1554 do {
1555 int16_t l = *in++;
1556 out[0] = mulAdd(l, vl, out[0]);
1557 out[1] = mulAdd(l, vr, out[1]);
1558 out += 2;
1559 } while (--frameCount);
1560 }
1561 }
1562 t->in = in;
1563}
1564
Mathias Agopian65ab4712010-07-14 17:59:35 -07001565// no-op case
John Grossman4ff14ba2012-02-08 16:37:41 -08001566void AudioMixer::process__nop(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001567{
Andy Hung296b7412014-06-17 15:25:47 -07001568 ALOGVV("process__nop\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001569 uint32_t e0 = state->enabledTracks;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001570 while (e0) {
1571 // process by group of tracks with same output buffer to
1572 // avoid multiple memset() on same buffer
1573 uint32_t e1 = e0, e2 = e0;
1574 int i = 31 - __builtin_clz(e1);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001575 {
1576 track_t& t1 = state->tracks[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001577 e2 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001578 while (e2) {
1579 i = 31 - __builtin_clz(e2);
1580 e2 &= ~(1<<i);
1581 track_t& t2 = state->tracks[i];
1582 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1583 e1 &= ~(1<<i);
1584 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001585 }
Glenn Kastenfc900c92013-02-18 12:47:49 -08001586 e0 &= ~(e1);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001587
Andy Hunge93b6b72014-07-17 21:30:53 -07001588 memset(t1.mainBuffer, 0, state->frameCount * t1.mMixerChannelCount
Andy Hung78820702014-02-28 16:23:02 -08001589 * audio_bytes_per_sample(t1.mMixerFormat));
Glenn Kastenfc900c92013-02-18 12:47:49 -08001590 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001591
1592 while (e1) {
1593 i = 31 - __builtin_clz(e1);
1594 e1 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001595 {
1596 track_t& t3 = state->tracks[i];
1597 size_t outFrames = state->frameCount;
1598 while (outFrames) {
1599 t3.buffer.frameCount = outFrames;
1600 int64_t outputPTS = calculateOutputPTS(
1601 t3, pts, state->frameCount - outFrames);
1602 t3.bufferProvider->getNextBuffer(&t3.buffer, outputPTS);
1603 if (t3.buffer.raw == NULL) break;
1604 outFrames -= t3.buffer.frameCount;
1605 t3.bufferProvider->releaseBuffer(&t3.buffer);
1606 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001607 }
1608 }
1609 }
1610}
1611
1612// generic code without resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001613void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001614{
Andy Hung296b7412014-06-17 15:25:47 -07001615 ALOGVV("process__genericNoResampling\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001616 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1617
1618 // acquire each track's buffer
1619 uint32_t enabledTracks = state->enabledTracks;
1620 uint32_t e0 = enabledTracks;
1621 while (e0) {
1622 const int i = 31 - __builtin_clz(e0);
1623 e0 &= ~(1<<i);
1624 track_t& t = state->tracks[i];
1625 t.buffer.frameCount = state->frameCount;
John Grossman4ff14ba2012-02-08 16:37:41 -08001626 t.bufferProvider->getNextBuffer(&t.buffer, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001627 t.frameCount = t.buffer.frameCount;
1628 t.in = t.buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001629 }
1630
1631 e0 = enabledTracks;
1632 while (e0) {
1633 // process by group of tracks with same output buffer to
1634 // optimize cache use
1635 uint32_t e1 = e0, e2 = e0;
1636 int j = 31 - __builtin_clz(e1);
1637 track_t& t1 = state->tracks[j];
1638 e2 &= ~(1<<j);
1639 while (e2) {
1640 j = 31 - __builtin_clz(e2);
1641 e2 &= ~(1<<j);
1642 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001643 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001644 e1 &= ~(1<<j);
1645 }
1646 }
1647 e0 &= ~(e1);
1648 // this assumes output 16 bits stereo, no resampling
1649 int32_t *out = t1.mainBuffer;
1650 size_t numFrames = 0;
1651 do {
1652 memset(outTemp, 0, sizeof(outTemp));
1653 e2 = e1;
1654 while (e2) {
1655 const int i = 31 - __builtin_clz(e2);
1656 e2 &= ~(1<<i);
1657 track_t& t = state->tracks[i];
1658 size_t outFrames = BLOCKSIZE;
1659 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001660 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001661 aux = t.auxBuffer + numFrames;
1662 }
1663 while (outFrames) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301664 // t.in == NULL can happen if the track was flushed just after having
1665 // been enabled for mixing.
1666 if (t.in == NULL) {
1667 enabledTracks &= ~(1<<i);
1668 e1 &= ~(1<<i);
1669 break;
1670 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001671 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001672 if (inFrames > 0) {
Andy Hunge93b6b72014-07-17 21:30:53 -07001673 t.hook(&t, outTemp + (BLOCKSIZE - outFrames) * t.mMixerChannelCount,
1674 inFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001675 t.frameCount -= inFrames;
1676 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001677 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001678 aux += inFrames;
1679 }
1680 }
1681 if (t.frameCount == 0 && outFrames) {
1682 t.bufferProvider->releaseBuffer(&t.buffer);
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001683 t.buffer.frameCount = (state->frameCount - numFrames) -
1684 (BLOCKSIZE - outFrames);
John Grossman4ff14ba2012-02-08 16:37:41 -08001685 int64_t outputPTS = calculateOutputPTS(
1686 t, pts, numFrames + (BLOCKSIZE - outFrames));
1687 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001688 t.in = t.buffer.raw;
1689 if (t.in == NULL) {
1690 enabledTracks &= ~(1<<i);
1691 e1 &= ~(1<<i);
1692 break;
1693 }
1694 t.frameCount = t.buffer.frameCount;
1695 }
1696 }
1697 }
Andy Hung296b7412014-06-17 15:25:47 -07001698
1699 convertMixerFormat(out, t1.mMixerFormat, outTemp, t1.mMixerInFormat,
Andy Hunge93b6b72014-07-17 21:30:53 -07001700 BLOCKSIZE * t1.mMixerChannelCount);
Andy Hung296b7412014-06-17 15:25:47 -07001701 // TODO: fix ugly casting due to choice of out pointer type
1702 out = reinterpret_cast<int32_t*>((uint8_t*)out
Andy Hunge93b6b72014-07-17 21:30:53 -07001703 + BLOCKSIZE * t1.mMixerChannelCount
1704 * audio_bytes_per_sample(t1.mMixerFormat));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001705 numFrames += BLOCKSIZE;
1706 } while (numFrames < state->frameCount);
1707 }
1708
1709 // release each track's buffer
1710 e0 = enabledTracks;
1711 while (e0) {
1712 const int i = 31 - __builtin_clz(e0);
1713 e0 &= ~(1<<i);
1714 track_t& t = state->tracks[i];
1715 t.bufferProvider->releaseBuffer(&t.buffer);
1716 }
1717}
1718
1719
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001720// generic code with resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001721void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001722{
Andy Hung296b7412014-06-17 15:25:47 -07001723 ALOGVV("process__genericResampling\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001724 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -07001725 int32_t* const outTemp = state->outputTemp;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001726 size_t numFrames = state->frameCount;
1727
1728 uint32_t e0 = state->enabledTracks;
1729 while (e0) {
1730 // process by group of tracks with same output buffer
1731 // to optimize cache use
1732 uint32_t e1 = e0, e2 = e0;
1733 int j = 31 - __builtin_clz(e1);
1734 track_t& t1 = state->tracks[j];
1735 e2 &= ~(1<<j);
1736 while (e2) {
1737 j = 31 - __builtin_clz(e2);
1738 e2 &= ~(1<<j);
1739 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001740 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001741 e1 &= ~(1<<j);
1742 }
1743 }
1744 e0 &= ~(e1);
1745 int32_t *out = t1.mainBuffer;
Andy Hunge93b6b72014-07-17 21:30:53 -07001746 memset(outTemp, 0, sizeof(*outTemp) * t1.mMixerChannelCount * state->frameCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001747 while (e1) {
1748 const int i = 31 - __builtin_clz(e1);
1749 e1 &= ~(1<<i);
1750 track_t& t = state->tracks[i];
1751 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001752 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001753 aux = t.auxBuffer;
1754 }
1755
1756 // this is a little goofy, on the resampling case we don't
1757 // acquire/release the buffers because it's done by
1758 // the resampler.
Glenn Kastend6fadf02013-10-30 14:37:29 -07001759 if (t.needs & NEEDS_RESAMPLE) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001760 t.resampler->setPTS(pts);
Glenn Kastena1117922012-01-26 10:53:32 -08001761 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001762 } else {
1763
1764 size_t outFrames = 0;
1765
1766 while (outFrames < numFrames) {
1767 t.buffer.frameCount = numFrames - outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001768 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
1769 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001770 t.in = t.buffer.raw;
1771 // t.in == NULL can happen if the track was flushed just after having
1772 // been enabled for mixing.
1773 if (t.in == NULL) break;
1774
Glenn Kastenf6b16782011-12-15 09:51:17 -08001775 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001776 aux += outFrames;
1777 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001778 t.hook(&t, outTemp + outFrames * t.mMixerChannelCount, t.buffer.frameCount,
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001779 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001780 outFrames += t.buffer.frameCount;
1781 t.bufferProvider->releaseBuffer(&t.buffer);
1782 }
1783 }
1784 }
Andy Hunge93b6b72014-07-17 21:30:53 -07001785 convertMixerFormat(out, t1.mMixerFormat,
1786 outTemp, t1.mMixerInFormat, numFrames * t1.mMixerChannelCount);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001787 }
1788}
1789
1790// one track, 16 bits stereo without resampling is the most common case
John Grossman4ff14ba2012-02-08 16:37:41 -08001791void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
1792 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001793{
Andy Hung296b7412014-06-17 15:25:47 -07001794 ALOGVV("process__OneTrack16BitsStereoNoResampling\n");
Glenn Kasten99e53b82012-01-19 08:59:58 -08001795 // This method is only called when state->enabledTracks has exactly
1796 // one bit set. The asserts below would verify this, but are commented out
1797 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001798 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001799 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001800 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001801 const track_t& t = state->tracks[i];
1802
1803 AudioBufferProvider::Buffer& b(t.buffer);
1804
1805 int32_t* out = t.mainBuffer;
Andy Hungf8a106a2014-05-29 18:52:38 -07001806 float *fout = reinterpret_cast<float*>(out);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001807 size_t numFrames = state->frameCount;
1808
1809 const int16_t vl = t.volume[0];
1810 const int16_t vr = t.volume[1];
1811 const uint32_t vrl = t.volumeRL;
1812 while (numFrames) {
1813 b.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001814 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
1815 t.bufferProvider->getNextBuffer(&b, outputPTS);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001816 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001817
1818 // in == NULL can happen if the track was flushed just after having
1819 // been enabled for mixing.
Andy Hungf8a106a2014-05-29 18:52:38 -07001820 if (in == NULL || (((uintptr_t)in) & 3)) {
1821 memset(out, 0, numFrames
Andy Hunge93b6b72014-07-17 21:30:53 -07001822 * t.mMixerChannelCount * audio_bytes_per_sample(t.mMixerFormat));
Andy Hung395db4b2014-08-25 17:15:29 -07001823 ALOGE_IF((((uintptr_t)in) & 3),
1824 "process__OneTrack16BitsStereoNoResampling: misaligned buffer"
1825 " %p track %d, channels %d, needs %08x, volume %08x vfl %f vfr %f",
1826 in, i, t.channelCount, t.needs, vrl, t.mVolume[0], t.mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001827 return;
1828 }
1829 size_t outFrames = b.frameCount;
1830
Andy Hung78820702014-02-28 16:23:02 -08001831 switch (t.mMixerFormat) {
Andy Hungf8a106a2014-05-29 18:52:38 -07001832 case AUDIO_FORMAT_PCM_FLOAT:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001833 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001834 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001835 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001836 int32_t l = mulRL(1, rl, vrl);
1837 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001838 *fout++ = float_from_q4_27(l);
1839 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001840 // Note: In case of later int16_t sink output,
1841 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001842 } while (--outFrames);
Andy Hungf8a106a2014-05-29 18:52:38 -07001843 break;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001844 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung97ae8242014-05-30 10:35:47 -07001845 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001846 // volume is boosted, so we might need to clamp even though
1847 // we process only one track.
1848 do {
1849 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1850 in += 2;
1851 int32_t l = mulRL(1, rl, vrl) >> 12;
1852 int32_t r = mulRL(0, rl, vrl) >> 12;
1853 // clamping...
1854 l = clamp16(l);
1855 r = clamp16(r);
1856 *out++ = (r<<16) | (l & 0xFFFF);
1857 } while (--outFrames);
1858 } else {
1859 do {
1860 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1861 in += 2;
1862 int32_t l = mulRL(1, rl, vrl) >> 12;
1863 int32_t r = mulRL(0, rl, vrl) >> 12;
1864 *out++ = (r<<16) | (l & 0xFFFF);
1865 } while (--outFrames);
1866 }
1867 break;
1868 default:
Andy Hung78820702014-02-28 16:23:02 -08001869 LOG_ALWAYS_FATAL("bad mixer format: %d", t.mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001870 }
1871 numFrames -= b.frameCount;
1872 t.bufferProvider->releaseBuffer(&b);
1873 }
1874}
1875
John Grossman4ff14ba2012-02-08 16:37:41 -08001876int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1877 int outputFrameIndex)
1878{
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001879 if (AudioBufferProvider::kInvalidPTS == basePTS) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001880 return AudioBufferProvider::kInvalidPTS;
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001881 }
John Grossman4ff14ba2012-02-08 16:37:41 -08001882
Glenn Kasten52008f82012-03-18 09:34:41 -07001883 return basePTS + ((outputFrameIndex * sLocalTimeFreq) / t.sampleRate);
1884}
1885
1886/*static*/ uint64_t AudioMixer::sLocalTimeFreq;
1887/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1888
1889/*static*/ void AudioMixer::sInitRoutine()
1890{
1891 LocalClock lc;
Andy Hung34803d52014-07-16 21:41:35 -07001892 sLocalTimeFreq = lc.getLocalFreq(); // for the resampler
Glenn Kasten49c34ac2013-10-30 14:37:01 -07001893
Andy Hung34803d52014-07-16 21:41:35 -07001894 DownmixerBufferProvider::init(); // for the downmixer
John Grossman4ff14ba2012-02-08 16:37:41 -08001895}
1896
Andy Hunge93b6b72014-07-17 21:30:53 -07001897/* TODO: consider whether this level of optimization is necessary.
1898 * Perhaps just stick with a single for loop.
1899 */
1900
1901// Needs to derive a compile time constant (constexpr). Could be targeted to go
1902// to a MONOVOL mixtype based on MAX_NUM_VOLUMES, but that's an unnecessary complication.
1903#define MIXTYPE_MONOVOL(mixtype) (mixtype == MIXTYPE_MULTI ? MIXTYPE_MULTI_MONOVOL : \
1904 mixtype == MIXTYPE_MULTI_SAVEONLY ? MIXTYPE_MULTI_SAVEONLY_MONOVOL : mixtype)
1905
1906/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1907 * TO: int32_t (Q4.27) or float
1908 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1909 * TA: int32_t (Q4.27)
1910 */
1911template <int MIXTYPE,
1912 typename TO, typename TI, typename TV, typename TA, typename TAV>
1913static void volumeRampMulti(uint32_t channels, TO* out, size_t frameCount,
1914 const TI* in, TA* aux, TV *vol, const TV *volinc, TAV *vola, TAV volainc)
1915{
1916 switch (channels) {
1917 case 1:
1918 volumeRampMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1919 break;
1920 case 2:
1921 volumeRampMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, volinc, vola, volainc);
1922 break;
1923 case 3:
1924 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out,
1925 frameCount, in, aux, vol, volinc, vola, volainc);
1926 break;
1927 case 4:
1928 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out,
1929 frameCount, in, aux, vol, volinc, vola, volainc);
1930 break;
1931 case 5:
1932 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out,
1933 frameCount, in, aux, vol, volinc, vola, volainc);
1934 break;
1935 case 6:
1936 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out,
1937 frameCount, in, aux, vol, volinc, vola, volainc);
1938 break;
1939 case 7:
1940 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out,
1941 frameCount, in, aux, vol, volinc, vola, volainc);
1942 break;
1943 case 8:
1944 volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out,
1945 frameCount, in, aux, vol, volinc, vola, volainc);
1946 break;
1947 }
1948}
1949
1950/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1951 * TO: int32_t (Q4.27) or float
1952 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1953 * TA: int32_t (Q4.27)
1954 */
1955template <int MIXTYPE,
1956 typename TO, typename TI, typename TV, typename TA, typename TAV>
1957static void volumeMulti(uint32_t channels, TO* out, size_t frameCount,
1958 const TI* in, TA* aux, const TV *vol, TAV vola)
1959{
1960 switch (channels) {
1961 case 1:
1962 volumeMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, vola);
1963 break;
1964 case 2:
1965 volumeMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, vola);
1966 break;
1967 case 3:
1968 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out, frameCount, in, aux, vol, vola);
1969 break;
1970 case 4:
1971 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out, frameCount, in, aux, vol, vola);
1972 break;
1973 case 5:
1974 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out, frameCount, in, aux, vol, vola);
1975 break;
1976 case 6:
1977 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out, frameCount, in, aux, vol, vola);
1978 break;
1979 case 7:
1980 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out, frameCount, in, aux, vol, vola);
1981 break;
1982 case 8:
1983 volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out, frameCount, in, aux, vol, vola);
1984 break;
1985 }
1986}
1987
1988/* MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
1989 * USEFLOATVOL (set to true if float volume is used)
1990 * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards)
1991 * TO: int32_t (Q4.27) or float
1992 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
1993 * TA: int32_t (Q4.27)
1994 */
1995template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
Andy Hung5e58b0a2014-06-23 19:07:29 -07001996 typename TO, typename TI, typename TA>
1997void AudioMixer::volumeMix(TO *out, size_t outFrames,
1998 const TI *in, TA *aux, bool ramp, AudioMixer::track_t *t)
1999{
2000 if (USEFLOATVOL) {
2001 if (ramp) {
Andy Hunge93b6b72014-07-17 21:30:53 -07002002 volumeRampMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07002003 t->mPrevVolume, t->mVolumeInc, &t->prevAuxLevel, t->auxInc);
2004 if (ADJUSTVOL) {
2005 t->adjustVolumeRamp(aux != NULL, true);
2006 }
2007 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -07002008 volumeMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07002009 t->mVolume, t->auxLevel);
2010 }
2011 } else {
2012 if (ramp) {
Andy Hunge93b6b72014-07-17 21:30:53 -07002013 volumeRampMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07002014 t->prevVolume, t->volumeInc, &t->prevAuxLevel, t->auxInc);
2015 if (ADJUSTVOL) {
2016 t->adjustVolumeRamp(aux != NULL);
2017 }
2018 } else {
Andy Hunge93b6b72014-07-17 21:30:53 -07002019 volumeMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
Andy Hung5e58b0a2014-06-23 19:07:29 -07002020 t->volume, t->auxLevel);
2021 }
2022 }
2023}
2024
Andy Hung296b7412014-06-17 15:25:47 -07002025/* This process hook is called when there is a single track without
2026 * aux buffer, volume ramp, or resampling.
2027 * TODO: Update the hook selection: this can properly handle aux and ramp.
Andy Hunge93b6b72014-07-17 21:30:53 -07002028 *
2029 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
2030 * TO: int32_t (Q4.27) or float
2031 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
2032 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07002033 */
Andy Hunge93b6b72014-07-17 21:30:53 -07002034template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung296b7412014-06-17 15:25:47 -07002035void AudioMixer::process_NoResampleOneTrack(state_t* state, int64_t pts)
2036{
2037 ALOGVV("process_NoResampleOneTrack\n");
2038 // CLZ is faster than CTZ on ARM, though really not sure if true after 31 - clz.
2039 const int i = 31 - __builtin_clz(state->enabledTracks);
2040 ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
2041 track_t *t = &state->tracks[i];
Andy Hunge93b6b72014-07-17 21:30:53 -07002042 const uint32_t channels = t->mMixerChannelCount;
Andy Hung296b7412014-06-17 15:25:47 -07002043 TO* out = reinterpret_cast<TO*>(t->mainBuffer);
2044 TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
2045 const bool ramp = t->needsRamp();
2046
2047 for (size_t numFrames = state->frameCount; numFrames; ) {
2048 AudioBufferProvider::Buffer& b(t->buffer);
2049 // get input buffer
2050 b.frameCount = numFrames;
2051 const int64_t outputPTS = calculateOutputPTS(*t, pts, state->frameCount - numFrames);
2052 t->bufferProvider->getNextBuffer(&b, outputPTS);
2053 const TI *in = reinterpret_cast<TI*>(b.raw);
2054
2055 // in == NULL can happen if the track was flushed just after having
2056 // been enabled for mixing.
2057 if (in == NULL || (((uintptr_t)in) & 3)) {
2058 memset(out, 0, numFrames
Andy Hunge93b6b72014-07-17 21:30:53 -07002059 * channels * audio_bytes_per_sample(t->mMixerFormat));
Andy Hung296b7412014-06-17 15:25:47 -07002060 ALOGE_IF((((uintptr_t)in) & 3), "process_NoResampleOneTrack: bus error: "
2061 "buffer %p track %p, channels %d, needs %#x",
2062 in, t, t->channelCount, t->needs);
2063 return;
2064 }
2065
2066 const size_t outFrames = b.frameCount;
Andy Hunge93b6b72014-07-17 21:30:53 -07002067 volumeMix<MIXTYPE, is_same<TI, float>::value, false> (
2068 out, outFrames, in, aux, ramp, t);
Andy Hung5e58b0a2014-06-23 19:07:29 -07002069
Andy Hunge93b6b72014-07-17 21:30:53 -07002070 out += outFrames * channels;
Andy Hung296b7412014-06-17 15:25:47 -07002071 if (aux != NULL) {
Andy Hunge93b6b72014-07-17 21:30:53 -07002072 aux += channels;
Andy Hung296b7412014-06-17 15:25:47 -07002073 }
2074 numFrames -= b.frameCount;
2075
2076 // release buffer
2077 t->bufferProvider->releaseBuffer(&b);
2078 }
2079 if (ramp) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07002080 t->adjustVolumeRamp(aux != NULL, is_same<TI, float>::value);
Andy Hung296b7412014-06-17 15:25:47 -07002081 }
2082}
2083
2084/* This track hook is called to do resampling then mixing,
2085 * pulling from the track's upstream AudioBufferProvider.
Andy Hunge93b6b72014-07-17 21:30:53 -07002086 *
2087 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
2088 * TO: int32_t (Q4.27) or float
2089 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
2090 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07002091 */
Andy Hunge93b6b72014-07-17 21:30:53 -07002092template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung296b7412014-06-17 15:25:47 -07002093void AudioMixer::track__Resample(track_t* t, TO* out, size_t outFrameCount, TO* temp, TA* aux)
2094{
2095 ALOGVV("track__Resample\n");
2096 t->resampler->setSampleRate(t->sampleRate);
Andy Hung296b7412014-06-17 15:25:47 -07002097 const bool ramp = t->needsRamp();
2098 if (ramp || aux != NULL) {
2099 // if ramp: resample with unity gain to temp buffer and scale/mix in 2nd step.
2100 // if aux != NULL: resample with unity gain to temp buffer then apply send level.
2101
Andy Hung5e58b0a2014-06-23 19:07:29 -07002102 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Andy Hunge93b6b72014-07-17 21:30:53 -07002103 memset(temp, 0, outFrameCount * t->mMixerChannelCount * sizeof(TO));
Andy Hung296b7412014-06-17 15:25:47 -07002104 t->resampler->resample((int32_t*)temp, outFrameCount, t->bufferProvider);
Andy Hung5e58b0a2014-06-23 19:07:29 -07002105
Andy Hunge93b6b72014-07-17 21:30:53 -07002106 volumeMix<MIXTYPE, is_same<TI, float>::value, true>(
2107 out, outFrameCount, temp, aux, ramp, t);
Andy Hung5e58b0a2014-06-23 19:07:29 -07002108
Andy Hung296b7412014-06-17 15:25:47 -07002109 } else { // constant volume gain
Andy Hung5e58b0a2014-06-23 19:07:29 -07002110 t->resampler->setVolume(t->mVolume[0], t->mVolume[1]);
Andy Hung296b7412014-06-17 15:25:47 -07002111 t->resampler->resample((int32_t*)out, outFrameCount, t->bufferProvider);
2112 }
2113}
2114
2115/* This track hook is called to mix a track, when no resampling is required.
2116 * The input buffer should be present in t->in.
Andy Hunge93b6b72014-07-17 21:30:53 -07002117 *
2118 * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
2119 * TO: int32_t (Q4.27) or float
2120 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
2121 * TA: int32_t (Q4.27)
Andy Hung296b7412014-06-17 15:25:47 -07002122 */
Andy Hunge93b6b72014-07-17 21:30:53 -07002123template <int MIXTYPE, typename TO, typename TI, typename TA>
Andy Hung296b7412014-06-17 15:25:47 -07002124void AudioMixer::track__NoResample(track_t* t, TO* out, size_t frameCount,
2125 TO* temp __unused, TA* aux)
2126{
2127 ALOGVV("track__NoResample\n");
2128 const TI *in = static_cast<const TI *>(t->in);
2129
Andy Hunge93b6b72014-07-17 21:30:53 -07002130 volumeMix<MIXTYPE, is_same<TI, float>::value, true>(
2131 out, frameCount, in, aux, t->needsRamp(), t);
Andy Hung5e58b0a2014-06-23 19:07:29 -07002132
Andy Hung296b7412014-06-17 15:25:47 -07002133 // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
2134 // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
Andy Hunge93b6b72014-07-17 21:30:53 -07002135 in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * t->mMixerChannelCount;
Andy Hung296b7412014-06-17 15:25:47 -07002136 t->in = in;
2137}
2138
2139/* The Mixer engine generates either int32_t (Q4_27) or float data.
2140 * We use this function to convert the engine buffers
2141 * to the desired mixer output format, either int16_t (Q.15) or float.
2142 */
2143void AudioMixer::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
2144 void *in, audio_format_t mixerInFormat, size_t sampleCount)
2145{
2146 switch (mixerInFormat) {
2147 case AUDIO_FORMAT_PCM_FLOAT:
2148 switch (mixerOutFormat) {
2149 case AUDIO_FORMAT_PCM_FLOAT:
2150 memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
2151 break;
2152 case AUDIO_FORMAT_PCM_16_BIT:
2153 memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
2154 break;
2155 default:
2156 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2157 break;
2158 }
2159 break;
2160 case AUDIO_FORMAT_PCM_16_BIT:
2161 switch (mixerOutFormat) {
2162 case AUDIO_FORMAT_PCM_FLOAT:
2163 memcpy_to_float_from_q4_27((float*)out, (int32_t*)in, sampleCount);
2164 break;
2165 case AUDIO_FORMAT_PCM_16_BIT:
2166 // two int16_t are produced per iteration
2167 ditherAndClamp((int32_t*)out, (int32_t*)in, sampleCount >> 1);
2168 break;
2169 default:
2170 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2171 break;
2172 }
2173 break;
2174 default:
2175 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2176 break;
2177 }
2178}
2179
2180/* Returns the proper track hook to use for mixing the track into the output buffer.
2181 */
Andy Hunge93b6b72014-07-17 21:30:53 -07002182AudioMixer::hook_t AudioMixer::getTrackHook(int trackType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07002183 audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
2184{
Andy Hunge93b6b72014-07-17 21:30:53 -07002185 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung296b7412014-06-17 15:25:47 -07002186 switch (trackType) {
2187 case TRACKTYPE_NOP:
2188 return track__nop;
2189 case TRACKTYPE_RESAMPLE:
2190 return track__genericResample;
2191 case TRACKTYPE_NORESAMPLEMONO:
2192 return track__16BitsMono;
2193 case TRACKTYPE_NORESAMPLE:
2194 return track__16BitsStereo;
2195 default:
2196 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
2197 break;
2198 }
2199 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002200 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07002201 switch (trackType) {
2202 case TRACKTYPE_NOP:
2203 return track__nop;
2204 case TRACKTYPE_RESAMPLE:
2205 switch (mixerInFormat) {
2206 case AUDIO_FORMAT_PCM_FLOAT:
2207 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07002208 track__Resample<MIXTYPE_MULTI, float /*TO*/, float /*TI*/, int32_t /*TA*/>;
Andy Hung296b7412014-06-17 15:25:47 -07002209 case AUDIO_FORMAT_PCM_16_BIT:
2210 return (AudioMixer::hook_t)\
Andy Hunge93b6b72014-07-17 21:30:53 -07002211 track__Resample<MIXTYPE_MULTI, int32_t, int16_t, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07002212 default:
2213 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2214 break;
2215 }
2216 break;
2217 case TRACKTYPE_NORESAMPLEMONO:
2218 switch (mixerInFormat) {
2219 case AUDIO_FORMAT_PCM_FLOAT:
2220 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07002221 track__NoResample<MIXTYPE_MONOEXPAND, float, float, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07002222 case AUDIO_FORMAT_PCM_16_BIT:
2223 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07002224 track__NoResample<MIXTYPE_MONOEXPAND, int32_t, int16_t, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07002225 default:
2226 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2227 break;
2228 }
2229 break;
2230 case TRACKTYPE_NORESAMPLE:
2231 switch (mixerInFormat) {
2232 case AUDIO_FORMAT_PCM_FLOAT:
2233 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07002234 track__NoResample<MIXTYPE_MULTI, float, float, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07002235 case AUDIO_FORMAT_PCM_16_BIT:
2236 return (AudioMixer::hook_t)
Andy Hunge93b6b72014-07-17 21:30:53 -07002237 track__NoResample<MIXTYPE_MULTI, int32_t, int16_t, int32_t>;
Andy Hung296b7412014-06-17 15:25:47 -07002238 default:
2239 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2240 break;
2241 }
2242 break;
2243 default:
2244 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
2245 break;
2246 }
2247 return NULL;
2248}
2249
2250/* Returns the proper process hook for mixing tracks. Currently works only for
2251 * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
Andy Hung395db4b2014-08-25 17:15:29 -07002252 *
2253 * TODO: Due to the special mixing considerations of duplicating to
2254 * a stereo output track, the input track cannot be MONO. This should be
2255 * prevented by the caller.
Andy Hung296b7412014-06-17 15:25:47 -07002256 */
Andy Hunge93b6b72014-07-17 21:30:53 -07002257AudioMixer::process_hook_t AudioMixer::getProcessHook(int processType, uint32_t channelCount,
Andy Hung296b7412014-06-17 15:25:47 -07002258 audio_format_t mixerInFormat, audio_format_t mixerOutFormat)
2259{
2260 if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
2261 LOG_ALWAYS_FATAL("bad processType: %d", processType);
2262 return NULL;
2263 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002264 if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
Andy Hung296b7412014-06-17 15:25:47 -07002265 return process__OneTrack16BitsStereoNoResampling;
2266 }
Andy Hunge93b6b72014-07-17 21:30:53 -07002267 LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
Andy Hung296b7412014-06-17 15:25:47 -07002268 switch (mixerInFormat) {
2269 case AUDIO_FORMAT_PCM_FLOAT:
2270 switch (mixerOutFormat) {
2271 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hunge93b6b72014-07-17 21:30:53 -07002272 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
2273 float /*TO*/, float /*TI*/, int32_t /*TA*/>;
Andy Hung296b7412014-06-17 15:25:47 -07002274 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hunge93b6b72014-07-17 21:30:53 -07002275 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
Andy Hung296b7412014-06-17 15:25:47 -07002276 int16_t, float, int32_t>;
2277 default:
2278 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2279 break;
2280 }
2281 break;
2282 case AUDIO_FORMAT_PCM_16_BIT:
2283 switch (mixerOutFormat) {
2284 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hunge93b6b72014-07-17 21:30:53 -07002285 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
Andy Hung296b7412014-06-17 15:25:47 -07002286 float, int16_t, int32_t>;
2287 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hunge93b6b72014-07-17 21:30:53 -07002288 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
Andy Hung296b7412014-06-17 15:25:47 -07002289 int16_t, int16_t, int32_t>;
2290 default:
2291 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2292 break;
2293 }
2294 break;
2295 default:
2296 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2297 break;
2298 }
2299 return NULL;
2300}
2301
Mathias Agopian65ab4712010-07-14 17:59:35 -07002302// ----------------------------------------------------------------------------
Glenn Kasten63238ef2015-03-02 15:50:29 -08002303} // namespace android