blob: 2d7894d7b356bf6832836209e89e05006d13cc77 [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 Kastendd976422013-02-13 14:46:45 -080019#define LOG_NDEBUG 0
Mathias Agopian65ab4712010-07-14 17:59:35 -070020
21#include <stdint.h>
22#include <string.h>
23#include <stdlib.h>
24#include <sys/types.h>
25
26#include <utils/Errors.h>
27#include <utils/Log.h>
Glenn Kastendd976422013-02-13 14:46:45 -080028#undef ALOGV
29#define ALOGV(a...) do { } while (0)
Mathias Agopian65ab4712010-07-14 17:59:35 -070030
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>
John Grossman4ff14ba2012-02-08 16:37:41 -080038#include <common_time/local_clock.h>
39#include <common_time/cc_helper.h>
Glenn Kasten3b21c502011-12-15 09:52:39 -080040
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070041#include <media/EffectsFactoryApi.h>
42
Mathias Agopian65ab4712010-07-14 17:59:35 -070043#include "AudioMixer.h"
44
45namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070046
47// ----------------------------------------------------------------------------
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070048AudioMixer::DownmixerBufferProvider::DownmixerBufferProvider() : AudioBufferProvider(),
49 mTrackBufferProvider(NULL), mDownmixHandle(NULL)
50{
51}
52
53AudioMixer::DownmixerBufferProvider::~DownmixerBufferProvider()
54{
55 ALOGV("AudioMixer deleting DownmixerBufferProvider (%p)", this);
56 EffectRelease(mDownmixHandle);
57}
58
59status_t AudioMixer::DownmixerBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer,
60 int64_t pts) {
61 //ALOGV("DownmixerBufferProvider::getNextBuffer()");
62 if (this->mTrackBufferProvider != NULL) {
63 status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts);
64 if (res == OK) {
65 mDownmixConfig.inputCfg.buffer.frameCount = pBuffer->frameCount;
66 mDownmixConfig.inputCfg.buffer.raw = pBuffer->raw;
67 mDownmixConfig.outputCfg.buffer.frameCount = pBuffer->frameCount;
68 mDownmixConfig.outputCfg.buffer.raw = mDownmixConfig.inputCfg.buffer.raw;
69 // in-place so overwrite the buffer contents, has been set in prepareTrackForDownmix()
70 //mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
71
72 res = (*mDownmixHandle)->process(mDownmixHandle,
73 &mDownmixConfig.inputCfg.buffer, &mDownmixConfig.outputCfg.buffer);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -070074 //ALOGV("getNextBuffer is downmixing");
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070075 }
76 return res;
77 } else {
78 ALOGE("DownmixerBufferProvider::getNextBuffer() error: NULL track buffer provider");
79 return NO_INIT;
80 }
81}
82
83void AudioMixer::DownmixerBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -070084 //ALOGV("DownmixerBufferProvider::releaseBuffer()");
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070085 if (this->mTrackBufferProvider != NULL) {
86 mTrackBufferProvider->releaseBuffer(pBuffer);
87 } else {
88 ALOGE("DownmixerBufferProvider::releaseBuffer() error: NULL track buffer provider");
89 }
90}
91
92
93// ----------------------------------------------------------------------------
94bool AudioMixer::isMultichannelCapable = false;
95
96effect_descriptor_t AudioMixer::dwnmFxDesc;
Mathias Agopian65ab4712010-07-14 17:59:35 -070097
Paul Lind3c0a0e82012-08-01 18:49:49 -070098// Ensure mConfiguredNames bitmask is initialized properly on all architectures.
99// The value of 1 << x is undefined in C when x >= 32.
100
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700101AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks)
Paul Lind3c0a0e82012-08-01 18:49:49 -0700102 : mTrackNames(0), mConfiguredNames((maxNumTracks >= 32 ? 0 : 1 << maxNumTracks) - 1),
Glenn Kastendd976422013-02-13 14:46:45 -0800103 mSampleRate(sampleRate), mLog(&mDummyLog)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700104{
Glenn Kasten788040c2011-05-05 08:19:00 -0700105 // AudioMixer is not yet capable of multi-channel beyond stereo
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800106 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(2 == MAX_NUM_CHANNELS);
Jean-Michel Triviacb86cc2012-04-16 12:43:57 -0700107
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700108 ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u",
109 maxNumTracks, MAX_NUM_TRACKS);
110
Glenn Kastend82c7502012-03-08 12:33:37 -0800111 // AudioMixer is not yet capable of more than 32 active track inputs
112 ALOG_ASSERT(32 >= MAX_NUM_TRACKS, "bad MAX_NUM_TRACKS %d", MAX_NUM_TRACKS);
113
114 // AudioMixer is not yet capable of multi-channel output beyond stereo
115 ALOG_ASSERT(2 == MAX_NUM_CHANNELS, "bad MAX_NUM_CHANNELS %d", MAX_NUM_CHANNELS);
116
John Grossman4ff14ba2012-02-08 16:37:41 -0800117 LocalClock lc;
118
Glenn Kasten52008f82012-03-18 09:34:41 -0700119 pthread_once(&sOnceControl, &sInitRoutine);
120
Mathias Agopian65ab4712010-07-14 17:59:35 -0700121 mState.enabledTracks= 0;
122 mState.needsChanged = 0;
123 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800124 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -0800125 mState.outputTemp = NULL;
126 mState.resampleTemp = NULL;
Glenn Kastendd976422013-02-13 14:46:45 -0800127 mState.mLog = &mDummyLog;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800128 // mState.reserved
Glenn Kasten17a736c2012-02-14 08:52:15 -0800129
130 // FIXME Most of the following initialization is probably redundant since
131 // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0
132 // and mTrackNames is initially 0. However, leave it here until that's verified.
Mathias Agopian65ab4712010-07-14 17:59:35 -0700133 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800134 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Eric Laurenta5e82142012-04-16 13:47:17 -0700135 t->resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700136 t->downmixerBufferProvider = NULL;
Glenn Kastendd976422013-02-13 14:46:45 -0800137 t->magic = track_t::kMagic;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700138 t++;
139 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700140
141 // find multichannel downmix effect if we have to play multichannel content
142 uint32_t numEffects = 0;
143 int ret = EffectQueryNumberEffects(&numEffects);
144 if (ret != 0) {
145 ALOGE("AudioMixer() error %d querying number of effects", ret);
146 return;
147 }
148 ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects);
149
150 for (uint32_t i = 0 ; i < numEffects ; i++) {
151 if (EffectQueryEffect(i, &dwnmFxDesc) == 0) {
152 ALOGV("effect %d is called %s", i, dwnmFxDesc.name);
153 if (memcmp(&dwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) {
154 ALOGI("found effect \"%s\" from %s",
155 dwnmFxDesc.name, dwnmFxDesc.implementor);
156 isMultichannelCapable = true;
157 break;
158 }
159 }
160 }
161 ALOGE_IF(!isMultichannelCapable, "unable to find downmix effect");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700162}
163
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800164AudioMixer::~AudioMixer()
165{
166 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800167 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800168 delete t->resampler;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700169 delete t->downmixerBufferProvider;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800170 t++;
171 }
172 delete [] mState.outputTemp;
173 delete [] mState.resampleTemp;
174}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700175
Glenn Kastendd976422013-02-13 14:46:45 -0800176void AudioMixer::setLog(NBLog::Writer *log)
177{
178 mLog = log;
179 mState.mLog = log;
180}
181
Jean-Michel Trivia59d2712012-09-12 15:47:07 -0700182int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800183{
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700184 uint32_t names = (~mTrackNames) & mConfiguredNames;
Glenn Kasten98dd5422011-12-15 14:38:29 -0800185 if (names != 0) {
186 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100187 ALOGV("add track (%d)", n);
Glenn Kasten98dd5422011-12-15 14:38:29 -0800188 mTrackNames |= 1 << n;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700189 // assume default parameters for the track, except where noted below
190 track_t* t = &mState.tracks[n];
191 t->needs = 0;
192 t->volume[0] = UNITY_GAIN;
193 t->volume[1] = UNITY_GAIN;
194 // no initialization needed
195 // t->prevVolume[0]
196 // t->prevVolume[1]
197 t->volumeInc[0] = 0;
198 t->volumeInc[1] = 0;
199 t->auxLevel = 0;
200 t->auxInc = 0;
201 // no initialization needed
202 // t->prevAuxLevel
203 // t->frameCount
204 t->channelCount = 2;
205 t->enabled = false;
206 t->format = 16;
207 t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
Jean-Michel Trivia59d2712012-09-12 15:47:07 -0700208 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700209 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
210 t->bufferProvider = NULL;
211 t->buffer.raw = NULL;
212 // no initialization needed
213 // t->buffer.frameCount
214 t->hook = NULL;
215 t->in = NULL;
216 t->resampler = NULL;
217 t->sampleRate = mSampleRate;
218 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
219 t->mainBuffer = NULL;
220 t->auxBuffer = NULL;
Glenn Kasten52008f82012-03-18 09:34:41 -0700221 t->downmixerBufferProvider = NULL;
Glenn Kastendd976422013-02-13 14:46:45 -0800222 t->fastIndex = -1;
223 // t->magic unchanged
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700224
225 status_t status = initTrackDownmix(&mState.tracks[n], n, channelMask);
226 if (status == OK) {
Glenn Kastendd976422013-02-13 14:46:45 -0800227 mLog->logf("getTrackName %d", n);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700228 return TRACK0 + n;
229 }
230 ALOGE("AudioMixer::getTrackName(0x%x) failed, error preparing track for downmix",
231 channelMask);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700232 }
233 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800234}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700235
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800236void AudioMixer::invalidateState(uint32_t mask)
237{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700238 if (mask) {
239 mState.needsChanged |= mask;
240 mState.hook = process__validate;
241 }
242 }
243
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700244status_t AudioMixer::initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask)
245{
246 uint32_t channelCount = popcount(mask);
247 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
248 status_t status = OK;
249 if (channelCount > MAX_NUM_CHANNELS) {
250 pTrack->channelMask = mask;
251 pTrack->channelCount = channelCount;
252 ALOGV("initTrackDownmix(track=%d, mask=0x%x) calls prepareTrackForDownmix()",
253 trackNum, mask);
254 status = prepareTrackForDownmix(pTrack, trackNum);
255 } else {
256 unprepareTrackForDownmix(pTrack, trackNum);
257 }
258 return status;
259}
260
261void AudioMixer::unprepareTrackForDownmix(track_t* pTrack, int trackName) {
262 ALOGV("AudioMixer::unprepareTrackForDownmix(%d)", trackName);
263
264 if (pTrack->downmixerBufferProvider != NULL) {
265 // this track had previously been configured with a downmixer, delete it
266 ALOGV(" deleting old downmixer");
267 pTrack->bufferProvider = pTrack->downmixerBufferProvider->mTrackBufferProvider;
268 delete pTrack->downmixerBufferProvider;
269 pTrack->downmixerBufferProvider = NULL;
270 } else {
271 ALOGV(" nothing to do, no downmixer to delete");
272 }
273}
274
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700275status_t AudioMixer::prepareTrackForDownmix(track_t* pTrack, int trackName)
276{
277 ALOGV("AudioMixer::prepareTrackForDownmix(%d) with mask 0x%x", trackName, pTrack->channelMask);
278
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700279 // discard the previous downmixer if there was one
280 unprepareTrackForDownmix(pTrack, trackName);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700281
282 DownmixerBufferProvider* pDbp = new DownmixerBufferProvider();
283 int32_t status;
284
285 if (!isMultichannelCapable) {
286 ALOGE("prepareTrackForDownmix(%d) fails: mixer doesn't support multichannel content",
287 trackName);
288 goto noDownmixForActiveTrack;
289 }
290
291 if (EffectCreate(&dwnmFxDesc.uuid,
Jean-Michel Trivia59d2712012-09-12 15:47:07 -0700292 pTrack->sessionId /*sessionId*/, -2 /*ioId not relevant here, using random value*/,
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700293 &pDbp->mDownmixHandle/*pHandle*/) != 0) {
294 ALOGE("prepareTrackForDownmix(%d) fails: error creating downmixer effect", trackName);
295 goto noDownmixForActiveTrack;
296 }
297
298 // channel input configuration will be overridden per-track
299 pDbp->mDownmixConfig.inputCfg.channels = pTrack->channelMask;
300 pDbp->mDownmixConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
301 pDbp->mDownmixConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
302 pDbp->mDownmixConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
303 pDbp->mDownmixConfig.inputCfg.samplingRate = pTrack->sampleRate;
304 pDbp->mDownmixConfig.outputCfg.samplingRate = pTrack->sampleRate;
305 pDbp->mDownmixConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
306 pDbp->mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
307 // input and output buffer provider, and frame count will not be used as the downmix effect
308 // process() function is called directly (see DownmixerBufferProvider::getNextBuffer())
309 pDbp->mDownmixConfig.inputCfg.mask = EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS |
310 EFFECT_CONFIG_FORMAT | EFFECT_CONFIG_ACC_MODE;
311 pDbp->mDownmixConfig.outputCfg.mask = pDbp->mDownmixConfig.inputCfg.mask;
312
313 {// scope for local variables that are not used in goto label "noDownmixForActiveTrack"
314 int cmdStatus;
315 uint32_t replySize = sizeof(int);
316
317 // Configure and enable downmixer
318 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
319 EFFECT_CMD_SET_CONFIG /*cmdCode*/, sizeof(effect_config_t) /*cmdSize*/,
320 &pDbp->mDownmixConfig /*pCmdData*/,
321 &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
322 if ((status != 0) || (cmdStatus != 0)) {
323 ALOGE("error %d while configuring downmixer for track %d", status, trackName);
324 goto noDownmixForActiveTrack;
325 }
326 replySize = sizeof(int);
327 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
328 EFFECT_CMD_ENABLE /*cmdCode*/, 0 /*cmdSize*/, NULL /*pCmdData*/,
329 &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
330 if ((status != 0) || (cmdStatus != 0)) {
331 ALOGE("error %d while enabling downmixer for track %d", status, trackName);
332 goto noDownmixForActiveTrack;
333 }
334
335 // Set downmix type
336 // parameter size rounded for padding on 32bit boundary
337 const int psizePadded = ((sizeof(downmix_params_t) - 1)/sizeof(int) + 1) * sizeof(int);
338 const int downmixParamSize =
339 sizeof(effect_param_t) + psizePadded + sizeof(downmix_type_t);
340 effect_param_t * const param = (effect_param_t *) malloc(downmixParamSize);
341 param->psize = sizeof(downmix_params_t);
342 const downmix_params_t downmixParam = DOWNMIX_PARAM_TYPE;
343 memcpy(param->data, &downmixParam, param->psize);
344 const downmix_type_t downmixType = DOWNMIX_TYPE_FOLD;
345 param->vsize = sizeof(downmix_type_t);
346 memcpy(param->data + psizePadded, &downmixType, param->vsize);
347
348 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
349 EFFECT_CMD_SET_PARAM /* cmdCode */, downmixParamSize/* cmdSize */,
350 param /*pCmndData*/, &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
351
352 free(param);
353
354 if ((status != 0) || (cmdStatus != 0)) {
355 ALOGE("error %d while setting downmix type for track %d", status, trackName);
356 goto noDownmixForActiveTrack;
357 } else {
358 ALOGV("downmix type set to %d for track %d", (int) downmixType, trackName);
359 }
360 }// end of scope for local variables that are not used in goto label "noDownmixForActiveTrack"
361
362 // initialization successful:
363 // - keep track of the real buffer provider in case it was set before
364 pDbp->mTrackBufferProvider = pTrack->bufferProvider;
365 // - we'll use the downmix effect integrated inside this
366 // track's buffer provider, and we'll use it as the track's buffer provider
367 pTrack->downmixerBufferProvider = pDbp;
368 pTrack->bufferProvider = pDbp;
369
370 return NO_ERROR;
371
372noDownmixForActiveTrack:
373 delete pDbp;
374 pTrack->downmixerBufferProvider = NULL;
375 return NO_INIT;
376}
377
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800378void AudioMixer::deleteTrackName(int name)
379{
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700380 ALOGV("AudioMixer::deleteTrackName(%d)", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700381 name -= TRACK0;
Glenn Kastendd976422013-02-13 14:46:45 -0800382 mLog->logf("deleteTrackName %d", name);
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800383 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800384 ALOGV("deleteTrackName(%d)", name);
385 track_t& track(mState.tracks[ name ]);
Glenn Kastendd976422013-02-13 14:46:45 -0800386 track.checkMagic();
Glenn Kasten4c340c62012-01-27 12:33:54 -0800387 if (track.enabled) {
388 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800389 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700390 }
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700391 // delete the resampler
392 delete track.resampler;
393 track.resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700394 // delete the downmixer
395 unprepareTrackForDownmix(&mState.tracks[name], name);
396
Glenn Kasten237a6242011-12-15 15:32:27 -0800397 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800398}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700399
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800400void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700401{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800402 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800403 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800404 track_t& track = mState.tracks[name];
Glenn Kastendd976422013-02-13 14:46:45 -0800405 track.checkMagic();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800406
Glenn Kasten4c340c62012-01-27 12:33:54 -0800407 if (!track.enabled) {
Glenn Kastendd976422013-02-13 14:46:45 -0800408 mLog->logf("enable %d", name);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800409 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800410 ALOGV("enable(%d)", name);
411 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700412 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700413}
414
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800415void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700416{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800417 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800418 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800419 track_t& track = mState.tracks[name];
Glenn Kastendd976422013-02-13 14:46:45 -0800420 track.checkMagic();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800421
Glenn Kasten4c340c62012-01-27 12:33:54 -0800422 if (track.enabled) {
Glenn Kastendd976422013-02-13 14:46:45 -0800423 mLog->logf("disable %d", name);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800424 track.enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800425 ALOGV("disable(%d)", name);
426 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700427 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700428}
429
Glenn Kastendd976422013-02-13 14:46:45 -0800430bool AudioMixer::enabled(int name)
431{
432 name -= TRACK0;
433 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
434 track_t& track = mState.tracks[name];
435 track.checkMagic();
436#if 0
437 // can't do this because mState.enabledTracks is updated lazily
438 ALOG_ASSERT(track.enabled == ((mState.enabledTracks & (1 << name)) != 0));
439#endif
440
441 return track.enabled;
442}
443
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800444void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700445{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800446 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800447 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800448 track_t& track = mState.tracks[name];
Glenn Kastendd976422013-02-13 14:46:45 -0800449 track.checkMagic();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700450
Mathias Agopian65ab4712010-07-14 17:59:35 -0700451 int valueInt = (int)value;
452 int32_t *valueBuf = (int32_t *)value;
453
454 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700455
Mathias Agopian65ab4712010-07-14 17:59:35 -0700456 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800457 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700458 case CHANNEL_MASK: {
Glenn Kasten254af182012-07-03 14:59:05 -0700459 audio_channel_mask_t mask = (audio_channel_mask_t) value;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800460 if (track.channelMask != mask) {
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800461 uint32_t channelCount = popcount(mask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700462 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800463 track.channelMask = mask;
464 track.channelCount = channelCount;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700465 // the mask has changed, does this track need a downmixer?
466 initTrackDownmix(&mState.tracks[name], name, mask);
Glenn Kasten788040c2011-05-05 08:19:00 -0700467 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800468 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700469 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700470 } break;
471 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800472 if (track.mainBuffer != valueBuf) {
473 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100474 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800475 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700476 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700477 break;
478 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800479 if (track.auxBuffer != valueBuf) {
480 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100481 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800482 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700483 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700484 break;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700485 case FORMAT:
486 ALOG_ASSERT(valueInt == AUDIO_FORMAT_PCM_16_BIT);
487 break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700488 // FIXME do we want to support setting the downmix type from AudioFlinger?
489 // for a specific track? or per mixer?
490 /* case DOWNMIX_TYPE:
491 break */
Glenn Kastendd976422013-02-13 14:46:45 -0800492 case FAST_INDEX:
493 track.fastIndex = valueInt;
494 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700495 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800496 LOG_FATAL("bad param");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700497 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700498 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700499
Mathias Agopian65ab4712010-07-14 17:59:35 -0700500 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800501 switch (param) {
502 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800503 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700504 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
505 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
506 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800507 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700508 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800509 break;
510 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800511 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800512 invalidateState(1 << name);
513 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700514 case REMOVE:
515 delete track.resampler;
516 track.resampler = NULL;
517 track.sampleRate = mSampleRate;
518 invalidateState(1 << name);
519 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700520 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800521 LOG_FATAL("bad param");
Eric Laurent243f5f92011-02-28 16:52:51 -0800522 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700523 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700524
Mathias Agopian65ab4712010-07-14 17:59:35 -0700525 case RAMP_VOLUME:
526 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800527 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700528 case VOLUME0:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800529 case VOLUME1:
530 if (track.volume[param-VOLUME0] != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100531 ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800532 track.prevVolume[param-VOLUME0] = track.volume[param-VOLUME0] << 16;
533 track.volume[param-VOLUME0] = valueInt;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700534 if (target == VOLUME) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800535 track.prevVolume[param-VOLUME0] = valueInt << 16;
536 track.volumeInc[param-VOLUME0] = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700537 } else {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800538 int32_t d = (valueInt<<16) - track.prevVolume[param-VOLUME0];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700539 int32_t volInc = d / int32_t(mState.frameCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800540 track.volumeInc[param-VOLUME0] = volInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700541 if (volInc == 0) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800542 track.prevVolume[param-VOLUME0] = valueInt << 16;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700543 }
544 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800545 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700546 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800547 break;
548 case AUXLEVEL:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800549 //ALOG_ASSERT(0 <= valueInt && valueInt <= MAX_GAIN_INT, "bad aux level %d", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700550 if (track.auxLevel != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100551 ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700552 track.prevAuxLevel = track.auxLevel << 16;
553 track.auxLevel = valueInt;
554 if (target == VOLUME) {
555 track.prevAuxLevel = valueInt << 16;
556 track.auxInc = 0;
557 } else {
558 int32_t d = (valueInt<<16) - track.prevAuxLevel;
559 int32_t volInc = d / int32_t(mState.frameCount);
560 track.auxInc = volInc;
561 if (volInc == 0) {
562 track.prevAuxLevel = valueInt << 16;
563 }
564 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800565 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700566 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800567 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700568 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800569 LOG_FATAL("bad param");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700570 }
571 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700572
573 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800574 LOG_FATAL("bad target");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700575 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700576}
577
578bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
579{
Glenn Kastendd976422013-02-13 14:46:45 -0800580 checkMagic();
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700581 if (value != devSampleRate || resampler != NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700582 if (sampleRate != value) {
583 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800584 if (resampler == NULL) {
Glenn Kastena6d41332012-10-01 14:04:31 -0700585 ALOGV("creating resampler from track %d Hz to device %d Hz", value, devSampleRate);
586 AudioResampler::src_quality quality;
587 // force lowest quality level resampler if use case isn't music or video
588 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
589 // quality level based on the initial ratio, but that could change later.
590 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
591 if (!((value == 44100 && devSampleRate == 48000) ||
592 (value == 48000 && devSampleRate == 44100))) {
593 quality = AudioResampler::LOW_QUALITY;
594 } else {
595 quality = AudioResampler::DEFAULT_QUALITY;
596 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700597 resampler = AudioResampler::create(
Jean-Michel Triviacb86cc2012-04-16 12:43:57 -0700598 format,
599 // the resampler sees the number of channels after the downmixer, if any
600 downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount,
Glenn Kastena6d41332012-10-01 14:04:31 -0700601 devSampleRate, quality);
Glenn Kasten52008f82012-03-18 09:34:41 -0700602 resampler->setLocalTimeFreq(sLocalTimeFreq);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700603 }
604 return true;
605 }
606 }
607 return false;
608}
609
Mathias Agopian65ab4712010-07-14 17:59:35 -0700610inline
611void AudioMixer::track_t::adjustVolumeRamp(bool aux)
612{
Glenn Kastendd976422013-02-13 14:46:45 -0800613 checkMagic();
Glenn Kastenf9a27772012-01-06 07:47:26 -0800614 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700615 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
616 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
617 volumeInc[i] = 0;
618 prevVolume[i] = volume[i]<<16;
619 }
620 }
621 if (aux) {
622 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
623 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
624 auxInc = 0;
625 prevAuxLevel = auxLevel<<16;
626 }
627 }
628}
629
Glenn Kastenc59c0042012-02-02 14:06:11 -0800630size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800631{
632 name -= TRACK0;
633 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800634 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800635 }
636 return 0;
637}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700638
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800639void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700640{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800641 name -= TRACK0;
Glenn Kastendd976422013-02-13 14:46:45 -0800642 mLog->logf("set bp %d=%p", name, bufferProvider);
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800643 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700644
Glenn Kastendd976422013-02-13 14:46:45 -0800645 mState.tracks[name].checkMagic();
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700646 if (mState.tracks[name].downmixerBufferProvider != NULL) {
647 // update required?
648 if (mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider != bufferProvider) {
649 ALOGV("AudioMixer::setBufferProvider(%p) for downmix", bufferProvider);
650 // setting the buffer provider for a track that gets downmixed consists in:
651 // 1/ setting the buffer provider to the "downmix / buffer provider" wrapper
652 // so it's the one that gets called when the buffer provider is needed,
653 mState.tracks[name].bufferProvider = mState.tracks[name].downmixerBufferProvider;
654 // 2/ saving the buffer provider for the track so the wrapper can use it
655 // when it downmixes.
656 mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider = bufferProvider;
657 }
658 } else {
659 mState.tracks[name].bufferProvider = bufferProvider;
660 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700661}
662
Glenn Kastendd976422013-02-13 14:46:45 -0800663AudioBufferProvider* AudioMixer::getBufferProvider(int name)
664{
665 name -= TRACK0;
666 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
667 mState.tracks[name].checkMagic();
668 return mState.tracks[name].bufferProvider;
669}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700670
Glenn Kastendd976422013-02-13 14:46:45 -0800671int AudioMixer::getFastIndex(int name)
672{
673 name -= TRACK0;
674 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
675 mState.tracks[name].checkMagic();
676 return mState.tracks[name].fastIndex;
677}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700678
John Grossman4ff14ba2012-02-08 16:37:41 -0800679void AudioMixer::process(int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700680{
Glenn Kastendd976422013-02-13 14:46:45 -0800681 if (mState.needsChanged) {
682 mLog->logf("process needs=%#x", mState.needsChanged);
683 }
John Grossman4ff14ba2012-02-08 16:37:41 -0800684 mState.hook(&mState, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700685}
686
687
John Grossman4ff14ba2012-02-08 16:37:41 -0800688void AudioMixer::process__validate(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700689{
Steve Block5ff1dd52012-01-05 23:22:43 +0000690 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700691 "in process__validate() but nothing's invalid");
692
693 uint32_t changed = state->needsChanged;
694 state->needsChanged = 0; // clear the validation flag
695
696 // recompute which tracks are enabled / disabled
697 uint32_t enabled = 0;
698 uint32_t disabled = 0;
699 while (changed) {
700 const int i = 31 - __builtin_clz(changed);
701 const uint32_t mask = 1<<i;
702 changed &= ~mask;
703 track_t& t = state->tracks[i];
704 (t.enabled ? enabled : disabled) |= mask;
705 }
706 state->enabledTracks &= ~disabled;
707 state->enabledTracks |= enabled;
Glenn Kastendd976422013-02-13 14:46:45 -0800708 state->mLog->logf("process_validate ena=%#x", state->enabledTracks);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700709
710 // compute everything we need...
711 int countActiveTracks = 0;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800712 bool all16BitsStereoNoResample = true;
713 bool resampling = false;
714 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700715 uint32_t en = state->enabledTracks;
716 while (en) {
717 const int i = 31 - __builtin_clz(en);
718 en &= ~(1<<i);
719
720 countActiveTracks++;
721 track_t& t = state->tracks[i];
722 uint32_t n = 0;
723 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
724 n |= NEEDS_FORMAT_16;
725 n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
726 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
727 n |= NEEDS_AUX_ENABLED;
728 }
729
730 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800731 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700732 } else if (!t.doesResample() && t.volumeRL == 0) {
733 n |= NEEDS_MUTE_ENABLED;
734 }
735 t.needs = n;
736
737 if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
738 t.hook = track__nop;
739 } else {
740 if ((n & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800741 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700742 }
743 if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800744 all16BitsStereoNoResample = false;
745 resampling = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700746 t.hook = track__genericResample;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700747 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700748 "Track %d needs downmix + resample", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700749 } else {
750 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
751 t.hook = track__16BitsMono;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800752 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700753 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700754 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Mathias Agopian65ab4712010-07-14 17:59:35 -0700755 t.hook = track__16BitsStereo;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700756 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700757 "Track %d needs downmix", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700758 }
759 }
760 }
761 }
762
763 // select the processing hooks
764 state->hook = process__nop;
765 if (countActiveTracks) {
766 if (resampling) {
767 if (!state->outputTemp) {
768 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
769 }
770 if (!state->resampleTemp) {
771 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
772 }
773 state->hook = process__genericResampling;
774 } else {
775 if (state->outputTemp) {
776 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800777 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700778 }
779 if (state->resampleTemp) {
780 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800781 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700782 }
783 state->hook = process__genericNoResampling;
784 if (all16BitsStereoNoResample && !volumeRamp) {
785 if (countActiveTracks == 1) {
786 state->hook = process__OneTrack16BitsStereoNoResampling;
787 }
788 }
789 }
790 }
791
Steve Block3856b092011-10-20 11:56:00 +0100792 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700793 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
794 countActiveTracks, state->enabledTracks,
795 all16BitsStereoNoResample, resampling, volumeRamp);
796
John Grossman4ff14ba2012-02-08 16:37:41 -0800797 state->hook(state, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700798
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800799 // Now that the volume ramp has been done, set optimal state and
800 // track hooks for subsequent mixer process
801 if (countActiveTracks) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800802 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800803 uint32_t en = state->enabledTracks;
804 while (en) {
805 const int i = 31 - __builtin_clz(en);
806 en &= ~(1<<i);
807 track_t& t = state->tracks[i];
808 if (!t.doesResample() && t.volumeRL == 0)
809 {
810 t.needs |= NEEDS_MUTE_ENABLED;
811 t.hook = track__nop;
812 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800813 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800814 }
815 }
816 if (allMuted) {
817 state->hook = process__nop;
818 } else if (all16BitsStereoNoResample) {
819 if (countActiveTracks == 1) {
820 state->hook = process__OneTrack16BitsStereoNoResampling;
821 }
822 }
823 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700824}
825
Mathias Agopian65ab4712010-07-14 17:59:35 -0700826
Glenn Kasten8af901c2012-11-01 11:11:38 -0700827void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount,
828 int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700829{
830 t->resampler->setSampleRate(t->sampleRate);
831
832 // ramp gain - resample to temp buffer and scale/mix in 2nd step
833 if (aux != NULL) {
834 // always resample with unity gain when sending to auxiliary buffer to be able
835 // to apply send level after resampling
836 // TODO: modify each resampler to support aux channel?
837 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
838 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
839 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -0800840 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700841 volumeRampStereo(t, out, outFrameCount, temp, aux);
842 } else {
843 volumeStereo(t, out, outFrameCount, temp, aux);
844 }
845 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -0800846 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700847 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
848 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
849 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
850 volumeRampStereo(t, out, outFrameCount, temp, aux);
851 }
852
853 // constant gain
854 else {
855 t->resampler->setVolume(t->volume[0], t->volume[1]);
856 t->resampler->resample(out, outFrameCount, t->bufferProvider);
857 }
858 }
859}
860
Glenn Kasten8af901c2012-11-01 11:11:38 -0700861void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp,
862 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700863{
864}
865
Glenn Kasten8af901c2012-11-01 11:11:38 -0700866void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
867 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700868{
869 int32_t vl = t->prevVolume[0];
870 int32_t vr = t->prevVolume[1];
871 const int32_t vlInc = t->volumeInc[0];
872 const int32_t vrInc = t->volumeInc[1];
873
Steve Blockb8a80522011-12-20 16:23:08 +0000874 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700875 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
876 // (vl + vlInc*frameCount)/65536.0f, frameCount);
877
878 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -0800879 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700880 int32_t va = t->prevAuxLevel;
881 const int32_t vaInc = t->auxInc;
882 int32_t l;
883 int32_t r;
884
885 do {
886 l = (*temp++ >> 12);
887 r = (*temp++ >> 12);
888 *out++ += (vl >> 16) * l;
889 *out++ += (vr >> 16) * r;
890 *aux++ += (va >> 17) * (l + r);
891 vl += vlInc;
892 vr += vrInc;
893 va += vaInc;
894 } while (--frameCount);
895 t->prevAuxLevel = va;
896 } else {
897 do {
898 *out++ += (vl >> 16) * (*temp++ >> 12);
899 *out++ += (vr >> 16) * (*temp++ >> 12);
900 vl += vlInc;
901 vr += vrInc;
902 } while (--frameCount);
903 }
904 t->prevVolume[0] = vl;
905 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -0800906 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700907}
908
Glenn Kasten8af901c2012-11-01 11:11:38 -0700909void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
910 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700911{
912 const int16_t vl = t->volume[0];
913 const int16_t vr = t->volume[1];
914
Glenn Kastenf6b16782011-12-15 09:51:17 -0800915 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800916 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700917 do {
918 int16_t l = (int16_t)(*temp++ >> 12);
919 int16_t r = (int16_t)(*temp++ >> 12);
920 out[0] = mulAdd(l, vl, out[0]);
921 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
922 out[1] = mulAdd(r, vr, out[1]);
923 out += 2;
924 aux[0] = mulAdd(a, va, aux[0]);
925 aux++;
926 } while (--frameCount);
927 } else {
928 do {
929 int16_t l = (int16_t)(*temp++ >> 12);
930 int16_t r = (int16_t)(*temp++ >> 12);
931 out[0] = mulAdd(l, vl, out[0]);
932 out[1] = mulAdd(r, vr, out[1]);
933 out += 2;
934 } while (--frameCount);
935 }
936}
937
Glenn Kasten8af901c2012-11-01 11:11:38 -0700938void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
939 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700940{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800941 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700942
Glenn Kastenf6b16782011-12-15 09:51:17 -0800943 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700944 int32_t l;
945 int32_t r;
946 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800947 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700948 int32_t vl = t->prevVolume[0];
949 int32_t vr = t->prevVolume[1];
950 int32_t va = t->prevAuxLevel;
951 const int32_t vlInc = t->volumeInc[0];
952 const int32_t vrInc = t->volumeInc[1];
953 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +0000954 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700955 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
956 // (vl + vlInc*frameCount)/65536.0f, frameCount);
957
958 do {
959 l = (int32_t)*in++;
960 r = (int32_t)*in++;
961 *out++ += (vl >> 16) * l;
962 *out++ += (vr >> 16) * r;
963 *aux++ += (va >> 17) * (l + r);
964 vl += vlInc;
965 vr += vrInc;
966 va += vaInc;
967 } while (--frameCount);
968
969 t->prevVolume[0] = vl;
970 t->prevVolume[1] = vr;
971 t->prevAuxLevel = va;
972 t->adjustVolumeRamp(true);
973 }
974
975 // constant gain
976 else {
977 const uint32_t vrl = t->volumeRL;
978 const int16_t va = (int16_t)t->auxLevel;
979 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800980 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700981 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
982 in += 2;
983 out[0] = mulAddRL(1, rl, vrl, out[0]);
984 out[1] = mulAddRL(0, rl, vrl, out[1]);
985 out += 2;
986 aux[0] = mulAdd(a, va, aux[0]);
987 aux++;
988 } while (--frameCount);
989 }
990 } else {
991 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800992 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700993 int32_t vl = t->prevVolume[0];
994 int32_t vr = t->prevVolume[1];
995 const int32_t vlInc = t->volumeInc[0];
996 const int32_t vrInc = t->volumeInc[1];
997
Steve Blockb8a80522011-12-20 16:23:08 +0000998 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700999 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1000 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1001
1002 do {
1003 *out++ += (vl >> 16) * (int32_t) *in++;
1004 *out++ += (vr >> 16) * (int32_t) *in++;
1005 vl += vlInc;
1006 vr += vrInc;
1007 } while (--frameCount);
1008
1009 t->prevVolume[0] = vl;
1010 t->prevVolume[1] = vr;
1011 t->adjustVolumeRamp(false);
1012 }
1013
1014 // constant gain
1015 else {
1016 const uint32_t vrl = t->volumeRL;
1017 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001018 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001019 in += 2;
1020 out[0] = mulAddRL(1, rl, vrl, out[0]);
1021 out[1] = mulAddRL(0, rl, vrl, out[1]);
1022 out += 2;
1023 } while (--frameCount);
1024 }
1025 }
1026 t->in = in;
1027}
1028
Glenn Kasten8af901c2012-11-01 11:11:38 -07001029void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1030 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001031{
Glenn Kasten54c3b662012-01-06 07:46:30 -08001032 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001033
Glenn Kastenf6b16782011-12-15 09:51:17 -08001034 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001035 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001036 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001037 int32_t vl = t->prevVolume[0];
1038 int32_t vr = t->prevVolume[1];
1039 int32_t va = t->prevAuxLevel;
1040 const int32_t vlInc = t->volumeInc[0];
1041 const int32_t vrInc = t->volumeInc[1];
1042 const int32_t vaInc = t->auxInc;
1043
Steve Blockb8a80522011-12-20 16:23:08 +00001044 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001045 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1046 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1047
1048 do {
1049 int32_t l = *in++;
1050 *out++ += (vl >> 16) * l;
1051 *out++ += (vr >> 16) * l;
1052 *aux++ += (va >> 16) * l;
1053 vl += vlInc;
1054 vr += vrInc;
1055 va += vaInc;
1056 } while (--frameCount);
1057
1058 t->prevVolume[0] = vl;
1059 t->prevVolume[1] = vr;
1060 t->prevAuxLevel = va;
1061 t->adjustVolumeRamp(true);
1062 }
1063 // constant gain
1064 else {
1065 const int16_t vl = t->volume[0];
1066 const int16_t vr = t->volume[1];
1067 const int16_t va = (int16_t)t->auxLevel;
1068 do {
1069 int16_t l = *in++;
1070 out[0] = mulAdd(l, vl, out[0]);
1071 out[1] = mulAdd(l, vr, out[1]);
1072 out += 2;
1073 aux[0] = mulAdd(l, va, aux[0]);
1074 aux++;
1075 } while (--frameCount);
1076 }
1077 } else {
1078 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001079 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001080 int32_t vl = t->prevVolume[0];
1081 int32_t vr = t->prevVolume[1];
1082 const int32_t vlInc = t->volumeInc[0];
1083 const int32_t vrInc = t->volumeInc[1];
1084
Steve Blockb8a80522011-12-20 16:23:08 +00001085 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001086 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1087 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1088
1089 do {
1090 int32_t l = *in++;
1091 *out++ += (vl >> 16) * l;
1092 *out++ += (vr >> 16) * l;
1093 vl += vlInc;
1094 vr += vrInc;
1095 } while (--frameCount);
1096
1097 t->prevVolume[0] = vl;
1098 t->prevVolume[1] = vr;
1099 t->adjustVolumeRamp(false);
1100 }
1101 // constant gain
1102 else {
1103 const int16_t vl = t->volume[0];
1104 const int16_t vr = t->volume[1];
1105 do {
1106 int16_t l = *in++;
1107 out[0] = mulAdd(l, vl, out[0]);
1108 out[1] = mulAdd(l, vr, out[1]);
1109 out += 2;
1110 } while (--frameCount);
1111 }
1112 }
1113 t->in = in;
1114}
1115
Mathias Agopian65ab4712010-07-14 17:59:35 -07001116// no-op case
John Grossman4ff14ba2012-02-08 16:37:41 -08001117void AudioMixer::process__nop(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001118{
1119 uint32_t e0 = state->enabledTracks;
Glenn Kastendd976422013-02-13 14:46:45 -08001120 state->mLog->logf("process_nop ena=%#x", e0);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001121 size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS;
1122 while (e0) {
1123 // process by group of tracks with same output buffer to
1124 // avoid multiple memset() on same buffer
1125 uint32_t e1 = e0, e2 = e0;
1126 int i = 31 - __builtin_clz(e1);
1127 track_t& t1 = state->tracks[i];
1128 e2 &= ~(1<<i);
1129 while (e2) {
1130 i = 31 - __builtin_clz(e2);
1131 e2 &= ~(1<<i);
1132 track_t& t2 = state->tracks[i];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001133 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001134 e1 &= ~(1<<i);
1135 }
1136 }
1137 e0 &= ~(e1);
1138
1139 memset(t1.mainBuffer, 0, bufSize);
1140
1141 while (e1) {
1142 i = 31 - __builtin_clz(e1);
1143 e1 &= ~(1<<i);
1144 t1 = state->tracks[i];
1145 size_t outFrames = state->frameCount;
1146 while (outFrames) {
1147 t1.buffer.frameCount = outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001148 int64_t outputPTS = calculateOutputPTS(
1149 t1, pts, state->frameCount - outFrames);
1150 t1.bufferProvider->getNextBuffer(&t1.buffer, outputPTS);
Glenn Kastena0d68332012-01-27 16:47:15 -08001151 if (t1.buffer.raw == NULL) break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001152 outFrames -= t1.buffer.frameCount;
1153 t1.bufferProvider->releaseBuffer(&t1.buffer);
1154 }
1155 }
1156 }
1157}
1158
1159// generic code without resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001160void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001161{
1162 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1163
1164 // acquire each track's buffer
1165 uint32_t enabledTracks = state->enabledTracks;
Glenn Kastendd976422013-02-13 14:46:45 -08001166 state->mLog->logf("process_gNR ena=%#x", enabledTracks);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001167 uint32_t e0 = enabledTracks;
1168 while (e0) {
1169 const int i = 31 - __builtin_clz(e0);
1170 e0 &= ~(1<<i);
1171 track_t& t = state->tracks[i];
1172 t.buffer.frameCount = state->frameCount;
Glenn Kastenef5abc32012-12-07 14:13:35 -08001173 int valid = t.bufferProvider->getValid();
1174 if (valid != AudioBufferProvider::kValid) {
Glenn Kastendd976422013-02-13 14:46:45 -08001175 ALOGE("invalid bufferProvider=%p name=%d fastIndex=%d frameCount=%d valid=%#x enabledTracks=%#x",
1176 t.bufferProvider, i, t.fastIndex, t.buffer.frameCount, valid, enabledTracks);
Glenn Kastenef5abc32012-12-07 14:13:35 -08001177 // expect to crash
1178 }
John Grossman4ff14ba2012-02-08 16:37:41 -08001179 t.bufferProvider->getNextBuffer(&t.buffer, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001180 t.frameCount = t.buffer.frameCount;
1181 t.in = t.buffer.raw;
1182 // t.in == NULL can happen if the track was flushed just after having
1183 // been enabled for mixing.
1184 if (t.in == NULL)
1185 enabledTracks &= ~(1<<i);
1186 }
1187
1188 e0 = enabledTracks;
1189 while (e0) {
1190 // process by group of tracks with same output buffer to
1191 // optimize cache use
1192 uint32_t e1 = e0, e2 = e0;
1193 int j = 31 - __builtin_clz(e1);
1194 track_t& t1 = state->tracks[j];
1195 e2 &= ~(1<<j);
1196 while (e2) {
1197 j = 31 - __builtin_clz(e2);
1198 e2 &= ~(1<<j);
1199 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001200 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001201 e1 &= ~(1<<j);
1202 }
1203 }
1204 e0 &= ~(e1);
1205 // this assumes output 16 bits stereo, no resampling
1206 int32_t *out = t1.mainBuffer;
1207 size_t numFrames = 0;
1208 do {
1209 memset(outTemp, 0, sizeof(outTemp));
1210 e2 = e1;
1211 while (e2) {
1212 const int i = 31 - __builtin_clz(e2);
1213 e2 &= ~(1<<i);
1214 track_t& t = state->tracks[i];
1215 size_t outFrames = BLOCKSIZE;
1216 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001217 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001218 aux = t.auxBuffer + numFrames;
1219 }
1220 while (outFrames) {
1221 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
1222 if (inFrames) {
Glenn Kasten8af901c2012-11-01 11:11:38 -07001223 t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames,
1224 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001225 t.frameCount -= inFrames;
1226 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001227 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001228 aux += inFrames;
1229 }
1230 }
1231 if (t.frameCount == 0 && outFrames) {
1232 t.bufferProvider->releaseBuffer(&t.buffer);
Glenn Kasten8af901c2012-11-01 11:11:38 -07001233 t.buffer.frameCount = (state->frameCount - numFrames) -
1234 (BLOCKSIZE - outFrames);
John Grossman4ff14ba2012-02-08 16:37:41 -08001235 int64_t outputPTS = calculateOutputPTS(
1236 t, pts, numFrames + (BLOCKSIZE - outFrames));
1237 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001238 t.in = t.buffer.raw;
1239 if (t.in == NULL) {
1240 enabledTracks &= ~(1<<i);
1241 e1 &= ~(1<<i);
1242 break;
1243 }
1244 t.frameCount = t.buffer.frameCount;
1245 }
1246 }
1247 }
1248 ditherAndClamp(out, outTemp, BLOCKSIZE);
1249 out += BLOCKSIZE;
1250 numFrames += BLOCKSIZE;
1251 } while (numFrames < state->frameCount);
1252 }
1253
1254 // release each track's buffer
1255 e0 = enabledTracks;
1256 while (e0) {
1257 const int i = 31 - __builtin_clz(e0);
1258 e0 &= ~(1<<i);
1259 track_t& t = state->tracks[i];
1260 t.bufferProvider->releaseBuffer(&t.buffer);
1261 }
1262}
1263
1264
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001265// generic code with resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001266void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001267{
Glenn Kasten54c3b662012-01-06 07:46:30 -08001268 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -07001269 int32_t* const outTemp = state->outputTemp;
1270 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001271
1272 size_t numFrames = state->frameCount;
1273
1274 uint32_t e0 = state->enabledTracks;
Glenn Kastendd976422013-02-13 14:46:45 -08001275 state->mLog->logf("process_gR ena=%#x", e0);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001276 while (e0) {
1277 // process by group of tracks with same output buffer
1278 // to optimize cache use
1279 uint32_t e1 = e0, e2 = e0;
1280 int j = 31 - __builtin_clz(e1);
1281 track_t& t1 = state->tracks[j];
1282 e2 &= ~(1<<j);
1283 while (e2) {
1284 j = 31 - __builtin_clz(e2);
1285 e2 &= ~(1<<j);
1286 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001287 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001288 e1 &= ~(1<<j);
1289 }
1290 }
1291 e0 &= ~(e1);
1292 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +01001293 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001294 while (e1) {
1295 const int i = 31 - __builtin_clz(e1);
1296 e1 &= ~(1<<i);
1297 track_t& t = state->tracks[i];
1298 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001299 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001300 aux = t.auxBuffer;
1301 }
1302
1303 // this is a little goofy, on the resampling case we don't
1304 // acquire/release the buffers because it's done by
1305 // the resampler.
1306 if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001307 t.resampler->setPTS(pts);
Glenn Kastena1117922012-01-26 10:53:32 -08001308 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001309 } else {
1310
1311 size_t outFrames = 0;
1312
1313 while (outFrames < numFrames) {
1314 t.buffer.frameCount = numFrames - outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001315 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
1316 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001317 t.in = t.buffer.raw;
1318 // t.in == NULL can happen if the track was flushed just after having
1319 // been enabled for mixing.
1320 if (t.in == NULL) break;
1321
Glenn Kastenf6b16782011-12-15 09:51:17 -08001322 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001323 aux += outFrames;
1324 }
Glenn Kasten8af901c2012-11-01 11:11:38 -07001325 t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount,
1326 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001327 outFrames += t.buffer.frameCount;
1328 t.bufferProvider->releaseBuffer(&t.buffer);
1329 }
1330 }
1331 }
1332 ditherAndClamp(out, outTemp, numFrames);
1333 }
1334}
1335
1336// one track, 16 bits stereo without resampling is the most common case
John Grossman4ff14ba2012-02-08 16:37:41 -08001337void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
1338 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001339{
Glenn Kastendd976422013-02-13 14:46:45 -08001340 state->mLog->logf("process_1TSNR ena=%#x", state->enabledTracks);
Glenn Kasten99e53b82012-01-19 08:59:58 -08001341 // This method is only called when state->enabledTracks has exactly
1342 // one bit set. The asserts below would verify this, but are commented out
1343 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001344 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001345 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001346 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001347 const track_t& t = state->tracks[i];
1348
1349 AudioBufferProvider::Buffer& b(t.buffer);
1350
1351 int32_t* out = t.mainBuffer;
1352 size_t numFrames = state->frameCount;
1353
1354 const int16_t vl = t.volume[0];
1355 const int16_t vr = t.volume[1];
1356 const uint32_t vrl = t.volumeRL;
1357 while (numFrames) {
1358 b.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001359 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
1360 t.bufferProvider->getNextBuffer(&b, outputPTS);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001361 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001362
1363 // in == NULL can happen if the track was flushed just after having
1364 // been enabled for mixing.
1365 if (in == NULL || ((unsigned long)in & 3)) {
1366 memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
Glenn Kasten8af901c2012-11-01 11:11:38 -07001367 ALOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: "
1368 "buffer %p track %d, channels %d, needs %08x",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001369 in, i, t.channelCount, t.needs);
1370 return;
1371 }
1372 size_t outFrames = b.frameCount;
1373
Glenn Kastenf6b16782011-12-15 09:51:17 -08001374 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001375 // volume is boosted, so we might need to clamp even though
1376 // we process only one track.
1377 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001378 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001379 in += 2;
1380 int32_t l = mulRL(1, rl, vrl) >> 12;
1381 int32_t r = mulRL(0, rl, vrl) >> 12;
1382 // clamping...
1383 l = clamp16(l);
1384 r = clamp16(r);
1385 *out++ = (r<<16) | (l & 0xFFFF);
1386 } while (--outFrames);
1387 } else {
1388 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001389 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001390 in += 2;
1391 int32_t l = mulRL(1, rl, vrl) >> 12;
1392 int32_t r = mulRL(0, rl, vrl) >> 12;
1393 *out++ = (r<<16) | (l & 0xFFFF);
1394 } while (--outFrames);
1395 }
1396 numFrames -= b.frameCount;
1397 t.bufferProvider->releaseBuffer(&b);
1398 }
1399}
1400
Glenn Kasten81a028f2011-12-15 09:53:12 -08001401#if 0
Mathias Agopian65ab4712010-07-14 17:59:35 -07001402// 2 tracks is also a common case
1403// NEVER used in current implementation of process__validate()
1404// only use if the 2 tracks have the same output buffer
John Grossman4ff14ba2012-02-08 16:37:41 -08001405void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state,
1406 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001407{
1408 int i;
1409 uint32_t en = state->enabledTracks;
Glenn Kastendd976422013-02-13 14:46:45 -08001410 state->mLog->logf("process_2TSNR ena=%#x", en);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001411
1412 i = 31 - __builtin_clz(en);
1413 const track_t& t0 = state->tracks[i];
1414 AudioBufferProvider::Buffer& b0(t0.buffer);
1415
1416 en &= ~(1<<i);
1417 i = 31 - __builtin_clz(en);
1418 const track_t& t1 = state->tracks[i];
1419 AudioBufferProvider::Buffer& b1(t1.buffer);
1420
Glenn Kasten54c3b662012-01-06 07:46:30 -08001421 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001422 const int16_t vl0 = t0.volume[0];
1423 const int16_t vr0 = t0.volume[1];
1424 size_t frameCount0 = 0;
1425
Glenn Kasten54c3b662012-01-06 07:46:30 -08001426 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001427 const int16_t vl1 = t1.volume[0];
1428 const int16_t vr1 = t1.volume[1];
1429 size_t frameCount1 = 0;
1430
1431 //FIXME: only works if two tracks use same buffer
1432 int32_t* out = t0.mainBuffer;
1433 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001434 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001435
1436
1437 while (numFrames) {
1438
1439 if (frameCount0 == 0) {
1440 b0.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001441 int64_t outputPTS = calculateOutputPTS(t0, pts,
1442 out - t0.mainBuffer);
1443 t0.bufferProvider->getNextBuffer(&b0, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001444 if (b0.i16 == NULL) {
1445 if (buff == NULL) {
1446 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1447 }
1448 in0 = buff;
1449 b0.frameCount = numFrames;
1450 } else {
1451 in0 = b0.i16;
1452 }
1453 frameCount0 = b0.frameCount;
1454 }
1455 if (frameCount1 == 0) {
1456 b1.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001457 int64_t outputPTS = calculateOutputPTS(t1, pts,
1458 out - t0.mainBuffer);
1459 t1.bufferProvider->getNextBuffer(&b1, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001460 if (b1.i16 == NULL) {
1461 if (buff == NULL) {
1462 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1463 }
1464 in1 = buff;
1465 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001466 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001467 in1 = b1.i16;
1468 }
1469 frameCount1 = b1.frameCount;
1470 }
1471
1472 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1473
1474 numFrames -= outFrames;
1475 frameCount0 -= outFrames;
1476 frameCount1 -= outFrames;
1477
1478 do {
1479 int32_t l0 = *in0++;
1480 int32_t r0 = *in0++;
1481 l0 = mul(l0, vl0);
1482 r0 = mul(r0, vr0);
1483 int32_t l = *in1++;
1484 int32_t r = *in1++;
1485 l = mulAdd(l, vl1, l0) >> 12;
1486 r = mulAdd(r, vr1, r0) >> 12;
1487 // clamping...
1488 l = clamp16(l);
1489 r = clamp16(r);
1490 *out++ = (r<<16) | (l & 0xFFFF);
1491 } while (--outFrames);
1492
1493 if (frameCount0 == 0) {
1494 t0.bufferProvider->releaseBuffer(&b0);
1495 }
1496 if (frameCount1 == 0) {
1497 t1.bufferProvider->releaseBuffer(&b1);
1498 }
1499 }
1500
Glenn Kastene9dd0172012-01-27 18:08:45 -08001501 delete [] buff;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001502}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001503#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001504
John Grossman4ff14ba2012-02-08 16:37:41 -08001505int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1506 int outputFrameIndex)
1507{
1508 if (AudioBufferProvider::kInvalidPTS == basePTS)
1509 return AudioBufferProvider::kInvalidPTS;
1510
Glenn Kasten52008f82012-03-18 09:34:41 -07001511 return basePTS + ((outputFrameIndex * sLocalTimeFreq) / t.sampleRate);
1512}
1513
1514/*static*/ uint64_t AudioMixer::sLocalTimeFreq;
1515/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1516
1517/*static*/ void AudioMixer::sInitRoutine()
1518{
1519 LocalClock lc;
1520 sLocalTimeFreq = lc.getLocalFreq();
John Grossman4ff14ba2012-02-08 16:37:41 -08001521}
1522
Mathias Agopian65ab4712010-07-14 17:59:35 -07001523// ----------------------------------------------------------------------------
1524}; // namespace android