blob: ba135c6d5ebd1f75ebf900f9f595a0ad73aa7a7e [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>
43
Andy Hung296b7412014-06-17 15:25:47 -070044#include "AudioMixerOps.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070045#include "AudioMixer.h"
46
Andy Hung296b7412014-06-17 15:25:47 -070047// Use the FCC_2 macro for code assuming Fixed Channel Count of 2 and
48// whose stereo assumption may need to be revisited later.
49#ifndef FCC_2
50#define FCC_2 2
51#endif
52
53/* VERY_VERY_VERBOSE_LOGGING will show exactly which process hook and track hook is
54 * being used. This is a considerable amount of log spam, so don't enable unless you
55 * are verifying the hook based code.
56 */
57//#define VERY_VERY_VERBOSE_LOGGING
58#ifdef VERY_VERY_VERBOSE_LOGGING
59#define ALOGVV ALOGV
60//define ALOGVV printf // for test-mixer.cpp
61#else
62#define ALOGVV(a...) do { } while (0)
63#endif
64
65// Set kUseNewMixer to true to use the new mixer engine. Otherwise the
66// original code will be used. This is false for now.
67static const bool kUseNewMixer = false;
68
69// Set kUseFloat to true to allow floating input into the mixer engine.
70// If kUseNewMixer is false, this is ignored or may be overridden internally
71// because of downmix/upmix support.
72static const bool kUseFloat = true;
73
Andy Hung1b2fdcb2014-07-16 17:44:34 -070074// Set to default copy buffer size in frames for input processing.
75static const size_t kCopyBufferFrameCount = 256;
76
Mathias Agopian65ab4712010-07-14 17:59:35 -070077namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070078
79// ----------------------------------------------------------------------------
Andy Hung1b2fdcb2014-07-16 17:44:34 -070080
81template <typename T>
82T min(const T& a, const T& b)
83{
84 return a < b ? a : b;
85}
86
87AudioMixer::CopyBufferProvider::CopyBufferProvider(size_t inputFrameSize,
88 size_t outputFrameSize, size_t bufferFrameCount) :
89 mInputFrameSize(inputFrameSize),
90 mOutputFrameSize(outputFrameSize),
91 mLocalBufferFrameCount(bufferFrameCount),
92 mLocalBufferData(NULL),
93 mConsumed(0)
94{
95 ALOGV("CopyBufferProvider(%p)(%zu, %zu, %zu)", this,
96 inputFrameSize, outputFrameSize, bufferFrameCount);
97 LOG_ALWAYS_FATAL_IF(inputFrameSize < outputFrameSize && bufferFrameCount == 0,
98 "Requires local buffer if inputFrameSize(%d) < outputFrameSize(%d)",
99 inputFrameSize, outputFrameSize);
100 if (mLocalBufferFrameCount) {
101 (void)posix_memalign(&mLocalBufferData, 32, mLocalBufferFrameCount * mOutputFrameSize);
102 }
103 mBuffer.frameCount = 0;
104}
105
106AudioMixer::CopyBufferProvider::~CopyBufferProvider()
107{
108 ALOGV("~CopyBufferProvider(%p)", this);
109 if (mBuffer.frameCount != 0) {
110 mTrackBufferProvider->releaseBuffer(&mBuffer);
111 }
112 free(mLocalBufferData);
113}
114
115status_t AudioMixer::CopyBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer,
116 int64_t pts)
117{
118 //ALOGV("CopyBufferProvider(%p)::getNextBuffer(%p (%zu), %lld)",
119 // this, pBuffer, pBuffer->frameCount, pts);
120 if (mLocalBufferFrameCount == 0) {
121 status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts);
122 if (res == OK) {
123 copyFrames(pBuffer->raw, pBuffer->raw, pBuffer->frameCount);
124 }
125 return res;
126 }
127 if (mBuffer.frameCount == 0) {
128 mBuffer.frameCount = pBuffer->frameCount;
129 status_t res = mTrackBufferProvider->getNextBuffer(&mBuffer, pts);
130 // At one time an upstream buffer provider had
131 // res == OK and mBuffer.frameCount == 0, doesn't seem to happen now 7/18/2014.
132 //
133 // By API spec, if res != OK, then mBuffer.frameCount == 0.
134 // but there may be improper implementations.
135 ALOG_ASSERT(res == OK || mBuffer.frameCount == 0);
136 if (res != OK || mBuffer.frameCount == 0) { // not needed by API spec, but to be safe.
137 pBuffer->raw = NULL;
138 pBuffer->frameCount = 0;
139 return res;
140 }
141 mConsumed = 0;
142 }
143 ALOG_ASSERT(mConsumed < mBuffer.frameCount);
144 size_t count = min(mLocalBufferFrameCount, mBuffer.frameCount - mConsumed);
145 count = min(count, pBuffer->frameCount);
146 pBuffer->raw = mLocalBufferData;
147 pBuffer->frameCount = count;
148 copyFrames(pBuffer->raw, (uint8_t*)mBuffer.raw + mConsumed * mInputFrameSize,
149 pBuffer->frameCount);
150 return OK;
151}
152
153void AudioMixer::CopyBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer)
154{
155 //ALOGV("CopyBufferProvider(%p)::releaseBuffer(%p(%zu))",
156 // this, pBuffer, pBuffer->frameCount);
157 if (mLocalBufferFrameCount == 0) {
158 mTrackBufferProvider->releaseBuffer(pBuffer);
159 return;
160 }
161 // LOG_ALWAYS_FATAL_IF(pBuffer->frameCount == 0, "Invalid framecount");
162 mConsumed += pBuffer->frameCount; // TODO: update for efficiency to reuse existing content
163 if (mConsumed != 0 && mConsumed >= mBuffer.frameCount) {
164 mTrackBufferProvider->releaseBuffer(&mBuffer);
165 ALOG_ASSERT(mBuffer.frameCount == 0);
166 }
167 pBuffer->raw = NULL;
168 pBuffer->frameCount = 0;
169}
170
171void AudioMixer::CopyBufferProvider::reset()
172{
173 if (mBuffer.frameCount != 0) {
174 mTrackBufferProvider->releaseBuffer(&mBuffer);
175 }
176 mConsumed = 0;
177}
178
Andy Hung34803d52014-07-16 21:41:35 -0700179AudioMixer::DownmixerBufferProvider::DownmixerBufferProvider(
180 audio_channel_mask_t inputChannelMask,
181 audio_channel_mask_t outputChannelMask, audio_format_t format,
182 uint32_t sampleRate, int32_t sessionId, size_t bufferFrameCount) :
183 CopyBufferProvider(
184 audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(inputChannelMask),
185 audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(outputChannelMask),
186 bufferFrameCount) // set bufferFrameCount to 0 to do in-place
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700187{
Andy Hung34803d52014-07-16 21:41:35 -0700188 ALOGV("DownmixerBufferProvider(%p)(%#x, %#x, %#x %u %d)",
189 this, inputChannelMask, outputChannelMask, format,
190 sampleRate, sessionId);
191 if (!sIsMultichannelCapable
192 || EffectCreate(&sDwnmFxDesc.uuid,
193 sessionId,
194 SESSION_ID_INVALID_AND_IGNORED,
195 &mDownmixHandle) != 0) {
196 ALOGE("DownmixerBufferProvider() error creating downmixer effect");
197 mDownmixHandle = NULL;
198 return;
199 }
200 // channel input configuration will be overridden per-track
201 mDownmixConfig.inputCfg.channels = inputChannelMask; // FIXME: Should be bits
202 mDownmixConfig.outputCfg.channels = outputChannelMask; // FIXME: should be bits
203 mDownmixConfig.inputCfg.format = format;
204 mDownmixConfig.outputCfg.format = format;
205 mDownmixConfig.inputCfg.samplingRate = sampleRate;
206 mDownmixConfig.outputCfg.samplingRate = sampleRate;
207 mDownmixConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
208 mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
209 // input and output buffer provider, and frame count will not be used as the downmix effect
210 // process() function is called directly (see DownmixerBufferProvider::getNextBuffer())
211 mDownmixConfig.inputCfg.mask = EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS |
212 EFFECT_CONFIG_FORMAT | EFFECT_CONFIG_ACC_MODE;
213 mDownmixConfig.outputCfg.mask = mDownmixConfig.inputCfg.mask;
214
215 int cmdStatus;
216 uint32_t replySize = sizeof(int);
217
218 // Configure downmixer
219 status_t status = (*mDownmixHandle)->command(mDownmixHandle,
220 EFFECT_CMD_SET_CONFIG /*cmdCode*/, sizeof(effect_config_t) /*cmdSize*/,
221 &mDownmixConfig /*pCmdData*/,
222 &replySize, &cmdStatus /*pReplyData*/);
223 if (status != 0 || cmdStatus != 0) {
224 ALOGE("DownmixerBufferProvider() error %d cmdStatus %d while configuring downmixer",
225 status, cmdStatus);
226 EffectRelease(mDownmixHandle);
227 mDownmixHandle = NULL;
228 return;
229 }
230
231 // Enable downmixer
232 replySize = sizeof(int);
233 status = (*mDownmixHandle)->command(mDownmixHandle,
234 EFFECT_CMD_ENABLE /*cmdCode*/, 0 /*cmdSize*/, NULL /*pCmdData*/,
235 &replySize, &cmdStatus /*pReplyData*/);
236 if (status != 0 || cmdStatus != 0) {
237 ALOGE("DownmixerBufferProvider() error %d cmdStatus %d while enabling downmixer",
238 status, cmdStatus);
239 EffectRelease(mDownmixHandle);
240 mDownmixHandle = NULL;
241 return;
242 }
243
244 // Set downmix type
245 // parameter size rounded for padding on 32bit boundary
246 const int psizePadded = ((sizeof(downmix_params_t) - 1)/sizeof(int) + 1) * sizeof(int);
247 const int downmixParamSize =
248 sizeof(effect_param_t) + psizePadded + sizeof(downmix_type_t);
249 effect_param_t * const param = (effect_param_t *) malloc(downmixParamSize);
250 param->psize = sizeof(downmix_params_t);
251 const downmix_params_t downmixParam = DOWNMIX_PARAM_TYPE;
252 memcpy(param->data, &downmixParam, param->psize);
253 const downmix_type_t downmixType = DOWNMIX_TYPE_FOLD;
254 param->vsize = sizeof(downmix_type_t);
255 memcpy(param->data + psizePadded, &downmixType, param->vsize);
256 replySize = sizeof(int);
257 status = (*mDownmixHandle)->command(mDownmixHandle,
258 EFFECT_CMD_SET_PARAM /* cmdCode */, downmixParamSize /* cmdSize */,
259 param /*pCmdData*/, &replySize, &cmdStatus /*pReplyData*/);
260 free(param);
261 if (status != 0 || cmdStatus != 0) {
262 ALOGE("DownmixerBufferProvider() error %d cmdStatus %d while setting downmix type",
263 status, cmdStatus);
264 EffectRelease(mDownmixHandle);
265 mDownmixHandle = NULL;
266 return;
267 }
268 ALOGV("DownmixerBufferProvider() downmix type set to %d", (int) downmixType);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700269}
270
271AudioMixer::DownmixerBufferProvider::~DownmixerBufferProvider()
272{
Andy Hung34803d52014-07-16 21:41:35 -0700273 ALOGV("~DownmixerBufferProvider (%p)", this);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700274 EffectRelease(mDownmixHandle);
Andy Hung34803d52014-07-16 21:41:35 -0700275 mDownmixHandle = NULL;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700276}
277
Andy Hung34803d52014-07-16 21:41:35 -0700278void AudioMixer::DownmixerBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
279{
280 mDownmixConfig.inputCfg.buffer.frameCount = frames;
281 mDownmixConfig.inputCfg.buffer.raw = const_cast<void *>(src);
282 mDownmixConfig.outputCfg.buffer.frameCount = frames;
283 mDownmixConfig.outputCfg.buffer.raw = dst;
284 // may be in-place if src == dst.
285 status_t res = (*mDownmixHandle)->process(mDownmixHandle,
286 &mDownmixConfig.inputCfg.buffer, &mDownmixConfig.outputCfg.buffer);
287 ALOGE_IF(res != OK, "DownmixBufferProvider error %d", res);
288}
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700289
Andy Hung34803d52014-07-16 21:41:35 -0700290/* call once in a pthread_once handler. */
291/*static*/ status_t AudioMixer::DownmixerBufferProvider::init()
292{
293 // find multichannel downmix effect if we have to play multichannel content
294 uint32_t numEffects = 0;
295 int ret = EffectQueryNumberEffects(&numEffects);
296 if (ret != 0) {
297 ALOGE("AudioMixer() error %d querying number of effects", ret);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700298 return NO_INIT;
299 }
Andy Hung34803d52014-07-16 21:41:35 -0700300 ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects);
301
302 for (uint32_t i = 0 ; i < numEffects ; i++) {
303 if (EffectQueryEffect(i, &sDwnmFxDesc) == 0) {
304 ALOGV("effect %d is called %s", i, sDwnmFxDesc.name);
305 if (memcmp(&sDwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) {
306 ALOGI("found effect \"%s\" from %s",
307 sDwnmFxDesc.name, sDwnmFxDesc.implementor);
308 sIsMultichannelCapable = true;
309 break;
310 }
311 }
312 }
313 ALOGW_IF(!sIsMultichannelCapable, "unable to find downmix effect");
314 return NO_INIT;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700315}
316
Andy Hung34803d52014-07-16 21:41:35 -0700317/*static*/ bool AudioMixer::DownmixerBufferProvider::sIsMultichannelCapable = false;
318/*static*/ effect_descriptor_t AudioMixer::DownmixerBufferProvider::sDwnmFxDesc;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700319
Andy Hungef7c7fb2014-05-12 16:51:41 -0700320AudioMixer::ReformatBufferProvider::ReformatBufferProvider(int32_t channels,
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700321 audio_format_t inputFormat, audio_format_t outputFormat,
322 size_t bufferFrameCount) :
323 CopyBufferProvider(
324 channels * audio_bytes_per_sample(inputFormat),
325 channels * audio_bytes_per_sample(outputFormat),
326 bufferFrameCount),
Andy Hungef7c7fb2014-05-12 16:51:41 -0700327 mChannels(channels),
328 mInputFormat(inputFormat),
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700329 mOutputFormat(outputFormat)
Andy Hungef7c7fb2014-05-12 16:51:41 -0700330{
331 ALOGV("ReformatBufferProvider(%p)(%d, %#x, %#x)", this, channels, inputFormat, outputFormat);
Andy Hungef7c7fb2014-05-12 16:51:41 -0700332}
333
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700334void AudioMixer::ReformatBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
Andy Hungef7c7fb2014-05-12 16:51:41 -0700335{
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700336 memcpy_by_audio_format(dst, mOutputFormat, src, mInputFormat, frames * mChannels);
Andy Hungef7c7fb2014-05-12 16:51:41 -0700337}
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700338
339// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -0700340
Paul Lind3c0a0e82012-08-01 18:49:49 -0700341// Ensure mConfiguredNames bitmask is initialized properly on all architectures.
342// The value of 1 << x is undefined in C when x >= 32.
343
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700344AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks)
Paul Lind3c0a0e82012-08-01 18:49:49 -0700345 : mTrackNames(0), mConfiguredNames((maxNumTracks >= 32 ? 0 : 1 << maxNumTracks) - 1),
Glenn Kasten7f5d3352013-02-15 23:55:04 +0000346 mSampleRate(sampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700347{
Glenn Kasten788040c2011-05-05 08:19:00 -0700348 // AudioMixer is not yet capable of multi-channel beyond stereo
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800349 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(2 == MAX_NUM_CHANNELS);
Jean-Michel Triviacb86cc2012-04-16 12:43:57 -0700350
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700351 ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u",
352 maxNumTracks, MAX_NUM_TRACKS);
353
Glenn Kasten599fabc2012-03-08 12:33:37 -0800354 // AudioMixer is not yet capable of more than 32 active track inputs
355 ALOG_ASSERT(32 >= MAX_NUM_TRACKS, "bad MAX_NUM_TRACKS %d", MAX_NUM_TRACKS);
356
357 // AudioMixer is not yet capable of multi-channel output beyond stereo
358 ALOG_ASSERT(2 == MAX_NUM_CHANNELS, "bad MAX_NUM_CHANNELS %d", MAX_NUM_CHANNELS);
359
Glenn Kasten52008f82012-03-18 09:34:41 -0700360 pthread_once(&sOnceControl, &sInitRoutine);
361
Mathias Agopian65ab4712010-07-14 17:59:35 -0700362 mState.enabledTracks= 0;
363 mState.needsChanged = 0;
364 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800365 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -0800366 mState.outputTemp = NULL;
367 mState.resampleTemp = NULL;
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800368 mState.mLog = &mDummyLog;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800369 // mState.reserved
Glenn Kasten17a736c2012-02-14 08:52:15 -0800370
371 // FIXME Most of the following initialization is probably redundant since
372 // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0
373 // and mTrackNames is initially 0. However, leave it here until that's verified.
Mathias Agopian65ab4712010-07-14 17:59:35 -0700374 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800375 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Eric Laurenta5e82142012-04-16 13:47:17 -0700376 t->resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700377 t->downmixerBufferProvider = NULL;
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700378 t->mReformatBufferProvider = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700379 t++;
380 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700381
Mathias Agopian65ab4712010-07-14 17:59:35 -0700382}
383
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800384AudioMixer::~AudioMixer()
385{
386 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800387 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800388 delete t->resampler;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700389 delete t->downmixerBufferProvider;
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700390 delete t->mReformatBufferProvider;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800391 t++;
392 }
393 delete [] mState.outputTemp;
394 delete [] mState.resampleTemp;
395}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700396
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800397void AudioMixer::setLog(NBLog::Writer *log)
398{
399 mState.mLog = log;
400}
401
Andy Hunge8a1ced2014-05-09 15:02:21 -0700402int AudioMixer::getTrackName(audio_channel_mask_t channelMask,
403 audio_format_t format, int sessionId)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800404{
Andy Hunge8a1ced2014-05-09 15:02:21 -0700405 if (!isValidPcmTrackFormat(format)) {
406 ALOGE("AudioMixer::getTrackName invalid format (%#x)", format);
407 return -1;
408 }
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700409 uint32_t names = (~mTrackNames) & mConfiguredNames;
Glenn Kasten98dd5422011-12-15 14:38:29 -0800410 if (names != 0) {
411 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100412 ALOGV("add track (%d)", n);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700413 // assume default parameters for the track, except where noted below
414 track_t* t = &mState.tracks[n];
415 t->needs = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700416
417 // Integer volume.
418 // Currently integer volume is kept for the legacy integer mixer.
419 // Will be removed when the legacy mixer path is removed.
Andy Hung97ae8242014-05-30 10:35:47 -0700420 t->volume[0] = UNITY_GAIN_INT;
421 t->volume[1] = UNITY_GAIN_INT;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700422 t->prevVolume[0] = UNITY_GAIN_INT << 16;
423 t->prevVolume[1] = UNITY_GAIN_INT << 16;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700424 t->volumeInc[0] = 0;
425 t->volumeInc[1] = 0;
426 t->auxLevel = 0;
427 t->auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700428 t->prevAuxLevel = 0;
429
430 // Floating point volume.
431 t->mVolume[0] = UNITY_GAIN_FLOAT;
432 t->mVolume[1] = UNITY_GAIN_FLOAT;
433 t->mPrevVolume[0] = UNITY_GAIN_FLOAT;
434 t->mPrevVolume[1] = UNITY_GAIN_FLOAT;
435 t->mVolumeInc[0] = 0.;
436 t->mVolumeInc[1] = 0.;
437 t->mAuxLevel = 0.;
438 t->mAuxInc = 0.;
439 t->mPrevAuxLevel = 0.;
440
Glenn Kastendeeb1282012-03-25 11:59:31 -0700441 // no initialization needed
Glenn Kastendeeb1282012-03-25 11:59:31 -0700442 // t->frameCount
Andy Hung68112fc2014-05-14 14:13:23 -0700443 t->channelCount = audio_channel_count_from_out_mask(channelMask);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700444 t->enabled = false;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700445 ALOGV_IF(channelMask != AUDIO_CHANNEL_OUT_STEREO,
446 "Non-stereo channel mask: %d\n", channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700447 t->channelMask = channelMask;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700448 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700449 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
450 t->bufferProvider = NULL;
451 t->buffer.raw = NULL;
452 // no initialization needed
453 // t->buffer.frameCount
454 t->hook = NULL;
455 t->in = NULL;
456 t->resampler = NULL;
457 t->sampleRate = mSampleRate;
458 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
459 t->mainBuffer = NULL;
460 t->auxBuffer = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700461 t->mInputBufferProvider = NULL;
462 t->mReformatBufferProvider = NULL;
Glenn Kasten52008f82012-03-18 09:34:41 -0700463 t->downmixerBufferProvider = NULL;
Andy Hung78820702014-02-28 16:23:02 -0800464 t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
Andy Hunge8a1ced2014-05-09 15:02:21 -0700465 t->mFormat = format;
Andy Hung296b7412014-06-17 15:25:47 -0700466 t->mMixerInFormat = kUseFloat && kUseNewMixer
467 ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
468 // Check the downmixing (or upmixing) requirements.
469 status_t status = initTrackDownmix(t, n, channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700470 if (status != OK) {
471 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
472 return -1;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700473 }
Andy Hung296b7412014-06-17 15:25:47 -0700474 // initTrackDownmix() may change the input format requirement.
475 // If you desire floating point input to the mixer, it may change
476 // to integer because the downmixer requires integer to process.
477 ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
478 prepareTrackForReformat(t, n);
Andy Hung68112fc2014-05-14 14:13:23 -0700479 mTrackNames |= 1 << n;
480 return TRACK0 + n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700481 }
Andy Hung68112fc2014-05-14 14:13:23 -0700482 ALOGE("AudioMixer::getTrackName out of available tracks");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700483 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800484}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700485
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800486void AudioMixer::invalidateState(uint32_t mask)
487{
Glenn Kasten34fca342013-08-13 09:48:14 -0700488 if (mask != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700489 mState.needsChanged |= mask;
490 mState.hook = process__validate;
491 }
492 }
493
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700494status_t AudioMixer::initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask)
495{
Andy Hunge5412692014-05-16 11:25:07 -0700496 uint32_t channelCount = audio_channel_count_from_out_mask(mask);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700497 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
498 status_t status = OK;
499 if (channelCount > MAX_NUM_CHANNELS) {
500 pTrack->channelMask = mask;
501 pTrack->channelCount = channelCount;
502 ALOGV("initTrackDownmix(track=%d, mask=0x%x) calls prepareTrackForDownmix()",
503 trackNum, mask);
504 status = prepareTrackForDownmix(pTrack, trackNum);
505 } else {
506 unprepareTrackForDownmix(pTrack, trackNum);
507 }
508 return status;
509}
510
Andy Hungee931ff2014-01-28 13:44:14 -0800511void AudioMixer::unprepareTrackForDownmix(track_t* pTrack, int trackName __unused) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700512 ALOGV("AudioMixer::unprepareTrackForDownmix(%d)", trackName);
513
514 if (pTrack->downmixerBufferProvider != NULL) {
515 // this track had previously been configured with a downmixer, delete it
516 ALOGV(" deleting old downmixer");
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700517 delete pTrack->downmixerBufferProvider;
518 pTrack->downmixerBufferProvider = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700519 reconfigureBufferProviders(pTrack);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700520 } else {
521 ALOGV(" nothing to do, no downmixer to delete");
522 }
523}
524
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700525status_t AudioMixer::prepareTrackForDownmix(track_t* pTrack, int trackName)
526{
527 ALOGV("AudioMixer::prepareTrackForDownmix(%d) with mask 0x%x", trackName, pTrack->channelMask);
528
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700529 // discard the previous downmixer if there was one
530 unprepareTrackForDownmix(pTrack, trackName);
Andy Hung34803d52014-07-16 21:41:35 -0700531 if (DownmixerBufferProvider::isMultichannelCapable()) {
532 DownmixerBufferProvider* pDbp = new DownmixerBufferProvider(pTrack->channelMask,
533 /* pTrack->mMixerChannelMask */ audio_channel_out_mask_from_count(2),
534 /* pTrack->mMixerInFormat */ AUDIO_FORMAT_PCM_16_BIT,
535 pTrack->sampleRate, pTrack->sessionId, kCopyBufferFrameCount);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700536
Andy Hung34803d52014-07-16 21:41:35 -0700537 if (pDbp->isValid()) { // if constructor completed properly
538 pTrack->mMixerInFormat = AUDIO_FORMAT_PCM_16_BIT; // PCM 16 bit required for downmix
539 pTrack->downmixerBufferProvider = pDbp;
540 reconfigureBufferProviders(pTrack);
541 return NO_ERROR;
542 }
543 delete pDbp;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700544 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700545 pTrack->downmixerBufferProvider = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700546 reconfigureBufferProviders(pTrack);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700547 return NO_INIT;
548}
549
Andy Hungef7c7fb2014-05-12 16:51:41 -0700550void AudioMixer::unprepareTrackForReformat(track_t* pTrack, int trackName __unused) {
551 ALOGV("AudioMixer::unprepareTrackForReformat(%d)", trackName);
552 if (pTrack->mReformatBufferProvider != NULL) {
553 delete pTrack->mReformatBufferProvider;
554 pTrack->mReformatBufferProvider = NULL;
555 reconfigureBufferProviders(pTrack);
556 }
557}
558
559status_t AudioMixer::prepareTrackForReformat(track_t* pTrack, int trackName)
560{
561 ALOGV("AudioMixer::prepareTrackForReformat(%d) with format %#x", trackName, pTrack->mFormat);
562 // discard the previous reformatter if there was one
Andy Hung296b7412014-06-17 15:25:47 -0700563 unprepareTrackForReformat(pTrack, trackName);
564 // only configure reformatter if needed
565 if (pTrack->mFormat != pTrack->mMixerInFormat) {
566 pTrack->mReformatBufferProvider = new ReformatBufferProvider(
567 audio_channel_count_from_out_mask(pTrack->channelMask),
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700568 pTrack->mFormat, pTrack->mMixerInFormat,
569 kCopyBufferFrameCount);
Andy Hung296b7412014-06-17 15:25:47 -0700570 reconfigureBufferProviders(pTrack);
571 }
572 return NO_ERROR;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700573}
574
575void AudioMixer::reconfigureBufferProviders(track_t* pTrack)
576{
577 pTrack->bufferProvider = pTrack->mInputBufferProvider;
578 if (pTrack->mReformatBufferProvider) {
Andy Hung1b2fdcb2014-07-16 17:44:34 -0700579 pTrack->mReformatBufferProvider->setBufferProvider(pTrack->bufferProvider);
Andy Hungef7c7fb2014-05-12 16:51:41 -0700580 pTrack->bufferProvider = pTrack->mReformatBufferProvider;
581 }
582 if (pTrack->downmixerBufferProvider) {
Andy Hung34803d52014-07-16 21:41:35 -0700583 pTrack->downmixerBufferProvider->setBufferProvider(pTrack->bufferProvider);
Andy Hungef7c7fb2014-05-12 16:51:41 -0700584 pTrack->bufferProvider = pTrack->downmixerBufferProvider;
585 }
586}
587
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800588void AudioMixer::deleteTrackName(int name)
589{
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700590 ALOGV("AudioMixer::deleteTrackName(%d)", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700591 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800592 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800593 ALOGV("deleteTrackName(%d)", name);
594 track_t& track(mState.tracks[ name ]);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800595 if (track.enabled) {
596 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800597 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700598 }
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700599 // delete the resampler
600 delete track.resampler;
601 track.resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700602 // delete the downmixer
603 unprepareTrackForDownmix(&mState.tracks[name], name);
Andy Hungef7c7fb2014-05-12 16:51:41 -0700604 // delete the reformatter
605 unprepareTrackForReformat(&mState.tracks[name], name);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700606
Glenn Kasten237a6242011-12-15 15:32:27 -0800607 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800608}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700609
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800610void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700611{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800612 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800613 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800614 track_t& track = mState.tracks[name];
615
Glenn Kasten4c340c62012-01-27 12:33:54 -0800616 if (!track.enabled) {
617 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800618 ALOGV("enable(%d)", name);
619 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700620 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700621}
622
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800623void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700624{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800625 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800626 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800627 track_t& track = mState.tracks[name];
628
Glenn Kasten4c340c62012-01-27 12:33:54 -0800629 if (track.enabled) {
630 track.enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800631 ALOGV("disable(%d)", name);
632 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700633 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700634}
635
Andy Hung5866a3b2014-05-29 21:33:13 -0700636/* Sets the volume ramp variables for the AudioMixer.
637 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700638 * The volume ramp variables are used to transition from the previous
639 * volume to the set volume. ramp controls the duration of the transition.
640 * Its value is typically one state framecount period, but may also be 0,
641 * meaning "immediate."
Andy Hung5866a3b2014-05-29 21:33:13 -0700642 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700643 * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
644 * even if there is a nonzero floating point increment (in that case, the volume
645 * change is immediate). This restriction should be changed when the legacy mixer
646 * is removed (see #2).
647 * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
648 * when no longer needed.
649 *
650 * @param newVolume set volume target in floating point [0.0, 1.0].
651 * @param ramp number of frames to increment over. if ramp is 0, the volume
652 * should be set immediately. Currently ramp should not exceed 65535 (frames).
653 * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
654 * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
655 * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
656 * @param pSetVolume pointer to the float target volume, set on return.
657 * @param pPrevVolume pointer to the float previous volume, set on return.
658 * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
Andy Hung5866a3b2014-05-29 21:33:13 -0700659 * @return true if the volume has changed, false if volume is same.
660 */
Andy Hung5e58b0a2014-06-23 19:07:29 -0700661static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
662 int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
663 float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
664 if (newVolume == *pSetVolume) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700665 return false;
666 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700667 /* set the floating point volume variables */
Andy Hung5866a3b2014-05-29 21:33:13 -0700668 if (ramp != 0) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700669 *pVolumeInc = (newVolume - *pSetVolume) / ramp;
670 *pPrevVolume = *pSetVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700671 } else {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700672 *pVolumeInc = 0;
673 *pPrevVolume = newVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700674 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700675 *pSetVolume = newVolume;
676
677 /* set the legacy integer volume variables */
678 int32_t intVolume = newVolume * AudioMixer::UNITY_GAIN_INT;
679 if (intVolume > AudioMixer::UNITY_GAIN_INT) {
680 intVolume = AudioMixer::UNITY_GAIN_INT;
681 } else if (intVolume < 0) {
682 ALOGE("negative volume %.7g", newVolume);
683 intVolume = 0; // should never happen, but for safety check.
684 }
685 if (intVolume == *pIntSetVolume) {
686 *pIntVolumeInc = 0;
687 /* TODO: integer/float workaround: ignore floating volume ramp */
688 *pVolumeInc = 0;
689 *pPrevVolume = newVolume;
690 return true;
691 }
692 if (ramp != 0) {
693 *pIntVolumeInc = ((intVolume - *pIntSetVolume) << 16) / ramp;
694 *pIntPrevVolume = (*pIntVolumeInc == 0 ? intVolume : *pIntSetVolume) << 16;
695 } else {
696 *pIntVolumeInc = 0;
697 *pIntPrevVolume = intVolume << 16;
698 }
699 *pIntSetVolume = intVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700700 return true;
701}
702
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800703void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700704{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800705 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800706 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800707 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700708
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000709 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
710 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700711
712 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700713
Mathias Agopian65ab4712010-07-14 17:59:35 -0700714 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800715 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700716 case CHANNEL_MASK: {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000717 audio_channel_mask_t mask =
718 static_cast<audio_channel_mask_t>(reinterpret_cast<uintptr_t>(value));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800719 if (track.channelMask != mask) {
Andy Hunge5412692014-05-16 11:25:07 -0700720 uint32_t channelCount = audio_channel_count_from_out_mask(mask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700721 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800722 track.channelMask = mask;
723 track.channelCount = channelCount;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700724 // the mask has changed, does this track need a downmixer?
Andy Hung296b7412014-06-17 15:25:47 -0700725 // update to try using our desired format (if we aren't already using it)
726 track.mMixerInFormat = kUseFloat && kUseNewMixer
727 ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
728 status_t status = initTrackDownmix(&mState.tracks[name], name, mask);
729 ALOGE_IF(status != OK,
730 "Invalid channel mask %#x, initTrackDownmix returned %d",
731 mask, status);
Glenn Kasten788040c2011-05-05 08:19:00 -0700732 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Andy Hung296b7412014-06-17 15:25:47 -0700733 prepareTrackForReformat(&track, name); // format may have changed
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800734 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700735 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700736 } break;
737 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800738 if (track.mainBuffer != valueBuf) {
739 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100740 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800741 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700742 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700743 break;
744 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800745 if (track.auxBuffer != valueBuf) {
746 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100747 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800748 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700749 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700750 break;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700751 case FORMAT: {
752 audio_format_t format = static_cast<audio_format_t>(valueInt);
753 if (track.mFormat != format) {
754 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
755 track.mFormat = format;
756 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
Andy Hung296b7412014-06-17 15:25:47 -0700757 prepareTrackForReformat(&track, name);
Andy Hungef7c7fb2014-05-12 16:51:41 -0700758 invalidateState(1 << name);
759 }
760 } break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700761 // FIXME do we want to support setting the downmix type from AudioFlinger?
762 // for a specific track? or per mixer?
763 /* case DOWNMIX_TYPE:
764 break */
Andy Hung78820702014-02-28 16:23:02 -0800765 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800766 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung78820702014-02-28 16:23:02 -0800767 if (track.mMixerFormat != format) {
768 track.mMixerFormat = format;
769 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800770 }
771 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700772 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800773 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700774 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700775 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700776
Mathias Agopian65ab4712010-07-14 17:59:35 -0700777 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800778 switch (param) {
779 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800780 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700781 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
782 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
783 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800784 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700785 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800786 break;
787 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800788 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800789 invalidateState(1 << name);
790 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700791 case REMOVE:
792 delete track.resampler;
793 track.resampler = NULL;
794 track.sampleRate = mSampleRate;
795 invalidateState(1 << name);
796 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700797 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800798 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800799 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700800 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700801
Mathias Agopian65ab4712010-07-14 17:59:35 -0700802 case RAMP_VOLUME:
803 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800804 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700805 case VOLUME0:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800806 case VOLUME1:
Andy Hung6be49402014-05-30 10:42:03 -0700807 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung5866a3b2014-05-29 21:33:13 -0700808 target == RAMP_VOLUME ? mState.frameCount : 0,
Andy Hung5e58b0a2014-06-23 19:07:29 -0700809 &track.volume[param - VOLUME0], &track.prevVolume[param - VOLUME0],
810 &track.volumeInc[param - VOLUME0],
811 &track.mVolume[param - VOLUME0], &track.mPrevVolume[param - VOLUME0],
812 &track.mVolumeInc[param - VOLUME0])) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700813 ALOGV("setParameter(%s, VOLUME%d: %04x)",
Andy Hung6be49402014-05-30 10:42:03 -0700814 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
815 track.volume[param - VOLUME0]);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800816 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700817 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800818 break;
819 case AUXLEVEL:
Andy Hung6be49402014-05-30 10:42:03 -0700820 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung5866a3b2014-05-29 21:33:13 -0700821 target == RAMP_VOLUME ? mState.frameCount : 0,
Andy Hung5e58b0a2014-06-23 19:07:29 -0700822 &track.auxLevel, &track.prevAuxLevel, &track.auxInc,
823 &track.mAuxLevel, &track.mPrevAuxLevel, &track.mAuxInc)) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700824 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
Andy Hung6be49402014-05-30 10:42:03 -0700825 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track.auxLevel);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800826 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700827 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800828 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700829 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800830 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700831 }
832 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700833
834 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800835 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700836 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700837}
838
839bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
840{
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700841 if (value != devSampleRate || resampler != NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700842 if (sampleRate != value) {
843 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800844 if (resampler == NULL) {
Glenn Kastenac602052012-10-01 14:04:31 -0700845 ALOGV("creating resampler from track %d Hz to device %d Hz", value, devSampleRate);
846 AudioResampler::src_quality quality;
847 // force lowest quality level resampler if use case isn't music or video
848 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
849 // quality level based on the initial ratio, but that could change later.
850 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
851 if (!((value == 44100 && devSampleRate == 48000) ||
852 (value == 48000 && devSampleRate == 44100))) {
Andy Hung9e0308c2014-01-30 14:32:31 -0800853 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700854 } else {
855 quality = AudioResampler::DEFAULT_QUALITY;
856 }
Andy Hung296b7412014-06-17 15:25:47 -0700857
Andy Hung296b7412014-06-17 15:25:47 -0700858 ALOGVV("Creating resampler with %d bits\n", bits);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700859 resampler = AudioResampler::create(
Andy Hung3348e362014-07-07 10:21:44 -0700860 mMixerInFormat,
Jean-Michel Triviacb86cc2012-04-16 12:43:57 -0700861 // the resampler sees the number of channels after the downmixer, if any
Glenn Kastenf551e992013-08-19 18:45:42 -0700862 (int) (downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount),
Glenn Kastenac602052012-10-01 14:04:31 -0700863 devSampleRate, quality);
Glenn Kasten52008f82012-03-18 09:34:41 -0700864 resampler->setLocalTimeFreq(sLocalTimeFreq);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700865 }
866 return true;
867 }
868 }
869 return false;
870}
871
Andy Hung5e58b0a2014-06-23 19:07:29 -0700872/* Checks to see if the volume ramp has completed and clears the increment
873 * variables appropriately.
874 *
875 * FIXME: There is code to handle int/float ramp variable switchover should it not
876 * complete within a mixer buffer processing call, but it is preferred to avoid switchover
877 * due to precision issues. The switchover code is included for legacy code purposes
878 * and can be removed once the integer volume is removed.
879 *
880 * It is not sufficient to clear only the volumeInc integer variable because
881 * if one channel requires ramping, all channels are ramped.
882 *
883 * There is a bit of duplicated code here, but it keeps backward compatibility.
884 */
885inline void AudioMixer::track_t::adjustVolumeRamp(bool aux, bool useFloat)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700886{
Andy Hung5e58b0a2014-06-23 19:07:29 -0700887 if (useFloat) {
888 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
889 if (mVolumeInc[i] != 0 && fabs(mVolume[i] - mPrevVolume[i]) <= fabs(mVolumeInc[i])) {
890 volumeInc[i] = 0;
891 prevVolume[i] = volume[i] << 16;
892 mVolumeInc[i] = 0.;
893 mPrevVolume[i] = mVolume[i];
894
895 } else {
896 //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
897 prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
898 }
899 }
900 } else {
901 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
902 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
903 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
904 volumeInc[i] = 0;
905 prevVolume[i] = volume[i] << 16;
906 mVolumeInc[i] = 0.;
907 mPrevVolume[i] = mVolume[i];
908 } else {
909 //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
910 mPrevVolume[i] = float_from_u4_28(prevVolume[i]);
911 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700912 }
913 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700914 /* TODO: aux is always integer regardless of output buffer type */
Mathias Agopian65ab4712010-07-14 17:59:35 -0700915 if (aux) {
916 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
Andy Hung5e58b0a2014-06-23 19:07:29 -0700917 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700918 auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700919 prevAuxLevel = auxLevel << 16;
920 mAuxInc = 0.;
921 mPrevAuxLevel = mAuxLevel;
922 } else {
923 //ALOGV("aux ramp: %d %d %d", auxLevel << 16, prevAuxLevel, auxInc);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700924 }
925 }
926}
927
Glenn Kastenc59c0042012-02-02 14:06:11 -0800928size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800929{
930 name -= TRACK0;
931 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800932 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800933 }
934 return 0;
935}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700936
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800937void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700938{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800939 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800940 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700941
Andy Hung1d26ddf2014-05-29 15:53:09 -0700942 if (mState.tracks[name].mInputBufferProvider == bufferProvider) {
943 return; // don't reset any buffer providers if identical.
944 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700945 if (mState.tracks[name].mReformatBufferProvider != NULL) {
946 mState.tracks[name].mReformatBufferProvider->reset();
947 } else if (mState.tracks[name].downmixerBufferProvider != NULL) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700948 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700949
950 mState.tracks[name].mInputBufferProvider = bufferProvider;
951 reconfigureBufferProviders(&mState.tracks[name]);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700952}
953
954
John Grossman4ff14ba2012-02-08 16:37:41 -0800955void AudioMixer::process(int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700956{
John Grossman4ff14ba2012-02-08 16:37:41 -0800957 mState.hook(&mState, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700958}
959
960
John Grossman4ff14ba2012-02-08 16:37:41 -0800961void AudioMixer::process__validate(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700962{
Steve Block5ff1dd52012-01-05 23:22:43 +0000963 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700964 "in process__validate() but nothing's invalid");
965
966 uint32_t changed = state->needsChanged;
967 state->needsChanged = 0; // clear the validation flag
968
969 // recompute which tracks are enabled / disabled
970 uint32_t enabled = 0;
971 uint32_t disabled = 0;
972 while (changed) {
973 const int i = 31 - __builtin_clz(changed);
974 const uint32_t mask = 1<<i;
975 changed &= ~mask;
976 track_t& t = state->tracks[i];
977 (t.enabled ? enabled : disabled) |= mask;
978 }
979 state->enabledTracks &= ~disabled;
980 state->enabledTracks |= enabled;
981
982 // compute everything we need...
983 int countActiveTracks = 0;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800984 bool all16BitsStereoNoResample = true;
985 bool resampling = false;
986 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700987 uint32_t en = state->enabledTracks;
988 while (en) {
989 const int i = 31 - __builtin_clz(en);
990 en &= ~(1<<i);
991
992 countActiveTracks++;
993 track_t& t = state->tracks[i];
994 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700995 // FIXME can overflow (mask is only 3 bits)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700996 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700997 if (t.doesResample()) {
998 n |= NEEDS_RESAMPLE;
999 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001000 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001001 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001002 }
1003
1004 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001005 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001006 } else if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001007 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001008 }
1009 t.needs = n;
1010
Glenn Kastend6fadf02013-10-30 14:37:29 -07001011 if (n & NEEDS_MUTE) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001012 t.hook = track__nop;
1013 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001014 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001015 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001016 }
Glenn Kastend6fadf02013-10-30 14:37:29 -07001017 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001018 all16BitsStereoNoResample = false;
1019 resampling = true;
Andy Hung296b7412014-06-17 15:25:47 -07001020 t.hook = getTrackHook(TRACKTYPE_RESAMPLE, FCC_2,
1021 t.mMixerInFormat, t.mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001022 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -07001023 "Track %d needs downmix + resample", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001024 } else {
1025 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
Andy Hung296b7412014-06-17 15:25:47 -07001026 t.hook = getTrackHook(TRACKTYPE_NORESAMPLEMONO, FCC_2,
1027 t.mMixerInFormat, t.mMixerFormat);
Glenn Kasten4c340c62012-01-27 12:33:54 -08001028 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001029 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001030 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Andy Hung296b7412014-06-17 15:25:47 -07001031 t.hook = getTrackHook(TRACKTYPE_NORESAMPLE, FCC_2,
1032 t.mMixerInFormat, t.mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -07001033 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -07001034 "Track %d needs downmix", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001035 }
1036 }
1037 }
1038 }
1039
1040 // select the processing hooks
1041 state->hook = process__nop;
Glenn Kasten34fca342013-08-13 09:48:14 -07001042 if (countActiveTracks > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001043 if (resampling) {
1044 if (!state->outputTemp) {
1045 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
1046 }
1047 if (!state->resampleTemp) {
1048 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
1049 }
1050 state->hook = process__genericResampling;
1051 } else {
1052 if (state->outputTemp) {
1053 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -08001054 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001055 }
1056 if (state->resampleTemp) {
1057 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -08001058 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001059 }
1060 state->hook = process__genericNoResampling;
1061 if (all16BitsStereoNoResample && !volumeRamp) {
1062 if (countActiveTracks == 1) {
Andy Hung296b7412014-06-17 15:25:47 -07001063 const int i = 31 - __builtin_clz(state->enabledTracks);
1064 track_t& t = state->tracks[i];
1065 state->hook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK, FCC_2,
1066 t.mMixerInFormat, t.mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001067 }
1068 }
1069 }
1070 }
1071
Steve Block3856b092011-10-20 11:56:00 +01001072 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001073 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
1074 countActiveTracks, state->enabledTracks,
1075 all16BitsStereoNoResample, resampling, volumeRamp);
1076
John Grossman4ff14ba2012-02-08 16:37:41 -08001077 state->hook(state, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001078
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001079 // Now that the volume ramp has been done, set optimal state and
1080 // track hooks for subsequent mixer process
Glenn Kasten34fca342013-08-13 09:48:14 -07001081 if (countActiveTracks > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001082 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001083 uint32_t en = state->enabledTracks;
1084 while (en) {
1085 const int i = 31 - __builtin_clz(en);
1086 en &= ~(1<<i);
1087 track_t& t = state->tracks[i];
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001088 if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001089 t.needs |= NEEDS_MUTE;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001090 t.hook = track__nop;
1091 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001092 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001093 }
1094 }
1095 if (allMuted) {
1096 state->hook = process__nop;
1097 } else if (all16BitsStereoNoResample) {
1098 if (countActiveTracks == 1) {
1099 state->hook = process__OneTrack16BitsStereoNoResampling;
1100 }
1101 }
1102 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001103}
1104
Mathias Agopian65ab4712010-07-14 17:59:35 -07001105
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001106void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount,
1107 int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001108{
Andy Hung296b7412014-06-17 15:25:47 -07001109 ALOGVV("track__genericResample\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001110 t->resampler->setSampleRate(t->sampleRate);
1111
1112 // ramp gain - resample to temp buffer and scale/mix in 2nd step
1113 if (aux != NULL) {
1114 // always resample with unity gain when sending to auxiliary buffer to be able
1115 // to apply send level after resampling
1116 // TODO: modify each resampler to support aux channel?
Andy Hung5e58b0a2014-06-23 19:07:29 -07001117 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001118 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
1119 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -08001120 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001121 volumeRampStereo(t, out, outFrameCount, temp, aux);
1122 } else {
1123 volumeStereo(t, out, outFrameCount, temp, aux);
1124 }
1125 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -08001126 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001127 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001128 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
1129 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
1130 volumeRampStereo(t, out, outFrameCount, temp, aux);
1131 }
1132
1133 // constant gain
1134 else {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001135 t->resampler->setVolume(t->mVolume[0], t->mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001136 t->resampler->resample(out, outFrameCount, t->bufferProvider);
1137 }
1138 }
1139}
1140
Andy Hungee931ff2014-01-28 13:44:14 -08001141void AudioMixer::track__nop(track_t* t __unused, int32_t* out __unused,
1142 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001143{
1144}
1145
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001146void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1147 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001148{
1149 int32_t vl = t->prevVolume[0];
1150 int32_t vr = t->prevVolume[1];
1151 const int32_t vlInc = t->volumeInc[0];
1152 const int32_t vrInc = t->volumeInc[1];
1153
Steve Blockb8a80522011-12-20 16:23:08 +00001154 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001155 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1156 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1157
1158 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -08001159 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001160 int32_t va = t->prevAuxLevel;
1161 const int32_t vaInc = t->auxInc;
1162 int32_t l;
1163 int32_t r;
1164
1165 do {
1166 l = (*temp++ >> 12);
1167 r = (*temp++ >> 12);
1168 *out++ += (vl >> 16) * l;
1169 *out++ += (vr >> 16) * r;
1170 *aux++ += (va >> 17) * (l + r);
1171 vl += vlInc;
1172 vr += vrInc;
1173 va += vaInc;
1174 } while (--frameCount);
1175 t->prevAuxLevel = va;
1176 } else {
1177 do {
1178 *out++ += (vl >> 16) * (*temp++ >> 12);
1179 *out++ += (vr >> 16) * (*temp++ >> 12);
1180 vl += vlInc;
1181 vr += vrInc;
1182 } while (--frameCount);
1183 }
1184 t->prevVolume[0] = vl;
1185 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -08001186 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001187}
1188
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001189void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1190 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001191{
1192 const int16_t vl = t->volume[0];
1193 const int16_t vr = t->volume[1];
1194
Glenn Kastenf6b16782011-12-15 09:51:17 -08001195 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -08001196 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001197 do {
1198 int16_t l = (int16_t)(*temp++ >> 12);
1199 int16_t r = (int16_t)(*temp++ >> 12);
1200 out[0] = mulAdd(l, vl, out[0]);
1201 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
1202 out[1] = mulAdd(r, vr, out[1]);
1203 out += 2;
1204 aux[0] = mulAdd(a, va, aux[0]);
1205 aux++;
1206 } while (--frameCount);
1207 } else {
1208 do {
1209 int16_t l = (int16_t)(*temp++ >> 12);
1210 int16_t r = (int16_t)(*temp++ >> 12);
1211 out[0] = mulAdd(l, vl, out[0]);
1212 out[1] = mulAdd(r, vr, out[1]);
1213 out += 2;
1214 } while (--frameCount);
1215 }
1216}
1217
Andy Hungee931ff2014-01-28 13:44:14 -08001218void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount,
1219 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001220{
Andy Hung296b7412014-06-17 15:25:47 -07001221 ALOGVV("track__16BitsStereo\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001222 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001223
Glenn Kastenf6b16782011-12-15 09:51:17 -08001224 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001225 int32_t l;
1226 int32_t r;
1227 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001228 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001229 int32_t vl = t->prevVolume[0];
1230 int32_t vr = t->prevVolume[1];
1231 int32_t va = t->prevAuxLevel;
1232 const int32_t vlInc = t->volumeInc[0];
1233 const int32_t vrInc = t->volumeInc[1];
1234 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +00001235 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001236 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1237 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1238
1239 do {
1240 l = (int32_t)*in++;
1241 r = (int32_t)*in++;
1242 *out++ += (vl >> 16) * l;
1243 *out++ += (vr >> 16) * r;
1244 *aux++ += (va >> 17) * (l + r);
1245 vl += vlInc;
1246 vr += vrInc;
1247 va += vaInc;
1248 } while (--frameCount);
1249
1250 t->prevVolume[0] = vl;
1251 t->prevVolume[1] = vr;
1252 t->prevAuxLevel = va;
1253 t->adjustVolumeRamp(true);
1254 }
1255
1256 // constant gain
1257 else {
1258 const uint32_t vrl = t->volumeRL;
1259 const int16_t va = (int16_t)t->auxLevel;
1260 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001261 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001262 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
1263 in += 2;
1264 out[0] = mulAddRL(1, rl, vrl, out[0]);
1265 out[1] = mulAddRL(0, rl, vrl, out[1]);
1266 out += 2;
1267 aux[0] = mulAdd(a, va, aux[0]);
1268 aux++;
1269 } while (--frameCount);
1270 }
1271 } else {
1272 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001273 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001274 int32_t vl = t->prevVolume[0];
1275 int32_t vr = t->prevVolume[1];
1276 const int32_t vlInc = t->volumeInc[0];
1277 const int32_t vrInc = t->volumeInc[1];
1278
Steve Blockb8a80522011-12-20 16:23:08 +00001279 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001280 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1281 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1282
1283 do {
1284 *out++ += (vl >> 16) * (int32_t) *in++;
1285 *out++ += (vr >> 16) * (int32_t) *in++;
1286 vl += vlInc;
1287 vr += vrInc;
1288 } while (--frameCount);
1289
1290 t->prevVolume[0] = vl;
1291 t->prevVolume[1] = vr;
1292 t->adjustVolumeRamp(false);
1293 }
1294
1295 // constant gain
1296 else {
1297 const uint32_t vrl = t->volumeRL;
1298 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001299 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001300 in += 2;
1301 out[0] = mulAddRL(1, rl, vrl, out[0]);
1302 out[1] = mulAddRL(0, rl, vrl, out[1]);
1303 out += 2;
1304 } while (--frameCount);
1305 }
1306 }
1307 t->in = in;
1308}
1309
Andy Hungee931ff2014-01-28 13:44:14 -08001310void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount,
1311 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001312{
Andy Hung296b7412014-06-17 15:25:47 -07001313 ALOGVV("track__16BitsMono\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001314 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001315
Glenn Kastenf6b16782011-12-15 09:51:17 -08001316 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001317 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001318 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001319 int32_t vl = t->prevVolume[0];
1320 int32_t vr = t->prevVolume[1];
1321 int32_t va = t->prevAuxLevel;
1322 const int32_t vlInc = t->volumeInc[0];
1323 const int32_t vrInc = t->volumeInc[1];
1324 const int32_t vaInc = t->auxInc;
1325
Steve Blockb8a80522011-12-20 16:23:08 +00001326 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001327 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1328 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1329
1330 do {
1331 int32_t l = *in++;
1332 *out++ += (vl >> 16) * l;
1333 *out++ += (vr >> 16) * l;
1334 *aux++ += (va >> 16) * l;
1335 vl += vlInc;
1336 vr += vrInc;
1337 va += vaInc;
1338 } while (--frameCount);
1339
1340 t->prevVolume[0] = vl;
1341 t->prevVolume[1] = vr;
1342 t->prevAuxLevel = va;
1343 t->adjustVolumeRamp(true);
1344 }
1345 // constant gain
1346 else {
1347 const int16_t vl = t->volume[0];
1348 const int16_t vr = t->volume[1];
1349 const int16_t va = (int16_t)t->auxLevel;
1350 do {
1351 int16_t l = *in++;
1352 out[0] = mulAdd(l, vl, out[0]);
1353 out[1] = mulAdd(l, vr, out[1]);
1354 out += 2;
1355 aux[0] = mulAdd(l, va, aux[0]);
1356 aux++;
1357 } while (--frameCount);
1358 }
1359 } else {
1360 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001361 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001362 int32_t vl = t->prevVolume[0];
1363 int32_t vr = t->prevVolume[1];
1364 const int32_t vlInc = t->volumeInc[0];
1365 const int32_t vrInc = t->volumeInc[1];
1366
Steve Blockb8a80522011-12-20 16:23:08 +00001367 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001368 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1369 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1370
1371 do {
1372 int32_t l = *in++;
1373 *out++ += (vl >> 16) * l;
1374 *out++ += (vr >> 16) * l;
1375 vl += vlInc;
1376 vr += vrInc;
1377 } while (--frameCount);
1378
1379 t->prevVolume[0] = vl;
1380 t->prevVolume[1] = vr;
1381 t->adjustVolumeRamp(false);
1382 }
1383 // constant gain
1384 else {
1385 const int16_t vl = t->volume[0];
1386 const int16_t vr = t->volume[1];
1387 do {
1388 int16_t l = *in++;
1389 out[0] = mulAdd(l, vl, out[0]);
1390 out[1] = mulAdd(l, vr, out[1]);
1391 out += 2;
1392 } while (--frameCount);
1393 }
1394 }
1395 t->in = in;
1396}
1397
Mathias Agopian65ab4712010-07-14 17:59:35 -07001398// no-op case
John Grossman4ff14ba2012-02-08 16:37:41 -08001399void AudioMixer::process__nop(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001400{
Andy Hung296b7412014-06-17 15:25:47 -07001401 ALOGVV("process__nop\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001402 uint32_t e0 = state->enabledTracks;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001403 size_t sampleCount = state->frameCount * MAX_NUM_CHANNELS;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001404 while (e0) {
1405 // process by group of tracks with same output buffer to
1406 // avoid multiple memset() on same buffer
1407 uint32_t e1 = e0, e2 = e0;
1408 int i = 31 - __builtin_clz(e1);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001409 {
1410 track_t& t1 = state->tracks[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001411 e2 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001412 while (e2) {
1413 i = 31 - __builtin_clz(e2);
1414 e2 &= ~(1<<i);
1415 track_t& t2 = state->tracks[i];
1416 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1417 e1 &= ~(1<<i);
1418 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001419 }
Glenn Kastenfc900c92013-02-18 12:47:49 -08001420 e0 &= ~(e1);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001421
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001422 memset(t1.mainBuffer, 0, sampleCount
Andy Hung78820702014-02-28 16:23:02 -08001423 * audio_bytes_per_sample(t1.mMixerFormat));
Glenn Kastenfc900c92013-02-18 12:47:49 -08001424 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001425
1426 while (e1) {
1427 i = 31 - __builtin_clz(e1);
1428 e1 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001429 {
1430 track_t& t3 = state->tracks[i];
1431 size_t outFrames = state->frameCount;
1432 while (outFrames) {
1433 t3.buffer.frameCount = outFrames;
1434 int64_t outputPTS = calculateOutputPTS(
1435 t3, pts, state->frameCount - outFrames);
1436 t3.bufferProvider->getNextBuffer(&t3.buffer, outputPTS);
1437 if (t3.buffer.raw == NULL) break;
1438 outFrames -= t3.buffer.frameCount;
1439 t3.bufferProvider->releaseBuffer(&t3.buffer);
1440 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001441 }
1442 }
1443 }
1444}
1445
1446// generic code without resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001447void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001448{
Andy Hung296b7412014-06-17 15:25:47 -07001449 ALOGVV("process__genericNoResampling\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001450 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1451
1452 // acquire each track's buffer
1453 uint32_t enabledTracks = state->enabledTracks;
1454 uint32_t e0 = enabledTracks;
1455 while (e0) {
1456 const int i = 31 - __builtin_clz(e0);
1457 e0 &= ~(1<<i);
1458 track_t& t = state->tracks[i];
1459 t.buffer.frameCount = state->frameCount;
John Grossman4ff14ba2012-02-08 16:37:41 -08001460 t.bufferProvider->getNextBuffer(&t.buffer, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001461 t.frameCount = t.buffer.frameCount;
1462 t.in = t.buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001463 }
1464
1465 e0 = enabledTracks;
1466 while (e0) {
1467 // process by group of tracks with same output buffer to
1468 // optimize cache use
1469 uint32_t e1 = e0, e2 = e0;
1470 int j = 31 - __builtin_clz(e1);
1471 track_t& t1 = state->tracks[j];
1472 e2 &= ~(1<<j);
1473 while (e2) {
1474 j = 31 - __builtin_clz(e2);
1475 e2 &= ~(1<<j);
1476 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001477 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001478 e1 &= ~(1<<j);
1479 }
1480 }
1481 e0 &= ~(e1);
1482 // this assumes output 16 bits stereo, no resampling
1483 int32_t *out = t1.mainBuffer;
1484 size_t numFrames = 0;
1485 do {
1486 memset(outTemp, 0, sizeof(outTemp));
1487 e2 = e1;
1488 while (e2) {
1489 const int i = 31 - __builtin_clz(e2);
1490 e2 &= ~(1<<i);
1491 track_t& t = state->tracks[i];
1492 size_t outFrames = BLOCKSIZE;
1493 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001494 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001495 aux = t.auxBuffer + numFrames;
1496 }
1497 while (outFrames) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301498 // t.in == NULL can happen if the track was flushed just after having
1499 // been enabled for mixing.
1500 if (t.in == NULL) {
1501 enabledTracks &= ~(1<<i);
1502 e1 &= ~(1<<i);
1503 break;
1504 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001505 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001506 if (inFrames > 0) {
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001507 t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames,
1508 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001509 t.frameCount -= inFrames;
1510 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001511 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001512 aux += inFrames;
1513 }
1514 }
1515 if (t.frameCount == 0 && outFrames) {
1516 t.bufferProvider->releaseBuffer(&t.buffer);
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001517 t.buffer.frameCount = (state->frameCount - numFrames) -
1518 (BLOCKSIZE - outFrames);
John Grossman4ff14ba2012-02-08 16:37:41 -08001519 int64_t outputPTS = calculateOutputPTS(
1520 t, pts, numFrames + (BLOCKSIZE - outFrames));
1521 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001522 t.in = t.buffer.raw;
1523 if (t.in == NULL) {
1524 enabledTracks &= ~(1<<i);
1525 e1 &= ~(1<<i);
1526 break;
1527 }
1528 t.frameCount = t.buffer.frameCount;
1529 }
1530 }
1531 }
Andy Hung296b7412014-06-17 15:25:47 -07001532
1533 convertMixerFormat(out, t1.mMixerFormat, outTemp, t1.mMixerInFormat,
1534 BLOCKSIZE * FCC_2);
1535 // TODO: fix ugly casting due to choice of out pointer type
1536 out = reinterpret_cast<int32_t*>((uint8_t*)out
1537 + BLOCKSIZE * FCC_2 * audio_bytes_per_sample(t1.mMixerFormat));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001538 numFrames += BLOCKSIZE;
1539 } while (numFrames < state->frameCount);
1540 }
1541
1542 // release each track's buffer
1543 e0 = enabledTracks;
1544 while (e0) {
1545 const int i = 31 - __builtin_clz(e0);
1546 e0 &= ~(1<<i);
1547 track_t& t = state->tracks[i];
1548 t.bufferProvider->releaseBuffer(&t.buffer);
1549 }
1550}
1551
1552
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001553// generic code with resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001554void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001555{
Andy Hung296b7412014-06-17 15:25:47 -07001556 ALOGVV("process__genericResampling\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001557 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -07001558 int32_t* const outTemp = state->outputTemp;
1559 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001560
1561 size_t numFrames = state->frameCount;
1562
1563 uint32_t e0 = state->enabledTracks;
1564 while (e0) {
1565 // process by group of tracks with same output buffer
1566 // to optimize cache use
1567 uint32_t e1 = e0, e2 = e0;
1568 int j = 31 - __builtin_clz(e1);
1569 track_t& t1 = state->tracks[j];
1570 e2 &= ~(1<<j);
1571 while (e2) {
1572 j = 31 - __builtin_clz(e2);
1573 e2 &= ~(1<<j);
1574 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001575 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001576 e1 &= ~(1<<j);
1577 }
1578 }
1579 e0 &= ~(e1);
1580 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +01001581 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001582 while (e1) {
1583 const int i = 31 - __builtin_clz(e1);
1584 e1 &= ~(1<<i);
1585 track_t& t = state->tracks[i];
1586 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001587 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001588 aux = t.auxBuffer;
1589 }
1590
1591 // this is a little goofy, on the resampling case we don't
1592 // acquire/release the buffers because it's done by
1593 // the resampler.
Glenn Kastend6fadf02013-10-30 14:37:29 -07001594 if (t.needs & NEEDS_RESAMPLE) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001595 t.resampler->setPTS(pts);
Glenn Kastena1117922012-01-26 10:53:32 -08001596 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001597 } else {
1598
1599 size_t outFrames = 0;
1600
1601 while (outFrames < numFrames) {
1602 t.buffer.frameCount = numFrames - outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001603 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
1604 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001605 t.in = t.buffer.raw;
1606 // t.in == NULL can happen if the track was flushed just after having
1607 // been enabled for mixing.
1608 if (t.in == NULL) break;
1609
Glenn Kastenf6b16782011-12-15 09:51:17 -08001610 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001611 aux += outFrames;
1612 }
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001613 t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount,
1614 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001615 outFrames += t.buffer.frameCount;
1616 t.bufferProvider->releaseBuffer(&t.buffer);
1617 }
1618 }
1619 }
Andy Hung296b7412014-06-17 15:25:47 -07001620 convertMixerFormat(out, t1.mMixerFormat, outTemp, t1.mMixerInFormat, numFrames * FCC_2);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001621 }
1622}
1623
1624// one track, 16 bits stereo without resampling is the most common case
John Grossman4ff14ba2012-02-08 16:37:41 -08001625void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
1626 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001627{
Andy Hung296b7412014-06-17 15:25:47 -07001628 ALOGVV("process__OneTrack16BitsStereoNoResampling\n");
Glenn Kasten99e53b82012-01-19 08:59:58 -08001629 // This method is only called when state->enabledTracks has exactly
1630 // one bit set. The asserts below would verify this, but are commented out
1631 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001632 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001633 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001634 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001635 const track_t& t = state->tracks[i];
1636
1637 AudioBufferProvider::Buffer& b(t.buffer);
1638
1639 int32_t* out = t.mainBuffer;
Andy Hungf8a106a2014-05-29 18:52:38 -07001640 float *fout = reinterpret_cast<float*>(out);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001641 size_t numFrames = state->frameCount;
1642
1643 const int16_t vl = t.volume[0];
1644 const int16_t vr = t.volume[1];
1645 const uint32_t vrl = t.volumeRL;
1646 while (numFrames) {
1647 b.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001648 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
1649 t.bufferProvider->getNextBuffer(&b, outputPTS);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001650 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001651
1652 // in == NULL can happen if the track was flushed just after having
1653 // been enabled for mixing.
Andy Hungf8a106a2014-05-29 18:52:38 -07001654 if (in == NULL || (((uintptr_t)in) & 3)) {
1655 memset(out, 0, numFrames
1656 * MAX_NUM_CHANNELS * audio_bytes_per_sample(t.mMixerFormat));
1657 ALOGE_IF((((uintptr_t)in) & 3), "process stereo track: input buffer alignment pb: "
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001658 "buffer %p track %d, channels %d, needs %08x",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001659 in, i, t.channelCount, t.needs);
1660 return;
1661 }
1662 size_t outFrames = b.frameCount;
1663
Andy Hung78820702014-02-28 16:23:02 -08001664 switch (t.mMixerFormat) {
Andy Hungf8a106a2014-05-29 18:52:38 -07001665 case AUDIO_FORMAT_PCM_FLOAT:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001666 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001667 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001668 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001669 int32_t l = mulRL(1, rl, vrl);
1670 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001671 *fout++ = float_from_q4_27(l);
1672 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001673 // Note: In case of later int16_t sink output,
1674 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001675 } while (--outFrames);
Andy Hungf8a106a2014-05-29 18:52:38 -07001676 break;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001677 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung97ae8242014-05-30 10:35:47 -07001678 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001679 // volume is boosted, so we might need to clamp even though
1680 // we process only one track.
1681 do {
1682 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1683 in += 2;
1684 int32_t l = mulRL(1, rl, vrl) >> 12;
1685 int32_t r = mulRL(0, rl, vrl) >> 12;
1686 // clamping...
1687 l = clamp16(l);
1688 r = clamp16(r);
1689 *out++ = (r<<16) | (l & 0xFFFF);
1690 } while (--outFrames);
1691 } else {
1692 do {
1693 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1694 in += 2;
1695 int32_t l = mulRL(1, rl, vrl) >> 12;
1696 int32_t r = mulRL(0, rl, vrl) >> 12;
1697 *out++ = (r<<16) | (l & 0xFFFF);
1698 } while (--outFrames);
1699 }
1700 break;
1701 default:
Andy Hung78820702014-02-28 16:23:02 -08001702 LOG_ALWAYS_FATAL("bad mixer format: %d", t.mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001703 }
1704 numFrames -= b.frameCount;
1705 t.bufferProvider->releaseBuffer(&b);
1706 }
1707}
1708
Glenn Kasten81a028f2011-12-15 09:53:12 -08001709#if 0
Mathias Agopian65ab4712010-07-14 17:59:35 -07001710// 2 tracks is also a common case
1711// NEVER used in current implementation of process__validate()
1712// only use if the 2 tracks have the same output buffer
John Grossman4ff14ba2012-02-08 16:37:41 -08001713void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state,
1714 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001715{
1716 int i;
1717 uint32_t en = state->enabledTracks;
1718
1719 i = 31 - __builtin_clz(en);
1720 const track_t& t0 = state->tracks[i];
1721 AudioBufferProvider::Buffer& b0(t0.buffer);
1722
1723 en &= ~(1<<i);
1724 i = 31 - __builtin_clz(en);
1725 const track_t& t1 = state->tracks[i];
1726 AudioBufferProvider::Buffer& b1(t1.buffer);
1727
Glenn Kasten54c3b662012-01-06 07:46:30 -08001728 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001729 const int16_t vl0 = t0.volume[0];
1730 const int16_t vr0 = t0.volume[1];
1731 size_t frameCount0 = 0;
1732
Glenn Kasten54c3b662012-01-06 07:46:30 -08001733 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001734 const int16_t vl1 = t1.volume[0];
1735 const int16_t vr1 = t1.volume[1];
1736 size_t frameCount1 = 0;
1737
1738 //FIXME: only works if two tracks use same buffer
1739 int32_t* out = t0.mainBuffer;
1740 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001741 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001742
1743
1744 while (numFrames) {
1745
1746 if (frameCount0 == 0) {
1747 b0.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001748 int64_t outputPTS = calculateOutputPTS(t0, pts,
1749 out - t0.mainBuffer);
1750 t0.bufferProvider->getNextBuffer(&b0, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001751 if (b0.i16 == NULL) {
1752 if (buff == NULL) {
1753 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1754 }
1755 in0 = buff;
1756 b0.frameCount = numFrames;
1757 } else {
1758 in0 = b0.i16;
1759 }
1760 frameCount0 = b0.frameCount;
1761 }
1762 if (frameCount1 == 0) {
1763 b1.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001764 int64_t outputPTS = calculateOutputPTS(t1, pts,
1765 out - t0.mainBuffer);
1766 t1.bufferProvider->getNextBuffer(&b1, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001767 if (b1.i16 == NULL) {
1768 if (buff == NULL) {
1769 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1770 }
1771 in1 = buff;
1772 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001773 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001774 in1 = b1.i16;
1775 }
1776 frameCount1 = b1.frameCount;
1777 }
1778
1779 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1780
1781 numFrames -= outFrames;
1782 frameCount0 -= outFrames;
1783 frameCount1 -= outFrames;
1784
1785 do {
1786 int32_t l0 = *in0++;
1787 int32_t r0 = *in0++;
1788 l0 = mul(l0, vl0);
1789 r0 = mul(r0, vr0);
1790 int32_t l = *in1++;
1791 int32_t r = *in1++;
1792 l = mulAdd(l, vl1, l0) >> 12;
1793 r = mulAdd(r, vr1, r0) >> 12;
1794 // clamping...
1795 l = clamp16(l);
1796 r = clamp16(r);
1797 *out++ = (r<<16) | (l & 0xFFFF);
1798 } while (--outFrames);
1799
1800 if (frameCount0 == 0) {
1801 t0.bufferProvider->releaseBuffer(&b0);
1802 }
1803 if (frameCount1 == 0) {
1804 t1.bufferProvider->releaseBuffer(&b1);
1805 }
1806 }
1807
Glenn Kastene9dd0172012-01-27 18:08:45 -08001808 delete [] buff;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001809}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001810#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001811
John Grossman4ff14ba2012-02-08 16:37:41 -08001812int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1813 int outputFrameIndex)
1814{
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001815 if (AudioBufferProvider::kInvalidPTS == basePTS) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001816 return AudioBufferProvider::kInvalidPTS;
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001817 }
John Grossman4ff14ba2012-02-08 16:37:41 -08001818
Glenn Kasten52008f82012-03-18 09:34:41 -07001819 return basePTS + ((outputFrameIndex * sLocalTimeFreq) / t.sampleRate);
1820}
1821
1822/*static*/ uint64_t AudioMixer::sLocalTimeFreq;
1823/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1824
1825/*static*/ void AudioMixer::sInitRoutine()
1826{
1827 LocalClock lc;
Andy Hung34803d52014-07-16 21:41:35 -07001828 sLocalTimeFreq = lc.getLocalFreq(); // for the resampler
Glenn Kasten49c34ac2013-10-30 14:37:01 -07001829
Andy Hung34803d52014-07-16 21:41:35 -07001830 DownmixerBufferProvider::init(); // for the downmixer
John Grossman4ff14ba2012-02-08 16:37:41 -08001831}
1832
Andy Hung5e58b0a2014-06-23 19:07:29 -07001833template <int MIXTYPE, int NCHAN, bool USEFLOATVOL, bool ADJUSTVOL,
1834 typename TO, typename TI, typename TA>
1835void AudioMixer::volumeMix(TO *out, size_t outFrames,
1836 const TI *in, TA *aux, bool ramp, AudioMixer::track_t *t)
1837{
1838 if (USEFLOATVOL) {
1839 if (ramp) {
1840 volumeRampMulti<MIXTYPE, NCHAN>(out, outFrames, in, aux,
1841 t->mPrevVolume, t->mVolumeInc, &t->prevAuxLevel, t->auxInc);
1842 if (ADJUSTVOL) {
1843 t->adjustVolumeRamp(aux != NULL, true);
1844 }
1845 } else {
1846 volumeMulti<MIXTYPE, NCHAN>(out, outFrames, in, aux,
1847 t->mVolume, t->auxLevel);
1848 }
1849 } else {
1850 if (ramp) {
1851 volumeRampMulti<MIXTYPE, NCHAN>(out, outFrames, in, aux,
1852 t->prevVolume, t->volumeInc, &t->prevAuxLevel, t->auxInc);
1853 if (ADJUSTVOL) {
1854 t->adjustVolumeRamp(aux != NULL);
1855 }
1856 } else {
1857 volumeMulti<MIXTYPE, NCHAN>(out, outFrames, in, aux,
1858 t->volume, t->auxLevel);
1859 }
1860 }
1861}
1862
Andy Hung296b7412014-06-17 15:25:47 -07001863/* This process hook is called when there is a single track without
1864 * aux buffer, volume ramp, or resampling.
1865 * TODO: Update the hook selection: this can properly handle aux and ramp.
1866 */
1867template <int MIXTYPE, int NCHAN, typename TO, typename TI, typename TA>
1868void AudioMixer::process_NoResampleOneTrack(state_t* state, int64_t pts)
1869{
1870 ALOGVV("process_NoResampleOneTrack\n");
1871 // CLZ is faster than CTZ on ARM, though really not sure if true after 31 - clz.
1872 const int i = 31 - __builtin_clz(state->enabledTracks);
1873 ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
1874 track_t *t = &state->tracks[i];
1875 TO* out = reinterpret_cast<TO*>(t->mainBuffer);
1876 TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
1877 const bool ramp = t->needsRamp();
1878
1879 for (size_t numFrames = state->frameCount; numFrames; ) {
1880 AudioBufferProvider::Buffer& b(t->buffer);
1881 // get input buffer
1882 b.frameCount = numFrames;
1883 const int64_t outputPTS = calculateOutputPTS(*t, pts, state->frameCount - numFrames);
1884 t->bufferProvider->getNextBuffer(&b, outputPTS);
1885 const TI *in = reinterpret_cast<TI*>(b.raw);
1886
1887 // in == NULL can happen if the track was flushed just after having
1888 // been enabled for mixing.
1889 if (in == NULL || (((uintptr_t)in) & 3)) {
1890 memset(out, 0, numFrames
1891 * NCHAN * audio_bytes_per_sample(t->mMixerFormat));
1892 ALOGE_IF((((uintptr_t)in) & 3), "process_NoResampleOneTrack: bus error: "
1893 "buffer %p track %p, channels %d, needs %#x",
1894 in, t, t->channelCount, t->needs);
1895 return;
1896 }
1897
1898 const size_t outFrames = b.frameCount;
Andy Hung5e58b0a2014-06-23 19:07:29 -07001899 volumeMix<MIXTYPE, NCHAN, is_same<TI, float>::value, false> (out,
1900 outFrames, in, aux, ramp, t);
1901
Andy Hung296b7412014-06-17 15:25:47 -07001902 out += outFrames * NCHAN;
1903 if (aux != NULL) {
1904 aux += NCHAN;
1905 }
1906 numFrames -= b.frameCount;
1907
1908 // release buffer
1909 t->bufferProvider->releaseBuffer(&b);
1910 }
1911 if (ramp) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001912 t->adjustVolumeRamp(aux != NULL, is_same<TI, float>::value);
Andy Hung296b7412014-06-17 15:25:47 -07001913 }
1914}
1915
1916/* This track hook is called to do resampling then mixing,
1917 * pulling from the track's upstream AudioBufferProvider.
1918 */
1919template <int MIXTYPE, int NCHAN, typename TO, typename TI, typename TA>
1920void AudioMixer::track__Resample(track_t* t, TO* out, size_t outFrameCount, TO* temp, TA* aux)
1921{
1922 ALOGVV("track__Resample\n");
1923 t->resampler->setSampleRate(t->sampleRate);
1924
1925 const bool ramp = t->needsRamp();
1926 if (ramp || aux != NULL) {
1927 // if ramp: resample with unity gain to temp buffer and scale/mix in 2nd step.
1928 // if aux != NULL: resample with unity gain to temp buffer then apply send level.
1929
Andy Hung5e58b0a2014-06-23 19:07:29 -07001930 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Andy Hung296b7412014-06-17 15:25:47 -07001931 memset(temp, 0, outFrameCount * NCHAN * sizeof(TO));
1932 t->resampler->resample((int32_t*)temp, outFrameCount, t->bufferProvider);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001933
1934 volumeMix<MIXTYPE, NCHAN, is_same<TI, float>::value, true>(out, outFrameCount,
1935 temp, aux, ramp, t);
1936
Andy Hung296b7412014-06-17 15:25:47 -07001937 } else { // constant volume gain
Andy Hung5e58b0a2014-06-23 19:07:29 -07001938 t->resampler->setVolume(t->mVolume[0], t->mVolume[1]);
Andy Hung296b7412014-06-17 15:25:47 -07001939 t->resampler->resample((int32_t*)out, outFrameCount, t->bufferProvider);
1940 }
1941}
1942
1943/* This track hook is called to mix a track, when no resampling is required.
1944 * The input buffer should be present in t->in.
1945 */
1946template <int MIXTYPE, int NCHAN, typename TO, typename TI, typename TA>
1947void AudioMixer::track__NoResample(track_t* t, TO* out, size_t frameCount,
1948 TO* temp __unused, TA* aux)
1949{
1950 ALOGVV("track__NoResample\n");
1951 const TI *in = static_cast<const TI *>(t->in);
1952
Andy Hung5e58b0a2014-06-23 19:07:29 -07001953 volumeMix<MIXTYPE, NCHAN, is_same<TI, float>::value, true>(out, frameCount,
1954 in, aux, t->needsRamp(), t);
1955
Andy Hung296b7412014-06-17 15:25:47 -07001956 // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
1957 // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
1958 in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * NCHAN;
1959 t->in = in;
1960}
1961
1962/* The Mixer engine generates either int32_t (Q4_27) or float data.
1963 * We use this function to convert the engine buffers
1964 * to the desired mixer output format, either int16_t (Q.15) or float.
1965 */
1966void AudioMixer::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
1967 void *in, audio_format_t mixerInFormat, size_t sampleCount)
1968{
1969 switch (mixerInFormat) {
1970 case AUDIO_FORMAT_PCM_FLOAT:
1971 switch (mixerOutFormat) {
1972 case AUDIO_FORMAT_PCM_FLOAT:
1973 memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
1974 break;
1975 case AUDIO_FORMAT_PCM_16_BIT:
1976 memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
1977 break;
1978 default:
1979 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1980 break;
1981 }
1982 break;
1983 case AUDIO_FORMAT_PCM_16_BIT:
1984 switch (mixerOutFormat) {
1985 case AUDIO_FORMAT_PCM_FLOAT:
1986 memcpy_to_float_from_q4_27((float*)out, (int32_t*)in, sampleCount);
1987 break;
1988 case AUDIO_FORMAT_PCM_16_BIT:
1989 // two int16_t are produced per iteration
1990 ditherAndClamp((int32_t*)out, (int32_t*)in, sampleCount >> 1);
1991 break;
1992 default:
1993 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1994 break;
1995 }
1996 break;
1997 default:
1998 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1999 break;
2000 }
2001}
2002
2003/* Returns the proper track hook to use for mixing the track into the output buffer.
2004 */
2005AudioMixer::hook_t AudioMixer::getTrackHook(int trackType, int channels,
2006 audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
2007{
2008 if (!kUseNewMixer && channels == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
2009 switch (trackType) {
2010 case TRACKTYPE_NOP:
2011 return track__nop;
2012 case TRACKTYPE_RESAMPLE:
2013 return track__genericResample;
2014 case TRACKTYPE_NORESAMPLEMONO:
2015 return track__16BitsMono;
2016 case TRACKTYPE_NORESAMPLE:
2017 return track__16BitsStereo;
2018 default:
2019 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
2020 break;
2021 }
2022 }
2023 LOG_ALWAYS_FATAL_IF(channels != FCC_2); // TODO: must be stereo right now
2024 switch (trackType) {
2025 case TRACKTYPE_NOP:
2026 return track__nop;
2027 case TRACKTYPE_RESAMPLE:
2028 switch (mixerInFormat) {
2029 case AUDIO_FORMAT_PCM_FLOAT:
2030 return (AudioMixer::hook_t)
2031 track__Resample<MIXTYPE_MULTI, 2, float, float, int32_t>;
2032 case AUDIO_FORMAT_PCM_16_BIT:
2033 return (AudioMixer::hook_t)\
2034 track__Resample<MIXTYPE_MULTI, 2, int32_t, int16_t, int32_t>;
2035 default:
2036 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2037 break;
2038 }
2039 break;
2040 case TRACKTYPE_NORESAMPLEMONO:
2041 switch (mixerInFormat) {
2042 case AUDIO_FORMAT_PCM_FLOAT:
2043 return (AudioMixer::hook_t)
2044 track__NoResample<MIXTYPE_MONOEXPAND, 2, float, float, int32_t>;
2045 case AUDIO_FORMAT_PCM_16_BIT:
2046 return (AudioMixer::hook_t)
2047 track__NoResample<MIXTYPE_MONOEXPAND, 2, int32_t, int16_t, int32_t>;
2048 default:
2049 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2050 break;
2051 }
2052 break;
2053 case TRACKTYPE_NORESAMPLE:
2054 switch (mixerInFormat) {
2055 case AUDIO_FORMAT_PCM_FLOAT:
2056 return (AudioMixer::hook_t)
2057 track__NoResample<MIXTYPE_MULTI, 2, float, float, int32_t>;
2058 case AUDIO_FORMAT_PCM_16_BIT:
2059 return (AudioMixer::hook_t)
2060 track__NoResample<MIXTYPE_MULTI, 2, int32_t, int16_t, int32_t>;
2061 default:
2062 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2063 break;
2064 }
2065 break;
2066 default:
2067 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
2068 break;
2069 }
2070 return NULL;
2071}
2072
2073/* Returns the proper process hook for mixing tracks. Currently works only for
2074 * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
2075 */
2076AudioMixer::process_hook_t AudioMixer::getProcessHook(int processType, int channels,
2077 audio_format_t mixerInFormat, audio_format_t mixerOutFormat)
2078{
2079 if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
2080 LOG_ALWAYS_FATAL("bad processType: %d", processType);
2081 return NULL;
2082 }
2083 if (!kUseNewMixer && channels == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
2084 return process__OneTrack16BitsStereoNoResampling;
2085 }
2086 LOG_ALWAYS_FATAL_IF(channels != FCC_2); // TODO: must be stereo right now
2087 switch (mixerInFormat) {
2088 case AUDIO_FORMAT_PCM_FLOAT:
2089 switch (mixerOutFormat) {
2090 case AUDIO_FORMAT_PCM_FLOAT:
2091 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY, 2,
2092 float, float, int32_t>;
2093 case AUDIO_FORMAT_PCM_16_BIT:
2094 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY, 2,
2095 int16_t, float, int32_t>;
2096 default:
2097 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2098 break;
2099 }
2100 break;
2101 case AUDIO_FORMAT_PCM_16_BIT:
2102 switch (mixerOutFormat) {
2103 case AUDIO_FORMAT_PCM_FLOAT:
2104 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY, 2,
2105 float, int16_t, int32_t>;
2106 case AUDIO_FORMAT_PCM_16_BIT:
2107 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY, 2,
2108 int16_t, int16_t, int32_t>;
2109 default:
2110 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2111 break;
2112 }
2113 break;
2114 default:
2115 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2116 break;
2117 }
2118 return NULL;
2119}
2120
Mathias Agopian65ab4712010-07-14 17:59:35 -07002121// ----------------------------------------------------------------------------
2122}; // namespace android