blob: 342364e76835f0025fe989846c8e9bf239895dc5 [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>
25#include <sys/types.h>
26
27#include <utils/Errors.h>
28#include <utils/Log.h>
29
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070030#include <cutils/bitops.h>
Glenn Kastenf6b16782011-12-15 09:51:17 -080031#include <cutils/compiler.h>
Glenn Kasten5798d4e2012-03-08 12:18:35 -080032#include <utils/Debug.h>
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070033
34#include <system/audio.h>
35
Glenn Kasten3b21c502011-12-15 09:52:39 -080036#include <audio_utils/primitives.h>
John Grossman4ff14ba2012-02-08 16:37:41 -080037#include <common_time/local_clock.h>
38#include <common_time/cc_helper.h>
Glenn Kasten3b21c502011-12-15 09:52:39 -080039
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070040#include <media/EffectsFactoryApi.h>
41
Mathias Agopian65ab4712010-07-14 17:59:35 -070042#include "AudioMixer.h"
43
44namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070045
46// ----------------------------------------------------------------------------
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070047AudioMixer::DownmixerBufferProvider::DownmixerBufferProvider() : AudioBufferProvider(),
48 mTrackBufferProvider(NULL), mDownmixHandle(NULL)
49{
50}
51
52AudioMixer::DownmixerBufferProvider::~DownmixerBufferProvider()
53{
54 ALOGV("AudioMixer deleting DownmixerBufferProvider (%p)", this);
55 EffectRelease(mDownmixHandle);
56}
57
58status_t AudioMixer::DownmixerBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer,
59 int64_t pts) {
60 //ALOGV("DownmixerBufferProvider::getNextBuffer()");
Glenn Kasten8f325372013-10-30 14:36:47 -070061 if (mTrackBufferProvider != NULL) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070062 status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts);
63 if (res == OK) {
64 mDownmixConfig.inputCfg.buffer.frameCount = pBuffer->frameCount;
65 mDownmixConfig.inputCfg.buffer.raw = pBuffer->raw;
66 mDownmixConfig.outputCfg.buffer.frameCount = pBuffer->frameCount;
67 mDownmixConfig.outputCfg.buffer.raw = mDownmixConfig.inputCfg.buffer.raw;
68 // in-place so overwrite the buffer contents, has been set in prepareTrackForDownmix()
69 //mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
70
71 res = (*mDownmixHandle)->process(mDownmixHandle,
72 &mDownmixConfig.inputCfg.buffer, &mDownmixConfig.outputCfg.buffer);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -070073 //ALOGV("getNextBuffer is downmixing");
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070074 }
75 return res;
76 } else {
77 ALOGE("DownmixerBufferProvider::getNextBuffer() error: NULL track buffer provider");
78 return NO_INIT;
79 }
80}
81
82void AudioMixer::DownmixerBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -070083 //ALOGV("DownmixerBufferProvider::releaseBuffer()");
Glenn Kasten8f325372013-10-30 14:36:47 -070084 if (mTrackBufferProvider != NULL) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070085 mTrackBufferProvider->releaseBuffer(pBuffer);
86 } else {
87 ALOGE("DownmixerBufferProvider::releaseBuffer() error: NULL track buffer provider");
88 }
89}
90
91
92// ----------------------------------------------------------------------------
Glenn Kasten49c34ac2013-10-30 14:37:01 -070093bool AudioMixer::sIsMultichannelCapable = false;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070094
Glenn Kasten49c34ac2013-10-30 14:37:01 -070095effect_descriptor_t AudioMixer::sDwnmFxDesc;
Mathias Agopian65ab4712010-07-14 17:59:35 -070096
Paul Lind3c0a0e82012-08-01 18:49:49 -070097// Ensure mConfiguredNames bitmask is initialized properly on all architectures.
98// The value of 1 << x is undefined in C when x >= 32.
99
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700100AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks)
Paul Lind3c0a0e82012-08-01 18:49:49 -0700101 : mTrackNames(0), mConfiguredNames((maxNumTracks >= 32 ? 0 : 1 << maxNumTracks) - 1),
Glenn Kasten7f5d3352013-02-15 23:55:04 +0000102 mSampleRate(sampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700103{
Glenn Kasten788040c2011-05-05 08:19:00 -0700104 // AudioMixer is not yet capable of multi-channel beyond stereo
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800105 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(2 == MAX_NUM_CHANNELS);
Jean-Michel Triviacb86cc2012-04-16 12:43:57 -0700106
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700107 ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u",
108 maxNumTracks, MAX_NUM_TRACKS);
109
Glenn Kasten599fabc2012-03-08 12:33:37 -0800110 // AudioMixer is not yet capable of more than 32 active track inputs
111 ALOG_ASSERT(32 >= MAX_NUM_TRACKS, "bad MAX_NUM_TRACKS %d", MAX_NUM_TRACKS);
112
113 // AudioMixer is not yet capable of multi-channel output beyond stereo
114 ALOG_ASSERT(2 == MAX_NUM_CHANNELS, "bad MAX_NUM_CHANNELS %d", MAX_NUM_CHANNELS);
115
Glenn Kasten52008f82012-03-18 09:34:41 -0700116 pthread_once(&sOnceControl, &sInitRoutine);
117
Mathias Agopian65ab4712010-07-14 17:59:35 -0700118 mState.enabledTracks= 0;
119 mState.needsChanged = 0;
120 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800121 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -0800122 mState.outputTemp = NULL;
123 mState.resampleTemp = NULL;
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800124 mState.mLog = &mDummyLog;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800125 // mState.reserved
Glenn Kasten17a736c2012-02-14 08:52:15 -0800126
127 // FIXME Most of the following initialization is probably redundant since
128 // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0
129 // and mTrackNames is initially 0. However, leave it here until that's verified.
Mathias Agopian65ab4712010-07-14 17:59:35 -0700130 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800131 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Eric Laurenta5e82142012-04-16 13:47:17 -0700132 t->resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700133 t->downmixerBufferProvider = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700134 t++;
135 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700136
Mathias Agopian65ab4712010-07-14 17:59:35 -0700137}
138
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800139AudioMixer::~AudioMixer()
140{
141 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800142 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800143 delete t->resampler;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700144 delete t->downmixerBufferProvider;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800145 t++;
146 }
147 delete [] mState.outputTemp;
148 delete [] mState.resampleTemp;
149}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700150
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800151void AudioMixer::setLog(NBLog::Writer *log)
152{
153 mState.mLog = log;
154}
155
Andy Hunge8a1ced2014-05-09 15:02:21 -0700156int AudioMixer::getTrackName(audio_channel_mask_t channelMask,
157 audio_format_t format, int sessionId)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800158{
Andy Hunge8a1ced2014-05-09 15:02:21 -0700159 if (!isValidPcmTrackFormat(format)) {
160 ALOGE("AudioMixer::getTrackName invalid format (%#x)", format);
161 return -1;
162 }
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700163 uint32_t names = (~mTrackNames) & mConfiguredNames;
Glenn Kasten98dd5422011-12-15 14:38:29 -0800164 if (names != 0) {
165 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100166 ALOGV("add track (%d)", n);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700167 // assume default parameters for the track, except where noted below
168 track_t* t = &mState.tracks[n];
169 t->needs = 0;
170 t->volume[0] = UNITY_GAIN;
171 t->volume[1] = UNITY_GAIN;
172 // no initialization needed
173 // t->prevVolume[0]
174 // t->prevVolume[1]
175 t->volumeInc[0] = 0;
176 t->volumeInc[1] = 0;
177 t->auxLevel = 0;
178 t->auxInc = 0;
179 // no initialization needed
180 // t->prevAuxLevel
181 // t->frameCount
Andy Hung68112fc2014-05-14 14:13:23 -0700182 t->channelCount = audio_channel_count_from_out_mask(channelMask);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700183 t->enabled = false;
184 t->format = 16;
Andy Hung68112fc2014-05-14 14:13:23 -0700185 t->channelMask = channelMask;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700186 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700187 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
188 t->bufferProvider = NULL;
189 t->buffer.raw = NULL;
190 // no initialization needed
191 // t->buffer.frameCount
192 t->hook = NULL;
193 t->in = NULL;
194 t->resampler = NULL;
195 t->sampleRate = mSampleRate;
196 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
197 t->mainBuffer = NULL;
198 t->auxBuffer = NULL;
Glenn Kasten52008f82012-03-18 09:34:41 -0700199 t->downmixerBufferProvider = NULL;
Andy Hung78820702014-02-28 16:23:02 -0800200 t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
Andy Hunge8a1ced2014-05-09 15:02:21 -0700201 t->mFormat = format;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700202 status_t status = initTrackDownmix(&mState.tracks[n], n, channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700203 if (status != OK) {
204 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
205 return -1;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700206 }
Andy Hung68112fc2014-05-14 14:13:23 -0700207 mTrackNames |= 1 << n;
208 return TRACK0 + n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700209 }
Andy Hung68112fc2014-05-14 14:13:23 -0700210 ALOGE("AudioMixer::getTrackName out of available tracks");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700211 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800212}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700213
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800214void AudioMixer::invalidateState(uint32_t mask)
215{
Glenn Kasten34fca342013-08-13 09:48:14 -0700216 if (mask != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700217 mState.needsChanged |= mask;
218 mState.hook = process__validate;
219 }
220 }
221
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700222status_t AudioMixer::initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask)
223{
Andy Hunge5412692014-05-16 11:25:07 -0700224 uint32_t channelCount = audio_channel_count_from_out_mask(mask);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700225 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
226 status_t status = OK;
227 if (channelCount > MAX_NUM_CHANNELS) {
228 pTrack->channelMask = mask;
229 pTrack->channelCount = channelCount;
230 ALOGV("initTrackDownmix(track=%d, mask=0x%x) calls prepareTrackForDownmix()",
231 trackNum, mask);
232 status = prepareTrackForDownmix(pTrack, trackNum);
233 } else {
234 unprepareTrackForDownmix(pTrack, trackNum);
235 }
236 return status;
237}
238
Andy Hungee931ff2014-01-28 13:44:14 -0800239void AudioMixer::unprepareTrackForDownmix(track_t* pTrack, int trackName __unused) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700240 ALOGV("AudioMixer::unprepareTrackForDownmix(%d)", trackName);
241
242 if (pTrack->downmixerBufferProvider != NULL) {
243 // this track had previously been configured with a downmixer, delete it
244 ALOGV(" deleting old downmixer");
245 pTrack->bufferProvider = pTrack->downmixerBufferProvider->mTrackBufferProvider;
246 delete pTrack->downmixerBufferProvider;
247 pTrack->downmixerBufferProvider = NULL;
248 } else {
249 ALOGV(" nothing to do, no downmixer to delete");
250 }
251}
252
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700253status_t AudioMixer::prepareTrackForDownmix(track_t* pTrack, int trackName)
254{
255 ALOGV("AudioMixer::prepareTrackForDownmix(%d) with mask 0x%x", trackName, pTrack->channelMask);
256
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700257 // discard the previous downmixer if there was one
258 unprepareTrackForDownmix(pTrack, trackName);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700259
260 DownmixerBufferProvider* pDbp = new DownmixerBufferProvider();
261 int32_t status;
262
Glenn Kasten49c34ac2013-10-30 14:37:01 -0700263 if (!sIsMultichannelCapable) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700264 ALOGE("prepareTrackForDownmix(%d) fails: mixer doesn't support multichannel content",
265 trackName);
266 goto noDownmixForActiveTrack;
267 }
268
Glenn Kasten49c34ac2013-10-30 14:37:01 -0700269 if (EffectCreate(&sDwnmFxDesc.uuid,
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700270 pTrack->sessionId /*sessionId*/, -2 /*ioId not relevant here, using random value*/,
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700271 &pDbp->mDownmixHandle/*pHandle*/) != 0) {
272 ALOGE("prepareTrackForDownmix(%d) fails: error creating downmixer effect", trackName);
273 goto noDownmixForActiveTrack;
274 }
275
276 // channel input configuration will be overridden per-track
277 pDbp->mDownmixConfig.inputCfg.channels = pTrack->channelMask;
278 pDbp->mDownmixConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
279 pDbp->mDownmixConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
280 pDbp->mDownmixConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
281 pDbp->mDownmixConfig.inputCfg.samplingRate = pTrack->sampleRate;
282 pDbp->mDownmixConfig.outputCfg.samplingRate = pTrack->sampleRate;
283 pDbp->mDownmixConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
284 pDbp->mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
285 // input and output buffer provider, and frame count will not be used as the downmix effect
286 // process() function is called directly (see DownmixerBufferProvider::getNextBuffer())
287 pDbp->mDownmixConfig.inputCfg.mask = EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS |
288 EFFECT_CONFIG_FORMAT | EFFECT_CONFIG_ACC_MODE;
289 pDbp->mDownmixConfig.outputCfg.mask = pDbp->mDownmixConfig.inputCfg.mask;
290
291 {// scope for local variables that are not used in goto label "noDownmixForActiveTrack"
292 int cmdStatus;
293 uint32_t replySize = sizeof(int);
294
295 // Configure and enable downmixer
296 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
297 EFFECT_CMD_SET_CONFIG /*cmdCode*/, sizeof(effect_config_t) /*cmdSize*/,
298 &pDbp->mDownmixConfig /*pCmdData*/,
299 &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
300 if ((status != 0) || (cmdStatus != 0)) {
301 ALOGE("error %d while configuring downmixer for track %d", status, trackName);
302 goto noDownmixForActiveTrack;
303 }
304 replySize = sizeof(int);
305 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
306 EFFECT_CMD_ENABLE /*cmdCode*/, 0 /*cmdSize*/, NULL /*pCmdData*/,
307 &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
308 if ((status != 0) || (cmdStatus != 0)) {
309 ALOGE("error %d while enabling downmixer for track %d", status, trackName);
310 goto noDownmixForActiveTrack;
311 }
312
313 // Set downmix type
314 // parameter size rounded for padding on 32bit boundary
315 const int psizePadded = ((sizeof(downmix_params_t) - 1)/sizeof(int) + 1) * sizeof(int);
316 const int downmixParamSize =
317 sizeof(effect_param_t) + psizePadded + sizeof(downmix_type_t);
318 effect_param_t * const param = (effect_param_t *) malloc(downmixParamSize);
319 param->psize = sizeof(downmix_params_t);
320 const downmix_params_t downmixParam = DOWNMIX_PARAM_TYPE;
321 memcpy(param->data, &downmixParam, param->psize);
322 const downmix_type_t downmixType = DOWNMIX_TYPE_FOLD;
323 param->vsize = sizeof(downmix_type_t);
324 memcpy(param->data + psizePadded, &downmixType, param->vsize);
325
326 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
327 EFFECT_CMD_SET_PARAM /* cmdCode */, downmixParamSize/* cmdSize */,
328 param /*pCmndData*/, &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
329
330 free(param);
331
332 if ((status != 0) || (cmdStatus != 0)) {
333 ALOGE("error %d while setting downmix type for track %d", status, trackName);
334 goto noDownmixForActiveTrack;
335 } else {
336 ALOGV("downmix type set to %d for track %d", (int) downmixType, trackName);
337 }
338 }// end of scope for local variables that are not used in goto label "noDownmixForActiveTrack"
339
340 // initialization successful:
341 // - keep track of the real buffer provider in case it was set before
342 pDbp->mTrackBufferProvider = pTrack->bufferProvider;
343 // - we'll use the downmix effect integrated inside this
344 // track's buffer provider, and we'll use it as the track's buffer provider
345 pTrack->downmixerBufferProvider = pDbp;
346 pTrack->bufferProvider = pDbp;
347
348 return NO_ERROR;
349
350noDownmixForActiveTrack:
351 delete pDbp;
352 pTrack->downmixerBufferProvider = NULL;
353 return NO_INIT;
354}
355
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800356void AudioMixer::deleteTrackName(int name)
357{
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700358 ALOGV("AudioMixer::deleteTrackName(%d)", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700359 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800360 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800361 ALOGV("deleteTrackName(%d)", name);
362 track_t& track(mState.tracks[ name ]);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800363 if (track.enabled) {
364 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800365 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700366 }
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700367 // delete the resampler
368 delete track.resampler;
369 track.resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700370 // delete the downmixer
371 unprepareTrackForDownmix(&mState.tracks[name], name);
372
Glenn Kasten237a6242011-12-15 15:32:27 -0800373 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800374}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700375
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800376void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700377{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800378 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800379 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800380 track_t& track = mState.tracks[name];
381
Glenn Kasten4c340c62012-01-27 12:33:54 -0800382 if (!track.enabled) {
383 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800384 ALOGV("enable(%d)", name);
385 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700386 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700387}
388
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800389void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700390{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800391 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800392 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800393 track_t& track = mState.tracks[name];
394
Glenn Kasten4c340c62012-01-27 12:33:54 -0800395 if (track.enabled) {
396 track.enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800397 ALOGV("disable(%d)", name);
398 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700399 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700400}
401
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800402void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700403{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800404 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800405 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800406 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700407
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000408 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
409 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700410
411 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700412
Mathias Agopian65ab4712010-07-14 17:59:35 -0700413 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800414 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700415 case CHANNEL_MASK: {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000416 audio_channel_mask_t mask =
417 static_cast<audio_channel_mask_t>(reinterpret_cast<uintptr_t>(value));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800418 if (track.channelMask != mask) {
Andy Hunge5412692014-05-16 11:25:07 -0700419 uint32_t channelCount = audio_channel_count_from_out_mask(mask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700420 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800421 track.channelMask = mask;
422 track.channelCount = channelCount;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700423 // the mask has changed, does this track need a downmixer?
424 initTrackDownmix(&mState.tracks[name], name, mask);
Glenn Kasten788040c2011-05-05 08:19:00 -0700425 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800426 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700427 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700428 } break;
429 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800430 if (track.mainBuffer != valueBuf) {
431 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100432 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800433 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700434 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700435 break;
436 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800437 if (track.auxBuffer != valueBuf) {
438 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100439 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800440 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700441 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700442 break;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700443 case FORMAT:
444 ALOG_ASSERT(valueInt == AUDIO_FORMAT_PCM_16_BIT);
445 break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700446 // FIXME do we want to support setting the downmix type from AudioFlinger?
447 // for a specific track? or per mixer?
448 /* case DOWNMIX_TYPE:
449 break */
Andy Hung78820702014-02-28 16:23:02 -0800450 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800451 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung78820702014-02-28 16:23:02 -0800452 if (track.mMixerFormat != format) {
453 track.mMixerFormat = format;
454 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800455 }
456 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700457 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800458 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700459 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700460 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700461
Mathias Agopian65ab4712010-07-14 17:59:35 -0700462 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800463 switch (param) {
464 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800465 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700466 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
467 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
468 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800469 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700470 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800471 break;
472 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800473 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800474 invalidateState(1 << name);
475 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700476 case REMOVE:
477 delete track.resampler;
478 track.resampler = NULL;
479 track.sampleRate = mSampleRate;
480 invalidateState(1 << name);
481 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700482 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800483 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800484 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700485 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700486
Mathias Agopian65ab4712010-07-14 17:59:35 -0700487 case RAMP_VOLUME:
488 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800489 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700490 case VOLUME0:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800491 case VOLUME1:
492 if (track.volume[param-VOLUME0] != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100493 ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800494 track.prevVolume[param-VOLUME0] = track.volume[param-VOLUME0] << 16;
495 track.volume[param-VOLUME0] = valueInt;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700496 if (target == VOLUME) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800497 track.prevVolume[param-VOLUME0] = valueInt << 16;
498 track.volumeInc[param-VOLUME0] = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700499 } else {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800500 int32_t d = (valueInt<<16) - track.prevVolume[param-VOLUME0];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700501 int32_t volInc = d / int32_t(mState.frameCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800502 track.volumeInc[param-VOLUME0] = volInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700503 if (volInc == 0) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800504 track.prevVolume[param-VOLUME0] = valueInt << 16;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700505 }
506 }
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 AUXLEVEL:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800511 //ALOG_ASSERT(0 <= valueInt && valueInt <= MAX_GAIN_INT, "bad aux level %d", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700512 if (track.auxLevel != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100513 ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700514 track.prevAuxLevel = track.auxLevel << 16;
515 track.auxLevel = valueInt;
516 if (target == VOLUME) {
517 track.prevAuxLevel = valueInt << 16;
518 track.auxInc = 0;
519 } else {
520 int32_t d = (valueInt<<16) - track.prevAuxLevel;
521 int32_t volInc = d / int32_t(mState.frameCount);
522 track.auxInc = volInc;
523 if (volInc == 0) {
524 track.prevAuxLevel = valueInt << 16;
525 }
526 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800527 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700528 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800529 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700530 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800531 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700532 }
533 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700534
535 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800536 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700537 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700538}
539
540bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
541{
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700542 if (value != devSampleRate || resampler != NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700543 if (sampleRate != value) {
544 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800545 if (resampler == NULL) {
Glenn Kastenac602052012-10-01 14:04:31 -0700546 ALOGV("creating resampler from track %d Hz to device %d Hz", value, devSampleRate);
547 AudioResampler::src_quality quality;
548 // force lowest quality level resampler if use case isn't music or video
549 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
550 // quality level based on the initial ratio, but that could change later.
551 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
552 if (!((value == 44100 && devSampleRate == 48000) ||
553 (value == 48000 && devSampleRate == 44100))) {
Andy Hung9e0308c2014-01-30 14:32:31 -0800554 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700555 } else {
556 quality = AudioResampler::DEFAULT_QUALITY;
557 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700558 resampler = AudioResampler::create(
Jean-Michel Triviacb86cc2012-04-16 12:43:57 -0700559 format,
560 // the resampler sees the number of channels after the downmixer, if any
Glenn Kastenf551e992013-08-19 18:45:42 -0700561 (int) (downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount),
Glenn Kastenac602052012-10-01 14:04:31 -0700562 devSampleRate, quality);
Glenn Kasten52008f82012-03-18 09:34:41 -0700563 resampler->setLocalTimeFreq(sLocalTimeFreq);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700564 }
565 return true;
566 }
567 }
568 return false;
569}
570
Mathias Agopian65ab4712010-07-14 17:59:35 -0700571inline
572void AudioMixer::track_t::adjustVolumeRamp(bool aux)
573{
Glenn Kastenf9a27772012-01-06 07:47:26 -0800574 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700575 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
576 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
577 volumeInc[i] = 0;
578 prevVolume[i] = volume[i]<<16;
579 }
580 }
581 if (aux) {
582 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
583 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
584 auxInc = 0;
585 prevAuxLevel = auxLevel<<16;
586 }
587 }
588}
589
Glenn Kastenc59c0042012-02-02 14:06:11 -0800590size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800591{
592 name -= TRACK0;
593 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800594 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800595 }
596 return 0;
597}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700598
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800599void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700600{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800601 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800602 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700603
604 if (mState.tracks[name].downmixerBufferProvider != NULL) {
605 // update required?
606 if (mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider != bufferProvider) {
607 ALOGV("AudioMixer::setBufferProvider(%p) for downmix", bufferProvider);
608 // setting the buffer provider for a track that gets downmixed consists in:
609 // 1/ setting the buffer provider to the "downmix / buffer provider" wrapper
610 // so it's the one that gets called when the buffer provider is needed,
611 mState.tracks[name].bufferProvider = mState.tracks[name].downmixerBufferProvider;
612 // 2/ saving the buffer provider for the track so the wrapper can use it
613 // when it downmixes.
614 mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider = bufferProvider;
615 }
616 } else {
617 mState.tracks[name].bufferProvider = bufferProvider;
618 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700619}
620
621
John Grossman4ff14ba2012-02-08 16:37:41 -0800622void AudioMixer::process(int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700623{
John Grossman4ff14ba2012-02-08 16:37:41 -0800624 mState.hook(&mState, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700625}
626
627
John Grossman4ff14ba2012-02-08 16:37:41 -0800628void AudioMixer::process__validate(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700629{
Steve Block5ff1dd52012-01-05 23:22:43 +0000630 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700631 "in process__validate() but nothing's invalid");
632
633 uint32_t changed = state->needsChanged;
634 state->needsChanged = 0; // clear the validation flag
635
636 // recompute which tracks are enabled / disabled
637 uint32_t enabled = 0;
638 uint32_t disabled = 0;
639 while (changed) {
640 const int i = 31 - __builtin_clz(changed);
641 const uint32_t mask = 1<<i;
642 changed &= ~mask;
643 track_t& t = state->tracks[i];
644 (t.enabled ? enabled : disabled) |= mask;
645 }
646 state->enabledTracks &= ~disabled;
647 state->enabledTracks |= enabled;
648
649 // compute everything we need...
650 int countActiveTracks = 0;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800651 bool all16BitsStereoNoResample = true;
652 bool resampling = false;
653 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700654 uint32_t en = state->enabledTracks;
655 while (en) {
656 const int i = 31 - __builtin_clz(en);
657 en &= ~(1<<i);
658
659 countActiveTracks++;
660 track_t& t = state->tracks[i];
661 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700662 // FIXME can overflow (mask is only 3 bits)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700663 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700664 if (t.doesResample()) {
665 n |= NEEDS_RESAMPLE;
666 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700667 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700668 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700669 }
670
671 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800672 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700673 } else if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700674 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700675 }
676 t.needs = n;
677
Glenn Kastend6fadf02013-10-30 14:37:29 -0700678 if (n & NEEDS_MUTE) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700679 t.hook = track__nop;
680 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700681 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800682 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700683 }
Glenn Kastend6fadf02013-10-30 14:37:29 -0700684 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800685 all16BitsStereoNoResample = false;
686 resampling = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700687 t.hook = track__genericResample;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700688 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700689 "Track %d needs downmix + resample", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700690 } else {
691 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
692 t.hook = track__16BitsMono;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800693 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700694 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700695 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Mathias Agopian65ab4712010-07-14 17:59:35 -0700696 t.hook = track__16BitsStereo;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700697 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700698 "Track %d needs downmix", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700699 }
700 }
701 }
702 }
703
704 // select the processing hooks
705 state->hook = process__nop;
Glenn Kasten34fca342013-08-13 09:48:14 -0700706 if (countActiveTracks > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700707 if (resampling) {
708 if (!state->outputTemp) {
709 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
710 }
711 if (!state->resampleTemp) {
712 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
713 }
714 state->hook = process__genericResampling;
715 } else {
716 if (state->outputTemp) {
717 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800718 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700719 }
720 if (state->resampleTemp) {
721 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800722 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700723 }
724 state->hook = process__genericNoResampling;
725 if (all16BitsStereoNoResample && !volumeRamp) {
726 if (countActiveTracks == 1) {
727 state->hook = process__OneTrack16BitsStereoNoResampling;
728 }
729 }
730 }
731 }
732
Steve Block3856b092011-10-20 11:56:00 +0100733 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700734 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
735 countActiveTracks, state->enabledTracks,
736 all16BitsStereoNoResample, resampling, volumeRamp);
737
John Grossman4ff14ba2012-02-08 16:37:41 -0800738 state->hook(state, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700739
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800740 // Now that the volume ramp has been done, set optimal state and
741 // track hooks for subsequent mixer process
Glenn Kasten34fca342013-08-13 09:48:14 -0700742 if (countActiveTracks > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800743 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800744 uint32_t en = state->enabledTracks;
745 while (en) {
746 const int i = 31 - __builtin_clz(en);
747 en &= ~(1<<i);
748 track_t& t = state->tracks[i];
Glenn Kasten6e2ebe92013-08-13 09:14:51 -0700749 if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700750 t.needs |= NEEDS_MUTE;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800751 t.hook = track__nop;
752 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800753 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800754 }
755 }
756 if (allMuted) {
757 state->hook = process__nop;
758 } else if (all16BitsStereoNoResample) {
759 if (countActiveTracks == 1) {
760 state->hook = process__OneTrack16BitsStereoNoResampling;
761 }
762 }
763 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700764}
765
Mathias Agopian65ab4712010-07-14 17:59:35 -0700766
Glenn Kasten85ab62c2012-11-01 11:11:38 -0700767void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount,
768 int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700769{
770 t->resampler->setSampleRate(t->sampleRate);
771
772 // ramp gain - resample to temp buffer and scale/mix in 2nd step
773 if (aux != NULL) {
774 // always resample with unity gain when sending to auxiliary buffer to be able
775 // to apply send level after resampling
776 // TODO: modify each resampler to support aux channel?
777 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
778 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
779 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -0800780 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700781 volumeRampStereo(t, out, outFrameCount, temp, aux);
782 } else {
783 volumeStereo(t, out, outFrameCount, temp, aux);
784 }
785 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -0800786 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700787 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
788 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
789 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
790 volumeRampStereo(t, out, outFrameCount, temp, aux);
791 }
792
793 // constant gain
794 else {
795 t->resampler->setVolume(t->volume[0], t->volume[1]);
796 t->resampler->resample(out, outFrameCount, t->bufferProvider);
797 }
798 }
799}
800
Andy Hungee931ff2014-01-28 13:44:14 -0800801void AudioMixer::track__nop(track_t* t __unused, int32_t* out __unused,
802 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700803{
804}
805
Glenn Kasten85ab62c2012-11-01 11:11:38 -0700806void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
807 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700808{
809 int32_t vl = t->prevVolume[0];
810 int32_t vr = t->prevVolume[1];
811 const int32_t vlInc = t->volumeInc[0];
812 const int32_t vrInc = t->volumeInc[1];
813
Steve Blockb8a80522011-12-20 16:23:08 +0000814 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700815 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
816 // (vl + vlInc*frameCount)/65536.0f, frameCount);
817
818 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -0800819 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700820 int32_t va = t->prevAuxLevel;
821 const int32_t vaInc = t->auxInc;
822 int32_t l;
823 int32_t r;
824
825 do {
826 l = (*temp++ >> 12);
827 r = (*temp++ >> 12);
828 *out++ += (vl >> 16) * l;
829 *out++ += (vr >> 16) * r;
830 *aux++ += (va >> 17) * (l + r);
831 vl += vlInc;
832 vr += vrInc;
833 va += vaInc;
834 } while (--frameCount);
835 t->prevAuxLevel = va;
836 } else {
837 do {
838 *out++ += (vl >> 16) * (*temp++ >> 12);
839 *out++ += (vr >> 16) * (*temp++ >> 12);
840 vl += vlInc;
841 vr += vrInc;
842 } while (--frameCount);
843 }
844 t->prevVolume[0] = vl;
845 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -0800846 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700847}
848
Glenn Kasten85ab62c2012-11-01 11:11:38 -0700849void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
850 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700851{
852 const int16_t vl = t->volume[0];
853 const int16_t vr = t->volume[1];
854
Glenn Kastenf6b16782011-12-15 09:51:17 -0800855 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800856 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700857 do {
858 int16_t l = (int16_t)(*temp++ >> 12);
859 int16_t r = (int16_t)(*temp++ >> 12);
860 out[0] = mulAdd(l, vl, out[0]);
861 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
862 out[1] = mulAdd(r, vr, out[1]);
863 out += 2;
864 aux[0] = mulAdd(a, va, aux[0]);
865 aux++;
866 } while (--frameCount);
867 } else {
868 do {
869 int16_t l = (int16_t)(*temp++ >> 12);
870 int16_t r = (int16_t)(*temp++ >> 12);
871 out[0] = mulAdd(l, vl, out[0]);
872 out[1] = mulAdd(r, vr, out[1]);
873 out += 2;
874 } while (--frameCount);
875 }
876}
877
Andy Hungee931ff2014-01-28 13:44:14 -0800878void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount,
879 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700880{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800881 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700882
Glenn Kastenf6b16782011-12-15 09:51:17 -0800883 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700884 int32_t l;
885 int32_t r;
886 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800887 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700888 int32_t vl = t->prevVolume[0];
889 int32_t vr = t->prevVolume[1];
890 int32_t va = t->prevAuxLevel;
891 const int32_t vlInc = t->volumeInc[0];
892 const int32_t vrInc = t->volumeInc[1];
893 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +0000894 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700895 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
896 // (vl + vlInc*frameCount)/65536.0f, frameCount);
897
898 do {
899 l = (int32_t)*in++;
900 r = (int32_t)*in++;
901 *out++ += (vl >> 16) * l;
902 *out++ += (vr >> 16) * r;
903 *aux++ += (va >> 17) * (l + r);
904 vl += vlInc;
905 vr += vrInc;
906 va += vaInc;
907 } while (--frameCount);
908
909 t->prevVolume[0] = vl;
910 t->prevVolume[1] = vr;
911 t->prevAuxLevel = va;
912 t->adjustVolumeRamp(true);
913 }
914
915 // constant gain
916 else {
917 const uint32_t vrl = t->volumeRL;
918 const int16_t va = (int16_t)t->auxLevel;
919 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800920 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700921 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
922 in += 2;
923 out[0] = mulAddRL(1, rl, vrl, out[0]);
924 out[1] = mulAddRL(0, rl, vrl, out[1]);
925 out += 2;
926 aux[0] = mulAdd(a, va, aux[0]);
927 aux++;
928 } while (--frameCount);
929 }
930 } else {
931 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800932 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700933 int32_t vl = t->prevVolume[0];
934 int32_t vr = t->prevVolume[1];
935 const int32_t vlInc = t->volumeInc[0];
936 const int32_t vrInc = t->volumeInc[1];
937
Steve Blockb8a80522011-12-20 16:23:08 +0000938 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700939 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
940 // (vl + vlInc*frameCount)/65536.0f, frameCount);
941
942 do {
943 *out++ += (vl >> 16) * (int32_t) *in++;
944 *out++ += (vr >> 16) * (int32_t) *in++;
945 vl += vlInc;
946 vr += vrInc;
947 } while (--frameCount);
948
949 t->prevVolume[0] = vl;
950 t->prevVolume[1] = vr;
951 t->adjustVolumeRamp(false);
952 }
953
954 // constant gain
955 else {
956 const uint32_t vrl = t->volumeRL;
957 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800958 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700959 in += 2;
960 out[0] = mulAddRL(1, rl, vrl, out[0]);
961 out[1] = mulAddRL(0, rl, vrl, out[1]);
962 out += 2;
963 } while (--frameCount);
964 }
965 }
966 t->in = in;
967}
968
Andy Hungee931ff2014-01-28 13:44:14 -0800969void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount,
970 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700971{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800972 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700973
Glenn Kastenf6b16782011-12-15 09:51:17 -0800974 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700975 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800976 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700977 int32_t vl = t->prevVolume[0];
978 int32_t vr = t->prevVolume[1];
979 int32_t va = t->prevAuxLevel;
980 const int32_t vlInc = t->volumeInc[0];
981 const int32_t vrInc = t->volumeInc[1];
982 const int32_t vaInc = t->auxInc;
983
Steve Blockb8a80522011-12-20 16:23:08 +0000984 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700985 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
986 // (vl + vlInc*frameCount)/65536.0f, frameCount);
987
988 do {
989 int32_t l = *in++;
990 *out++ += (vl >> 16) * l;
991 *out++ += (vr >> 16) * l;
992 *aux++ += (va >> 16) * l;
993 vl += vlInc;
994 vr += vrInc;
995 va += vaInc;
996 } while (--frameCount);
997
998 t->prevVolume[0] = vl;
999 t->prevVolume[1] = vr;
1000 t->prevAuxLevel = va;
1001 t->adjustVolumeRamp(true);
1002 }
1003 // constant gain
1004 else {
1005 const int16_t vl = t->volume[0];
1006 const int16_t vr = t->volume[1];
1007 const int16_t va = (int16_t)t->auxLevel;
1008 do {
1009 int16_t l = *in++;
1010 out[0] = mulAdd(l, vl, out[0]);
1011 out[1] = mulAdd(l, vr, out[1]);
1012 out += 2;
1013 aux[0] = mulAdd(l, va, aux[0]);
1014 aux++;
1015 } while (--frameCount);
1016 }
1017 } else {
1018 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001019 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001020 int32_t vl = t->prevVolume[0];
1021 int32_t vr = t->prevVolume[1];
1022 const int32_t vlInc = t->volumeInc[0];
1023 const int32_t vrInc = t->volumeInc[1];
1024
Steve Blockb8a80522011-12-20 16:23:08 +00001025 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001026 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1027 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1028
1029 do {
1030 int32_t l = *in++;
1031 *out++ += (vl >> 16) * l;
1032 *out++ += (vr >> 16) * l;
1033 vl += vlInc;
1034 vr += vrInc;
1035 } while (--frameCount);
1036
1037 t->prevVolume[0] = vl;
1038 t->prevVolume[1] = vr;
1039 t->adjustVolumeRamp(false);
1040 }
1041 // constant gain
1042 else {
1043 const int16_t vl = t->volume[0];
1044 const int16_t vr = t->volume[1];
1045 do {
1046 int16_t l = *in++;
1047 out[0] = mulAdd(l, vl, out[0]);
1048 out[1] = mulAdd(l, vr, out[1]);
1049 out += 2;
1050 } while (--frameCount);
1051 }
1052 }
1053 t->in = in;
1054}
1055
Mathias Agopian65ab4712010-07-14 17:59:35 -07001056// no-op case
John Grossman4ff14ba2012-02-08 16:37:41 -08001057void AudioMixer::process__nop(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001058{
1059 uint32_t e0 = state->enabledTracks;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001060 size_t sampleCount = state->frameCount * MAX_NUM_CHANNELS;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001061 while (e0) {
1062 // process by group of tracks with same output buffer to
1063 // avoid multiple memset() on same buffer
1064 uint32_t e1 = e0, e2 = e0;
1065 int i = 31 - __builtin_clz(e1);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001066 {
1067 track_t& t1 = state->tracks[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001068 e2 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001069 while (e2) {
1070 i = 31 - __builtin_clz(e2);
1071 e2 &= ~(1<<i);
1072 track_t& t2 = state->tracks[i];
1073 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1074 e1 &= ~(1<<i);
1075 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001076 }
Glenn Kastenfc900c92013-02-18 12:47:49 -08001077 e0 &= ~(e1);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001078
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001079 memset(t1.mainBuffer, 0, sampleCount
Andy Hung78820702014-02-28 16:23:02 -08001080 * audio_bytes_per_sample(t1.mMixerFormat));
Glenn Kastenfc900c92013-02-18 12:47:49 -08001081 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001082
1083 while (e1) {
1084 i = 31 - __builtin_clz(e1);
1085 e1 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001086 {
1087 track_t& t3 = state->tracks[i];
1088 size_t outFrames = state->frameCount;
1089 while (outFrames) {
1090 t3.buffer.frameCount = outFrames;
1091 int64_t outputPTS = calculateOutputPTS(
1092 t3, pts, state->frameCount - outFrames);
1093 t3.bufferProvider->getNextBuffer(&t3.buffer, outputPTS);
1094 if (t3.buffer.raw == NULL) break;
1095 outFrames -= t3.buffer.frameCount;
1096 t3.bufferProvider->releaseBuffer(&t3.buffer);
1097 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001098 }
1099 }
1100 }
1101}
1102
1103// generic code without resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001104void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001105{
1106 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1107
1108 // acquire each track's buffer
1109 uint32_t enabledTracks = state->enabledTracks;
1110 uint32_t e0 = enabledTracks;
1111 while (e0) {
1112 const int i = 31 - __builtin_clz(e0);
1113 e0 &= ~(1<<i);
1114 track_t& t = state->tracks[i];
1115 t.buffer.frameCount = state->frameCount;
John Grossman4ff14ba2012-02-08 16:37:41 -08001116 t.bufferProvider->getNextBuffer(&t.buffer, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001117 t.frameCount = t.buffer.frameCount;
1118 t.in = t.buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001119 }
1120
1121 e0 = enabledTracks;
1122 while (e0) {
1123 // process by group of tracks with same output buffer to
1124 // optimize cache use
1125 uint32_t e1 = e0, e2 = e0;
1126 int j = 31 - __builtin_clz(e1);
1127 track_t& t1 = state->tracks[j];
1128 e2 &= ~(1<<j);
1129 while (e2) {
1130 j = 31 - __builtin_clz(e2);
1131 e2 &= ~(1<<j);
1132 track_t& t2 = state->tracks[j];
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<<j);
1135 }
1136 }
1137 e0 &= ~(e1);
1138 // this assumes output 16 bits stereo, no resampling
1139 int32_t *out = t1.mainBuffer;
1140 size_t numFrames = 0;
1141 do {
1142 memset(outTemp, 0, sizeof(outTemp));
1143 e2 = e1;
1144 while (e2) {
1145 const int i = 31 - __builtin_clz(e2);
1146 e2 &= ~(1<<i);
1147 track_t& t = state->tracks[i];
1148 size_t outFrames = BLOCKSIZE;
1149 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001150 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001151 aux = t.auxBuffer + numFrames;
1152 }
1153 while (outFrames) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301154 // t.in == NULL can happen if the track was flushed just after having
1155 // been enabled for mixing.
1156 if (t.in == NULL) {
1157 enabledTracks &= ~(1<<i);
1158 e1 &= ~(1<<i);
1159 break;
1160 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001161 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001162 if (inFrames > 0) {
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001163 t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames,
1164 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001165 t.frameCount -= inFrames;
1166 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001167 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001168 aux += inFrames;
1169 }
1170 }
1171 if (t.frameCount == 0 && outFrames) {
1172 t.bufferProvider->releaseBuffer(&t.buffer);
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001173 t.buffer.frameCount = (state->frameCount - numFrames) -
1174 (BLOCKSIZE - outFrames);
John Grossman4ff14ba2012-02-08 16:37:41 -08001175 int64_t outputPTS = calculateOutputPTS(
1176 t, pts, numFrames + (BLOCKSIZE - outFrames));
1177 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001178 t.in = t.buffer.raw;
1179 if (t.in == NULL) {
1180 enabledTracks &= ~(1<<i);
1181 e1 &= ~(1<<i);
1182 break;
1183 }
1184 t.frameCount = t.buffer.frameCount;
1185 }
1186 }
1187 }
Andy Hung78820702014-02-28 16:23:02 -08001188 switch (t1.mMixerFormat) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001189 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung84a0c6e2014-04-02 11:24:53 -07001190 memcpy_to_float_from_q4_27(reinterpret_cast<float *>(out), outTemp, BLOCKSIZE * 2);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001191 out += BLOCKSIZE * 2; // output is 2 floats/frame.
1192 break;
1193 case AUDIO_FORMAT_PCM_16_BIT:
1194 ditherAndClamp(out, outTemp, BLOCKSIZE);
1195 out += BLOCKSIZE; // output is 1 int32_t (2 int16_t samples)/frame
1196 break;
1197 default:
Andy Hung78820702014-02-28 16:23:02 -08001198 LOG_ALWAYS_FATAL("bad mixer format: %d", t1.mMixerFormat);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001199 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001200 numFrames += BLOCKSIZE;
1201 } while (numFrames < state->frameCount);
1202 }
1203
1204 // release each track's buffer
1205 e0 = enabledTracks;
1206 while (e0) {
1207 const int i = 31 - __builtin_clz(e0);
1208 e0 &= ~(1<<i);
1209 track_t& t = state->tracks[i];
1210 t.bufferProvider->releaseBuffer(&t.buffer);
1211 }
1212}
1213
1214
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001215// generic code with resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001216void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001217{
Glenn Kasten54c3b662012-01-06 07:46:30 -08001218 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -07001219 int32_t* const outTemp = state->outputTemp;
1220 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001221
1222 size_t numFrames = state->frameCount;
1223
1224 uint32_t e0 = state->enabledTracks;
1225 while (e0) {
1226 // process by group of tracks with same output buffer
1227 // to optimize cache use
1228 uint32_t e1 = e0, e2 = e0;
1229 int j = 31 - __builtin_clz(e1);
1230 track_t& t1 = state->tracks[j];
1231 e2 &= ~(1<<j);
1232 while (e2) {
1233 j = 31 - __builtin_clz(e2);
1234 e2 &= ~(1<<j);
1235 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001236 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001237 e1 &= ~(1<<j);
1238 }
1239 }
1240 e0 &= ~(e1);
1241 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +01001242 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001243 while (e1) {
1244 const int i = 31 - __builtin_clz(e1);
1245 e1 &= ~(1<<i);
1246 track_t& t = state->tracks[i];
1247 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001248 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001249 aux = t.auxBuffer;
1250 }
1251
1252 // this is a little goofy, on the resampling case we don't
1253 // acquire/release the buffers because it's done by
1254 // the resampler.
Glenn Kastend6fadf02013-10-30 14:37:29 -07001255 if (t.needs & NEEDS_RESAMPLE) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001256 t.resampler->setPTS(pts);
Glenn Kastena1117922012-01-26 10:53:32 -08001257 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001258 } else {
1259
1260 size_t outFrames = 0;
1261
1262 while (outFrames < numFrames) {
1263 t.buffer.frameCount = numFrames - outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001264 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
1265 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001266 t.in = t.buffer.raw;
1267 // t.in == NULL can happen if the track was flushed just after having
1268 // been enabled for mixing.
1269 if (t.in == NULL) break;
1270
Glenn Kastenf6b16782011-12-15 09:51:17 -08001271 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001272 aux += outFrames;
1273 }
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001274 t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount,
1275 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001276 outFrames += t.buffer.frameCount;
1277 t.bufferProvider->releaseBuffer(&t.buffer);
1278 }
1279 }
1280 }
Andy Hung78820702014-02-28 16:23:02 -08001281 switch (t1.mMixerFormat) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001282 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung84a0c6e2014-04-02 11:24:53 -07001283 memcpy_to_float_from_q4_27(reinterpret_cast<float*>(out), outTemp, numFrames*2);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001284 break;
1285 case AUDIO_FORMAT_PCM_16_BIT:
1286 ditherAndClamp(out, outTemp, numFrames);
1287 break;
1288 default:
Andy Hung78820702014-02-28 16:23:02 -08001289 LOG_ALWAYS_FATAL("bad mixer format: %d", t1.mMixerFormat);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001290 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001291 }
1292}
1293
1294// one track, 16 bits stereo without resampling is the most common case
John Grossman4ff14ba2012-02-08 16:37:41 -08001295void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
1296 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001297{
Glenn Kasten99e53b82012-01-19 08:59:58 -08001298 // This method is only called when state->enabledTracks has exactly
1299 // one bit set. The asserts below would verify this, but are commented out
1300 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001301 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001302 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001303 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001304 const track_t& t = state->tracks[i];
1305
1306 AudioBufferProvider::Buffer& b(t.buffer);
1307
1308 int32_t* out = t.mainBuffer;
1309 size_t numFrames = state->frameCount;
1310
1311 const int16_t vl = t.volume[0];
1312 const int16_t vr = t.volume[1];
1313 const uint32_t vrl = t.volumeRL;
1314 while (numFrames) {
1315 b.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001316 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
1317 t.bufferProvider->getNextBuffer(&b, outputPTS);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001318 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001319
1320 // in == NULL can happen if the track was flushed just after having
1321 // been enabled for mixing.
1322 if (in == NULL || ((unsigned long)in & 3)) {
1323 memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001324 ALOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: "
1325 "buffer %p track %d, channels %d, needs %08x",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001326 in, i, t.channelCount, t.needs);
1327 return;
1328 }
1329 size_t outFrames = b.frameCount;
1330
Andy Hung78820702014-02-28 16:23:02 -08001331 switch (t.mMixerFormat) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001332 case AUDIO_FORMAT_PCM_FLOAT: {
1333 float *fout = reinterpret_cast<float*>(out);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001334 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001335 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001336 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001337 int32_t l = mulRL(1, rl, vrl);
1338 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001339 *fout++ = float_from_q4_27(l);
1340 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001341 // Note: In case of later int16_t sink output,
1342 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001343 } while (--outFrames);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001344 } break;
1345 case AUDIO_FORMAT_PCM_16_BIT:
1346 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
1347 // volume is boosted, so we might need to clamp even though
1348 // we process only one track.
1349 do {
1350 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1351 in += 2;
1352 int32_t l = mulRL(1, rl, vrl) >> 12;
1353 int32_t r = mulRL(0, rl, vrl) >> 12;
1354 // clamping...
1355 l = clamp16(l);
1356 r = clamp16(r);
1357 *out++ = (r<<16) | (l & 0xFFFF);
1358 } while (--outFrames);
1359 } else {
1360 do {
1361 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1362 in += 2;
1363 int32_t l = mulRL(1, rl, vrl) >> 12;
1364 int32_t r = mulRL(0, rl, vrl) >> 12;
1365 *out++ = (r<<16) | (l & 0xFFFF);
1366 } while (--outFrames);
1367 }
1368 break;
1369 default:
Andy Hung78820702014-02-28 16:23:02 -08001370 LOG_ALWAYS_FATAL("bad mixer format: %d", t.mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001371 }
1372 numFrames -= b.frameCount;
1373 t.bufferProvider->releaseBuffer(&b);
1374 }
1375}
1376
Glenn Kasten81a028f2011-12-15 09:53:12 -08001377#if 0
Mathias Agopian65ab4712010-07-14 17:59:35 -07001378// 2 tracks is also a common case
1379// NEVER used in current implementation of process__validate()
1380// only use if the 2 tracks have the same output buffer
John Grossman4ff14ba2012-02-08 16:37:41 -08001381void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state,
1382 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001383{
1384 int i;
1385 uint32_t en = state->enabledTracks;
1386
1387 i = 31 - __builtin_clz(en);
1388 const track_t& t0 = state->tracks[i];
1389 AudioBufferProvider::Buffer& b0(t0.buffer);
1390
1391 en &= ~(1<<i);
1392 i = 31 - __builtin_clz(en);
1393 const track_t& t1 = state->tracks[i];
1394 AudioBufferProvider::Buffer& b1(t1.buffer);
1395
Glenn Kasten54c3b662012-01-06 07:46:30 -08001396 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001397 const int16_t vl0 = t0.volume[0];
1398 const int16_t vr0 = t0.volume[1];
1399 size_t frameCount0 = 0;
1400
Glenn Kasten54c3b662012-01-06 07:46:30 -08001401 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001402 const int16_t vl1 = t1.volume[0];
1403 const int16_t vr1 = t1.volume[1];
1404 size_t frameCount1 = 0;
1405
1406 //FIXME: only works if two tracks use same buffer
1407 int32_t* out = t0.mainBuffer;
1408 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001409 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001410
1411
1412 while (numFrames) {
1413
1414 if (frameCount0 == 0) {
1415 b0.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001416 int64_t outputPTS = calculateOutputPTS(t0, pts,
1417 out - t0.mainBuffer);
1418 t0.bufferProvider->getNextBuffer(&b0, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001419 if (b0.i16 == NULL) {
1420 if (buff == NULL) {
1421 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1422 }
1423 in0 = buff;
1424 b0.frameCount = numFrames;
1425 } else {
1426 in0 = b0.i16;
1427 }
1428 frameCount0 = b0.frameCount;
1429 }
1430 if (frameCount1 == 0) {
1431 b1.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001432 int64_t outputPTS = calculateOutputPTS(t1, pts,
1433 out - t0.mainBuffer);
1434 t1.bufferProvider->getNextBuffer(&b1, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001435 if (b1.i16 == NULL) {
1436 if (buff == NULL) {
1437 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1438 }
1439 in1 = buff;
1440 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001441 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001442 in1 = b1.i16;
1443 }
1444 frameCount1 = b1.frameCount;
1445 }
1446
1447 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1448
1449 numFrames -= outFrames;
1450 frameCount0 -= outFrames;
1451 frameCount1 -= outFrames;
1452
1453 do {
1454 int32_t l0 = *in0++;
1455 int32_t r0 = *in0++;
1456 l0 = mul(l0, vl0);
1457 r0 = mul(r0, vr0);
1458 int32_t l = *in1++;
1459 int32_t r = *in1++;
1460 l = mulAdd(l, vl1, l0) >> 12;
1461 r = mulAdd(r, vr1, r0) >> 12;
1462 // clamping...
1463 l = clamp16(l);
1464 r = clamp16(r);
1465 *out++ = (r<<16) | (l & 0xFFFF);
1466 } while (--outFrames);
1467
1468 if (frameCount0 == 0) {
1469 t0.bufferProvider->releaseBuffer(&b0);
1470 }
1471 if (frameCount1 == 0) {
1472 t1.bufferProvider->releaseBuffer(&b1);
1473 }
1474 }
1475
Glenn Kastene9dd0172012-01-27 18:08:45 -08001476 delete [] buff;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001477}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001478#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001479
John Grossman4ff14ba2012-02-08 16:37:41 -08001480int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1481 int outputFrameIndex)
1482{
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001483 if (AudioBufferProvider::kInvalidPTS == basePTS) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001484 return AudioBufferProvider::kInvalidPTS;
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001485 }
John Grossman4ff14ba2012-02-08 16:37:41 -08001486
Glenn Kasten52008f82012-03-18 09:34:41 -07001487 return basePTS + ((outputFrameIndex * sLocalTimeFreq) / t.sampleRate);
1488}
1489
1490/*static*/ uint64_t AudioMixer::sLocalTimeFreq;
1491/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1492
1493/*static*/ void AudioMixer::sInitRoutine()
1494{
1495 LocalClock lc;
1496 sLocalTimeFreq = lc.getLocalFreq();
Glenn Kasten49c34ac2013-10-30 14:37:01 -07001497
1498 // find multichannel downmix effect if we have to play multichannel content
1499 uint32_t numEffects = 0;
1500 int ret = EffectQueryNumberEffects(&numEffects);
1501 if (ret != 0) {
1502 ALOGE("AudioMixer() error %d querying number of effects", ret);
1503 return;
1504 }
1505 ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects);
1506
1507 for (uint32_t i = 0 ; i < numEffects ; i++) {
1508 if (EffectQueryEffect(i, &sDwnmFxDesc) == 0) {
1509 ALOGV("effect %d is called %s", i, sDwnmFxDesc.name);
1510 if (memcmp(&sDwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) {
1511 ALOGI("found effect \"%s\" from %s",
1512 sDwnmFxDesc.name, sDwnmFxDesc.implementor);
1513 sIsMultichannelCapable = true;
1514 break;
1515 }
1516 }
1517 }
1518 ALOGW_IF(!sIsMultichannelCapable, "unable to find downmix effect");
John Grossman4ff14ba2012-02-08 16:37:41 -08001519}
1520
Mathias Agopian65ab4712010-07-14 17:59:35 -07001521// ----------------------------------------------------------------------------
1522}; // namespace android