blob: bfa0f387dce17174399017f679850b36095345c2 [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
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700156int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800157{
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700158 uint32_t names = (~mTrackNames) & mConfiguredNames;
Glenn Kasten98dd5422011-12-15 14:38:29 -0800159 if (names != 0) {
160 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100161 ALOGV("add track (%d)", n);
Glenn Kasten98dd5422011-12-15 14:38:29 -0800162 mTrackNames |= 1 << n;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700163 // assume default parameters for the track, except where noted below
164 track_t* t = &mState.tracks[n];
165 t->needs = 0;
166 t->volume[0] = UNITY_GAIN;
167 t->volume[1] = UNITY_GAIN;
168 // no initialization needed
169 // t->prevVolume[0]
170 // t->prevVolume[1]
171 t->volumeInc[0] = 0;
172 t->volumeInc[1] = 0;
173 t->auxLevel = 0;
174 t->auxInc = 0;
175 // no initialization needed
176 // t->prevAuxLevel
177 // t->frameCount
178 t->channelCount = 2;
179 t->enabled = false;
180 t->format = 16;
181 t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700182 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700183 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
184 t->bufferProvider = NULL;
185 t->buffer.raw = NULL;
186 // no initialization needed
187 // t->buffer.frameCount
188 t->hook = NULL;
189 t->in = NULL;
190 t->resampler = NULL;
191 t->sampleRate = mSampleRate;
192 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
193 t->mainBuffer = NULL;
194 t->auxBuffer = NULL;
Glenn Kasten52008f82012-03-18 09:34:41 -0700195 t->downmixerBufferProvider = NULL;
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800196 t->mSinkFormat = AUDIO_FORMAT_PCM_16_BIT;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700197
198 status_t status = initTrackDownmix(&mState.tracks[n], n, channelMask);
199 if (status == OK) {
200 return TRACK0 + n;
201 }
202 ALOGE("AudioMixer::getTrackName(0x%x) failed, error preparing track for downmix",
203 channelMask);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700204 }
205 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800206}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700207
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800208void AudioMixer::invalidateState(uint32_t mask)
209{
Glenn Kasten34fca342013-08-13 09:48:14 -0700210 if (mask != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700211 mState.needsChanged |= mask;
212 mState.hook = process__validate;
213 }
214 }
215
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700216status_t AudioMixer::initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask)
217{
218 uint32_t channelCount = popcount(mask);
219 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
220 status_t status = OK;
221 if (channelCount > MAX_NUM_CHANNELS) {
222 pTrack->channelMask = mask;
223 pTrack->channelCount = channelCount;
224 ALOGV("initTrackDownmix(track=%d, mask=0x%x) calls prepareTrackForDownmix()",
225 trackNum, mask);
226 status = prepareTrackForDownmix(pTrack, trackNum);
227 } else {
228 unprepareTrackForDownmix(pTrack, trackNum);
229 }
230 return status;
231}
232
Andy Hungee931ff2014-01-28 13:44:14 -0800233void AudioMixer::unprepareTrackForDownmix(track_t* pTrack, int trackName __unused) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700234 ALOGV("AudioMixer::unprepareTrackForDownmix(%d)", trackName);
235
236 if (pTrack->downmixerBufferProvider != NULL) {
237 // this track had previously been configured with a downmixer, delete it
238 ALOGV(" deleting old downmixer");
239 pTrack->bufferProvider = pTrack->downmixerBufferProvider->mTrackBufferProvider;
240 delete pTrack->downmixerBufferProvider;
241 pTrack->downmixerBufferProvider = NULL;
242 } else {
243 ALOGV(" nothing to do, no downmixer to delete");
244 }
245}
246
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700247status_t AudioMixer::prepareTrackForDownmix(track_t* pTrack, int trackName)
248{
249 ALOGV("AudioMixer::prepareTrackForDownmix(%d) with mask 0x%x", trackName, pTrack->channelMask);
250
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700251 // discard the previous downmixer if there was one
252 unprepareTrackForDownmix(pTrack, trackName);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700253
254 DownmixerBufferProvider* pDbp = new DownmixerBufferProvider();
255 int32_t status;
256
Glenn Kasten49c34ac2013-10-30 14:37:01 -0700257 if (!sIsMultichannelCapable) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700258 ALOGE("prepareTrackForDownmix(%d) fails: mixer doesn't support multichannel content",
259 trackName);
260 goto noDownmixForActiveTrack;
261 }
262
Glenn Kasten49c34ac2013-10-30 14:37:01 -0700263 if (EffectCreate(&sDwnmFxDesc.uuid,
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700264 pTrack->sessionId /*sessionId*/, -2 /*ioId not relevant here, using random value*/,
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700265 &pDbp->mDownmixHandle/*pHandle*/) != 0) {
266 ALOGE("prepareTrackForDownmix(%d) fails: error creating downmixer effect", trackName);
267 goto noDownmixForActiveTrack;
268 }
269
270 // channel input configuration will be overridden per-track
271 pDbp->mDownmixConfig.inputCfg.channels = pTrack->channelMask;
272 pDbp->mDownmixConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
273 pDbp->mDownmixConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
274 pDbp->mDownmixConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
275 pDbp->mDownmixConfig.inputCfg.samplingRate = pTrack->sampleRate;
276 pDbp->mDownmixConfig.outputCfg.samplingRate = pTrack->sampleRate;
277 pDbp->mDownmixConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
278 pDbp->mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
279 // input and output buffer provider, and frame count will not be used as the downmix effect
280 // process() function is called directly (see DownmixerBufferProvider::getNextBuffer())
281 pDbp->mDownmixConfig.inputCfg.mask = EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS |
282 EFFECT_CONFIG_FORMAT | EFFECT_CONFIG_ACC_MODE;
283 pDbp->mDownmixConfig.outputCfg.mask = pDbp->mDownmixConfig.inputCfg.mask;
284
285 {// scope for local variables that are not used in goto label "noDownmixForActiveTrack"
286 int cmdStatus;
287 uint32_t replySize = sizeof(int);
288
289 // Configure and enable downmixer
290 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
291 EFFECT_CMD_SET_CONFIG /*cmdCode*/, sizeof(effect_config_t) /*cmdSize*/,
292 &pDbp->mDownmixConfig /*pCmdData*/,
293 &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
294 if ((status != 0) || (cmdStatus != 0)) {
295 ALOGE("error %d while configuring downmixer for track %d", status, trackName);
296 goto noDownmixForActiveTrack;
297 }
298 replySize = sizeof(int);
299 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
300 EFFECT_CMD_ENABLE /*cmdCode*/, 0 /*cmdSize*/, NULL /*pCmdData*/,
301 &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
302 if ((status != 0) || (cmdStatus != 0)) {
303 ALOGE("error %d while enabling downmixer for track %d", status, trackName);
304 goto noDownmixForActiveTrack;
305 }
306
307 // Set downmix type
308 // parameter size rounded for padding on 32bit boundary
309 const int psizePadded = ((sizeof(downmix_params_t) - 1)/sizeof(int) + 1) * sizeof(int);
310 const int downmixParamSize =
311 sizeof(effect_param_t) + psizePadded + sizeof(downmix_type_t);
312 effect_param_t * const param = (effect_param_t *) malloc(downmixParamSize);
313 param->psize = sizeof(downmix_params_t);
314 const downmix_params_t downmixParam = DOWNMIX_PARAM_TYPE;
315 memcpy(param->data, &downmixParam, param->psize);
316 const downmix_type_t downmixType = DOWNMIX_TYPE_FOLD;
317 param->vsize = sizeof(downmix_type_t);
318 memcpy(param->data + psizePadded, &downmixType, param->vsize);
319
320 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
321 EFFECT_CMD_SET_PARAM /* cmdCode */, downmixParamSize/* cmdSize */,
322 param /*pCmndData*/, &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
323
324 free(param);
325
326 if ((status != 0) || (cmdStatus != 0)) {
327 ALOGE("error %d while setting downmix type for track %d", status, trackName);
328 goto noDownmixForActiveTrack;
329 } else {
330 ALOGV("downmix type set to %d for track %d", (int) downmixType, trackName);
331 }
332 }// end of scope for local variables that are not used in goto label "noDownmixForActiveTrack"
333
334 // initialization successful:
335 // - keep track of the real buffer provider in case it was set before
336 pDbp->mTrackBufferProvider = pTrack->bufferProvider;
337 // - we'll use the downmix effect integrated inside this
338 // track's buffer provider, and we'll use it as the track's buffer provider
339 pTrack->downmixerBufferProvider = pDbp;
340 pTrack->bufferProvider = pDbp;
341
342 return NO_ERROR;
343
344noDownmixForActiveTrack:
345 delete pDbp;
346 pTrack->downmixerBufferProvider = NULL;
347 return NO_INIT;
348}
349
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800350void AudioMixer::deleteTrackName(int name)
351{
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700352 ALOGV("AudioMixer::deleteTrackName(%d)", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700353 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800354 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800355 ALOGV("deleteTrackName(%d)", name);
356 track_t& track(mState.tracks[ name ]);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800357 if (track.enabled) {
358 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800359 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700360 }
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700361 // delete the resampler
362 delete track.resampler;
363 track.resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700364 // delete the downmixer
365 unprepareTrackForDownmix(&mState.tracks[name], name);
366
Glenn Kasten237a6242011-12-15 15:32:27 -0800367 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800368}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700369
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800370void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700371{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800372 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800373 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800374 track_t& track = mState.tracks[name];
375
Glenn Kasten4c340c62012-01-27 12:33:54 -0800376 if (!track.enabled) {
377 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800378 ALOGV("enable(%d)", name);
379 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700380 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700381}
382
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800383void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700384{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800385 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800386 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800387 track_t& track = mState.tracks[name];
388
Glenn Kasten4c340c62012-01-27 12:33:54 -0800389 if (track.enabled) {
390 track.enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800391 ALOGV("disable(%d)", name);
392 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700393 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700394}
395
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800396void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700397{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800398 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800399 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800400 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700401
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000402 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
403 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700404
405 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700406
Mathias Agopian65ab4712010-07-14 17:59:35 -0700407 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800408 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700409 case CHANNEL_MASK: {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000410 audio_channel_mask_t mask =
411 static_cast<audio_channel_mask_t>(reinterpret_cast<uintptr_t>(value));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800412 if (track.channelMask != mask) {
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800413 uint32_t channelCount = popcount(mask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700414 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800415 track.channelMask = mask;
416 track.channelCount = channelCount;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700417 // the mask has changed, does this track need a downmixer?
418 initTrackDownmix(&mState.tracks[name], name, mask);
Glenn Kasten788040c2011-05-05 08:19:00 -0700419 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800420 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700421 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700422 } break;
423 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800424 if (track.mainBuffer != valueBuf) {
425 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100426 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800427 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700428 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700429 break;
430 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800431 if (track.auxBuffer != valueBuf) {
432 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100433 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800434 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700435 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700436 break;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700437 case FORMAT:
438 ALOG_ASSERT(valueInt == AUDIO_FORMAT_PCM_16_BIT);
439 break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700440 // FIXME do we want to support setting the downmix type from AudioFlinger?
441 // for a specific track? or per mixer?
442 /* case DOWNMIX_TYPE:
443 break */
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800444 case SINK_FORMAT: {
445 audio_format_t format = static_cast<audio_format_t>(valueInt);
446 if (track.mSinkFormat != format) {
447 track.mSinkFormat = format;
448 ALOGV("setParameter(TRACK, SINK_FORMAT, %#x)", format);
449 }
450 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700451 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800452 LOG_FATAL("bad param");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700453 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700454 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700455
Mathias Agopian65ab4712010-07-14 17:59:35 -0700456 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800457 switch (param) {
458 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800459 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700460 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
461 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
462 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800463 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700464 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800465 break;
466 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800467 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800468 invalidateState(1 << name);
469 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700470 case REMOVE:
471 delete track.resampler;
472 track.resampler = NULL;
473 track.sampleRate = mSampleRate;
474 invalidateState(1 << name);
475 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700476 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800477 LOG_FATAL("bad param");
Eric Laurent243f5f92011-02-28 16:52:51 -0800478 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700479 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700480
Mathias Agopian65ab4712010-07-14 17:59:35 -0700481 case RAMP_VOLUME:
482 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800483 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700484 case VOLUME0:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800485 case VOLUME1:
486 if (track.volume[param-VOLUME0] != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100487 ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800488 track.prevVolume[param-VOLUME0] = track.volume[param-VOLUME0] << 16;
489 track.volume[param-VOLUME0] = valueInt;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700490 if (target == VOLUME) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800491 track.prevVolume[param-VOLUME0] = valueInt << 16;
492 track.volumeInc[param-VOLUME0] = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700493 } else {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800494 int32_t d = (valueInt<<16) - track.prevVolume[param-VOLUME0];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700495 int32_t volInc = d / int32_t(mState.frameCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800496 track.volumeInc[param-VOLUME0] = volInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700497 if (volInc == 0) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800498 track.prevVolume[param-VOLUME0] = valueInt << 16;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700499 }
500 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800501 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700502 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800503 break;
504 case AUXLEVEL:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800505 //ALOG_ASSERT(0 <= valueInt && valueInt <= MAX_GAIN_INT, "bad aux level %d", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700506 if (track.auxLevel != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100507 ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700508 track.prevAuxLevel = track.auxLevel << 16;
509 track.auxLevel = valueInt;
510 if (target == VOLUME) {
511 track.prevAuxLevel = valueInt << 16;
512 track.auxInc = 0;
513 } else {
514 int32_t d = (valueInt<<16) - track.prevAuxLevel;
515 int32_t volInc = d / int32_t(mState.frameCount);
516 track.auxInc = volInc;
517 if (volInc == 0) {
518 track.prevAuxLevel = valueInt << 16;
519 }
520 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800521 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700522 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800523 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700524 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800525 LOG_FATAL("bad param");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700526 }
527 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700528
529 default:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800530 LOG_FATAL("bad target");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700531 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700532}
533
534bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
535{
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700536 if (value != devSampleRate || resampler != NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700537 if (sampleRate != value) {
538 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800539 if (resampler == NULL) {
Glenn Kastenac602052012-10-01 14:04:31 -0700540 ALOGV("creating resampler from track %d Hz to device %d Hz", value, devSampleRate);
541 AudioResampler::src_quality quality;
542 // force lowest quality level resampler if use case isn't music or video
543 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
544 // quality level based on the initial ratio, but that could change later.
545 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
546 if (!((value == 44100 && devSampleRate == 48000) ||
547 (value == 48000 && devSampleRate == 44100))) {
Andy Hung9e0308c2014-01-30 14:32:31 -0800548 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700549 } else {
550 quality = AudioResampler::DEFAULT_QUALITY;
551 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700552 resampler = AudioResampler::create(
Jean-Michel Triviacb86cc2012-04-16 12:43:57 -0700553 format,
554 // the resampler sees the number of channels after the downmixer, if any
Glenn Kastenf551e992013-08-19 18:45:42 -0700555 (int) (downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount),
Glenn Kastenac602052012-10-01 14:04:31 -0700556 devSampleRate, quality);
Glenn Kasten52008f82012-03-18 09:34:41 -0700557 resampler->setLocalTimeFreq(sLocalTimeFreq);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700558 }
559 return true;
560 }
561 }
562 return false;
563}
564
Mathias Agopian65ab4712010-07-14 17:59:35 -0700565inline
566void AudioMixer::track_t::adjustVolumeRamp(bool aux)
567{
Glenn Kastenf9a27772012-01-06 07:47:26 -0800568 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700569 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
570 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
571 volumeInc[i] = 0;
572 prevVolume[i] = volume[i]<<16;
573 }
574 }
575 if (aux) {
576 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
577 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
578 auxInc = 0;
579 prevAuxLevel = auxLevel<<16;
580 }
581 }
582}
583
Glenn Kastenc59c0042012-02-02 14:06:11 -0800584size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800585{
586 name -= TRACK0;
587 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800588 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800589 }
590 return 0;
591}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700592
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800593void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700594{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800595 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800596 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700597
598 if (mState.tracks[name].downmixerBufferProvider != NULL) {
599 // update required?
600 if (mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider != bufferProvider) {
601 ALOGV("AudioMixer::setBufferProvider(%p) for downmix", bufferProvider);
602 // setting the buffer provider for a track that gets downmixed consists in:
603 // 1/ setting the buffer provider to the "downmix / buffer provider" wrapper
604 // so it's the one that gets called when the buffer provider is needed,
605 mState.tracks[name].bufferProvider = mState.tracks[name].downmixerBufferProvider;
606 // 2/ saving the buffer provider for the track so the wrapper can use it
607 // when it downmixes.
608 mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider = bufferProvider;
609 }
610 } else {
611 mState.tracks[name].bufferProvider = bufferProvider;
612 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700613}
614
615
John Grossman4ff14ba2012-02-08 16:37:41 -0800616void AudioMixer::process(int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700617{
John Grossman4ff14ba2012-02-08 16:37:41 -0800618 mState.hook(&mState, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700619}
620
621
John Grossman4ff14ba2012-02-08 16:37:41 -0800622void AudioMixer::process__validate(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700623{
Steve Block5ff1dd52012-01-05 23:22:43 +0000624 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700625 "in process__validate() but nothing's invalid");
626
627 uint32_t changed = state->needsChanged;
628 state->needsChanged = 0; // clear the validation flag
629
630 // recompute which tracks are enabled / disabled
631 uint32_t enabled = 0;
632 uint32_t disabled = 0;
633 while (changed) {
634 const int i = 31 - __builtin_clz(changed);
635 const uint32_t mask = 1<<i;
636 changed &= ~mask;
637 track_t& t = state->tracks[i];
638 (t.enabled ? enabled : disabled) |= mask;
639 }
640 state->enabledTracks &= ~disabled;
641 state->enabledTracks |= enabled;
642
643 // compute everything we need...
644 int countActiveTracks = 0;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800645 bool all16BitsStereoNoResample = true;
646 bool resampling = false;
647 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700648 uint32_t en = state->enabledTracks;
649 while (en) {
650 const int i = 31 - __builtin_clz(en);
651 en &= ~(1<<i);
652
653 countActiveTracks++;
654 track_t& t = state->tracks[i];
655 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700656 // FIXME can overflow (mask is only 3 bits)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700657 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700658 if (t.doesResample()) {
659 n |= NEEDS_RESAMPLE;
660 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700661 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700662 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700663 }
664
665 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800666 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700667 } else if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700668 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700669 }
670 t.needs = n;
671
Glenn Kastend6fadf02013-10-30 14:37:29 -0700672 if (n & NEEDS_MUTE) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700673 t.hook = track__nop;
674 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700675 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800676 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700677 }
Glenn Kastend6fadf02013-10-30 14:37:29 -0700678 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800679 all16BitsStereoNoResample = false;
680 resampling = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700681 t.hook = track__genericResample;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700682 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700683 "Track %d needs downmix + resample", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700684 } else {
685 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
686 t.hook = track__16BitsMono;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800687 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700688 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700689 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Mathias Agopian65ab4712010-07-14 17:59:35 -0700690 t.hook = track__16BitsStereo;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700691 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700692 "Track %d needs downmix", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700693 }
694 }
695 }
696 }
697
698 // select the processing hooks
699 state->hook = process__nop;
Glenn Kasten34fca342013-08-13 09:48:14 -0700700 if (countActiveTracks > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700701 if (resampling) {
702 if (!state->outputTemp) {
703 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
704 }
705 if (!state->resampleTemp) {
706 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
707 }
708 state->hook = process__genericResampling;
709 } else {
710 if (state->outputTemp) {
711 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800712 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700713 }
714 if (state->resampleTemp) {
715 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800716 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700717 }
718 state->hook = process__genericNoResampling;
719 if (all16BitsStereoNoResample && !volumeRamp) {
720 if (countActiveTracks == 1) {
721 state->hook = process__OneTrack16BitsStereoNoResampling;
722 }
723 }
724 }
725 }
726
Steve Block3856b092011-10-20 11:56:00 +0100727 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700728 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
729 countActiveTracks, state->enabledTracks,
730 all16BitsStereoNoResample, resampling, volumeRamp);
731
John Grossman4ff14ba2012-02-08 16:37:41 -0800732 state->hook(state, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700733
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800734 // Now that the volume ramp has been done, set optimal state and
735 // track hooks for subsequent mixer process
Glenn Kasten34fca342013-08-13 09:48:14 -0700736 if (countActiveTracks > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800737 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800738 uint32_t en = state->enabledTracks;
739 while (en) {
740 const int i = 31 - __builtin_clz(en);
741 en &= ~(1<<i);
742 track_t& t = state->tracks[i];
Glenn Kasten6e2ebe92013-08-13 09:14:51 -0700743 if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700744 t.needs |= NEEDS_MUTE;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800745 t.hook = track__nop;
746 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800747 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800748 }
749 }
750 if (allMuted) {
751 state->hook = process__nop;
752 } else if (all16BitsStereoNoResample) {
753 if (countActiveTracks == 1) {
754 state->hook = process__OneTrack16BitsStereoNoResampling;
755 }
756 }
757 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700758}
759
Mathias Agopian65ab4712010-07-14 17:59:35 -0700760
Glenn Kasten85ab62c2012-11-01 11:11:38 -0700761void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount,
762 int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700763{
764 t->resampler->setSampleRate(t->sampleRate);
765
766 // ramp gain - resample to temp buffer and scale/mix in 2nd step
767 if (aux != NULL) {
768 // always resample with unity gain when sending to auxiliary buffer to be able
769 // to apply send level after resampling
770 // TODO: modify each resampler to support aux channel?
771 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
772 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
773 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -0800774 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700775 volumeRampStereo(t, out, outFrameCount, temp, aux);
776 } else {
777 volumeStereo(t, out, outFrameCount, temp, aux);
778 }
779 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -0800780 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700781 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
782 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
783 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
784 volumeRampStereo(t, out, outFrameCount, temp, aux);
785 }
786
787 // constant gain
788 else {
789 t->resampler->setVolume(t->volume[0], t->volume[1]);
790 t->resampler->resample(out, outFrameCount, t->bufferProvider);
791 }
792 }
793}
794
Andy Hungee931ff2014-01-28 13:44:14 -0800795void AudioMixer::track__nop(track_t* t __unused, int32_t* out __unused,
796 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700797{
798}
799
Glenn Kasten85ab62c2012-11-01 11:11:38 -0700800void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
801 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700802{
803 int32_t vl = t->prevVolume[0];
804 int32_t vr = t->prevVolume[1];
805 const int32_t vlInc = t->volumeInc[0];
806 const int32_t vrInc = t->volumeInc[1];
807
Steve Blockb8a80522011-12-20 16:23:08 +0000808 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700809 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
810 // (vl + vlInc*frameCount)/65536.0f, frameCount);
811
812 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -0800813 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700814 int32_t va = t->prevAuxLevel;
815 const int32_t vaInc = t->auxInc;
816 int32_t l;
817 int32_t r;
818
819 do {
820 l = (*temp++ >> 12);
821 r = (*temp++ >> 12);
822 *out++ += (vl >> 16) * l;
823 *out++ += (vr >> 16) * r;
824 *aux++ += (va >> 17) * (l + r);
825 vl += vlInc;
826 vr += vrInc;
827 va += vaInc;
828 } while (--frameCount);
829 t->prevAuxLevel = va;
830 } else {
831 do {
832 *out++ += (vl >> 16) * (*temp++ >> 12);
833 *out++ += (vr >> 16) * (*temp++ >> 12);
834 vl += vlInc;
835 vr += vrInc;
836 } while (--frameCount);
837 }
838 t->prevVolume[0] = vl;
839 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -0800840 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700841}
842
Glenn Kasten85ab62c2012-11-01 11:11:38 -0700843void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
844 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700845{
846 const int16_t vl = t->volume[0];
847 const int16_t vr = t->volume[1];
848
Glenn Kastenf6b16782011-12-15 09:51:17 -0800849 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -0800850 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700851 do {
852 int16_t l = (int16_t)(*temp++ >> 12);
853 int16_t r = (int16_t)(*temp++ >> 12);
854 out[0] = mulAdd(l, vl, out[0]);
855 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
856 out[1] = mulAdd(r, vr, out[1]);
857 out += 2;
858 aux[0] = mulAdd(a, va, aux[0]);
859 aux++;
860 } while (--frameCount);
861 } else {
862 do {
863 int16_t l = (int16_t)(*temp++ >> 12);
864 int16_t r = (int16_t)(*temp++ >> 12);
865 out[0] = mulAdd(l, vl, out[0]);
866 out[1] = mulAdd(r, vr, out[1]);
867 out += 2;
868 } while (--frameCount);
869 }
870}
871
Andy Hungee931ff2014-01-28 13:44:14 -0800872void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount,
873 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700874{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800875 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700876
Glenn Kastenf6b16782011-12-15 09:51:17 -0800877 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700878 int32_t l;
879 int32_t r;
880 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800881 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700882 int32_t vl = t->prevVolume[0];
883 int32_t vr = t->prevVolume[1];
884 int32_t va = t->prevAuxLevel;
885 const int32_t vlInc = t->volumeInc[0];
886 const int32_t vrInc = t->volumeInc[1];
887 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +0000888 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700889 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
890 // (vl + vlInc*frameCount)/65536.0f, frameCount);
891
892 do {
893 l = (int32_t)*in++;
894 r = (int32_t)*in++;
895 *out++ += (vl >> 16) * l;
896 *out++ += (vr >> 16) * r;
897 *aux++ += (va >> 17) * (l + r);
898 vl += vlInc;
899 vr += vrInc;
900 va += vaInc;
901 } while (--frameCount);
902
903 t->prevVolume[0] = vl;
904 t->prevVolume[1] = vr;
905 t->prevAuxLevel = va;
906 t->adjustVolumeRamp(true);
907 }
908
909 // constant gain
910 else {
911 const uint32_t vrl = t->volumeRL;
912 const int16_t va = (int16_t)t->auxLevel;
913 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800914 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700915 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
916 in += 2;
917 out[0] = mulAddRL(1, rl, vrl, out[0]);
918 out[1] = mulAddRL(0, rl, vrl, out[1]);
919 out += 2;
920 aux[0] = mulAdd(a, va, aux[0]);
921 aux++;
922 } while (--frameCount);
923 }
924 } else {
925 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800926 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700927 int32_t vl = t->prevVolume[0];
928 int32_t vr = t->prevVolume[1];
929 const int32_t vlInc = t->volumeInc[0];
930 const int32_t vrInc = t->volumeInc[1];
931
Steve Blockb8a80522011-12-20 16:23:08 +0000932 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700933 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
934 // (vl + vlInc*frameCount)/65536.0f, frameCount);
935
936 do {
937 *out++ += (vl >> 16) * (int32_t) *in++;
938 *out++ += (vr >> 16) * (int32_t) *in++;
939 vl += vlInc;
940 vr += vrInc;
941 } while (--frameCount);
942
943 t->prevVolume[0] = vl;
944 t->prevVolume[1] = vr;
945 t->adjustVolumeRamp(false);
946 }
947
948 // constant gain
949 else {
950 const uint32_t vrl = t->volumeRL;
951 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800952 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700953 in += 2;
954 out[0] = mulAddRL(1, rl, vrl, out[0]);
955 out[1] = mulAddRL(0, rl, vrl, out[1]);
956 out += 2;
957 } while (--frameCount);
958 }
959 }
960 t->in = in;
961}
962
Andy Hungee931ff2014-01-28 13:44:14 -0800963void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount,
964 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700965{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800966 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700967
Glenn Kastenf6b16782011-12-15 09:51:17 -0800968 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700969 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800970 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700971 int32_t vl = t->prevVolume[0];
972 int32_t vr = t->prevVolume[1];
973 int32_t va = t->prevAuxLevel;
974 const int32_t vlInc = t->volumeInc[0];
975 const int32_t vrInc = t->volumeInc[1];
976 const int32_t vaInc = t->auxInc;
977
Steve Blockb8a80522011-12-20 16:23:08 +0000978 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700979 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
980 // (vl + vlInc*frameCount)/65536.0f, frameCount);
981
982 do {
983 int32_t l = *in++;
984 *out++ += (vl >> 16) * l;
985 *out++ += (vr >> 16) * l;
986 *aux++ += (va >> 16) * l;
987 vl += vlInc;
988 vr += vrInc;
989 va += vaInc;
990 } while (--frameCount);
991
992 t->prevVolume[0] = vl;
993 t->prevVolume[1] = vr;
994 t->prevAuxLevel = va;
995 t->adjustVolumeRamp(true);
996 }
997 // constant gain
998 else {
999 const int16_t vl = t->volume[0];
1000 const int16_t vr = t->volume[1];
1001 const int16_t va = (int16_t)t->auxLevel;
1002 do {
1003 int16_t l = *in++;
1004 out[0] = mulAdd(l, vl, out[0]);
1005 out[1] = mulAdd(l, vr, out[1]);
1006 out += 2;
1007 aux[0] = mulAdd(l, va, aux[0]);
1008 aux++;
1009 } while (--frameCount);
1010 }
1011 } else {
1012 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001013 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001014 int32_t vl = t->prevVolume[0];
1015 int32_t vr = t->prevVolume[1];
1016 const int32_t vlInc = t->volumeInc[0];
1017 const int32_t vrInc = t->volumeInc[1];
1018
Steve Blockb8a80522011-12-20 16:23:08 +00001019 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001020 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1021 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1022
1023 do {
1024 int32_t l = *in++;
1025 *out++ += (vl >> 16) * l;
1026 *out++ += (vr >> 16) * l;
1027 vl += vlInc;
1028 vr += vrInc;
1029 } while (--frameCount);
1030
1031 t->prevVolume[0] = vl;
1032 t->prevVolume[1] = vr;
1033 t->adjustVolumeRamp(false);
1034 }
1035 // constant gain
1036 else {
1037 const int16_t vl = t->volume[0];
1038 const int16_t vr = t->volume[1];
1039 do {
1040 int16_t l = *in++;
1041 out[0] = mulAdd(l, vl, out[0]);
1042 out[1] = mulAdd(l, vr, out[1]);
1043 out += 2;
1044 } while (--frameCount);
1045 }
1046 }
1047 t->in = in;
1048}
1049
Mathias Agopian65ab4712010-07-14 17:59:35 -07001050// no-op case
John Grossman4ff14ba2012-02-08 16:37:41 -08001051void AudioMixer::process__nop(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001052{
1053 uint32_t e0 = state->enabledTracks;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001054 size_t sampleCount = state->frameCount * MAX_NUM_CHANNELS;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001055 while (e0) {
1056 // process by group of tracks with same output buffer to
1057 // avoid multiple memset() on same buffer
1058 uint32_t e1 = e0, e2 = e0;
1059 int i = 31 - __builtin_clz(e1);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001060 {
1061 track_t& t1 = state->tracks[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001062 e2 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001063 while (e2) {
1064 i = 31 - __builtin_clz(e2);
1065 e2 &= ~(1<<i);
1066 track_t& t2 = state->tracks[i];
1067 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1068 e1 &= ~(1<<i);
1069 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001070 }
Glenn Kastenfc900c92013-02-18 12:47:49 -08001071 e0 &= ~(e1);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001072
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001073 memset(t1.mainBuffer, 0, sampleCount
1074 * audio_bytes_per_sample(t1.mSinkFormat));
Glenn Kastenfc900c92013-02-18 12:47:49 -08001075 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001076
1077 while (e1) {
1078 i = 31 - __builtin_clz(e1);
1079 e1 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001080 {
1081 track_t& t3 = state->tracks[i];
1082 size_t outFrames = state->frameCount;
1083 while (outFrames) {
1084 t3.buffer.frameCount = outFrames;
1085 int64_t outputPTS = calculateOutputPTS(
1086 t3, pts, state->frameCount - outFrames);
1087 t3.bufferProvider->getNextBuffer(&t3.buffer, outputPTS);
1088 if (t3.buffer.raw == NULL) break;
1089 outFrames -= t3.buffer.frameCount;
1090 t3.bufferProvider->releaseBuffer(&t3.buffer);
1091 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001092 }
1093 }
1094 }
1095}
1096
1097// generic code without resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001098void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001099{
1100 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1101
1102 // acquire each track's buffer
1103 uint32_t enabledTracks = state->enabledTracks;
1104 uint32_t e0 = enabledTracks;
1105 while (e0) {
1106 const int i = 31 - __builtin_clz(e0);
1107 e0 &= ~(1<<i);
1108 track_t& t = state->tracks[i];
1109 t.buffer.frameCount = state->frameCount;
John Grossman4ff14ba2012-02-08 16:37:41 -08001110 t.bufferProvider->getNextBuffer(&t.buffer, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001111 t.frameCount = t.buffer.frameCount;
1112 t.in = t.buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001113 }
1114
1115 e0 = enabledTracks;
1116 while (e0) {
1117 // process by group of tracks with same output buffer to
1118 // optimize cache use
1119 uint32_t e1 = e0, e2 = e0;
1120 int j = 31 - __builtin_clz(e1);
1121 track_t& t1 = state->tracks[j];
1122 e2 &= ~(1<<j);
1123 while (e2) {
1124 j = 31 - __builtin_clz(e2);
1125 e2 &= ~(1<<j);
1126 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001127 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001128 e1 &= ~(1<<j);
1129 }
1130 }
1131 e0 &= ~(e1);
1132 // this assumes output 16 bits stereo, no resampling
1133 int32_t *out = t1.mainBuffer;
1134 size_t numFrames = 0;
1135 do {
1136 memset(outTemp, 0, sizeof(outTemp));
1137 e2 = e1;
1138 while (e2) {
1139 const int i = 31 - __builtin_clz(e2);
1140 e2 &= ~(1<<i);
1141 track_t& t = state->tracks[i];
1142 size_t outFrames = BLOCKSIZE;
1143 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001144 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001145 aux = t.auxBuffer + numFrames;
1146 }
1147 while (outFrames) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301148 // t.in == NULL can happen if the track was flushed just after having
1149 // been enabled for mixing.
1150 if (t.in == NULL) {
1151 enabledTracks &= ~(1<<i);
1152 e1 &= ~(1<<i);
1153 break;
1154 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001155 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001156 if (inFrames > 0) {
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001157 t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames,
1158 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001159 t.frameCount -= inFrames;
1160 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001161 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001162 aux += inFrames;
1163 }
1164 }
1165 if (t.frameCount == 0 && outFrames) {
1166 t.bufferProvider->releaseBuffer(&t.buffer);
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001167 t.buffer.frameCount = (state->frameCount - numFrames) -
1168 (BLOCKSIZE - outFrames);
John Grossman4ff14ba2012-02-08 16:37:41 -08001169 int64_t outputPTS = calculateOutputPTS(
1170 t, pts, numFrames + (BLOCKSIZE - outFrames));
1171 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001172 t.in = t.buffer.raw;
1173 if (t.in == NULL) {
1174 enabledTracks &= ~(1<<i);
1175 e1 &= ~(1<<i);
1176 break;
1177 }
1178 t.frameCount = t.buffer.frameCount;
1179 }
1180 }
1181 }
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001182 switch (t1.mSinkFormat) {
1183 case AUDIO_FORMAT_PCM_FLOAT:
1184 memcpy_to_float_from_q19_12(reinterpret_cast<float *>(out), outTemp, BLOCKSIZE * 2);
1185 out += BLOCKSIZE * 2; // output is 2 floats/frame.
1186 break;
1187 case AUDIO_FORMAT_PCM_16_BIT:
1188 ditherAndClamp(out, outTemp, BLOCKSIZE);
1189 out += BLOCKSIZE; // output is 1 int32_t (2 int16_t samples)/frame
1190 break;
1191 default:
1192 LOG_ALWAYS_FATAL("bad sink format: %d", t1.mSinkFormat);
1193 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001194 numFrames += BLOCKSIZE;
1195 } while (numFrames < state->frameCount);
1196 }
1197
1198 // release each track's buffer
1199 e0 = enabledTracks;
1200 while (e0) {
1201 const int i = 31 - __builtin_clz(e0);
1202 e0 &= ~(1<<i);
1203 track_t& t = state->tracks[i];
1204 t.bufferProvider->releaseBuffer(&t.buffer);
1205 }
1206}
1207
1208
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001209// generic code with resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001210void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001211{
Glenn Kasten54c3b662012-01-06 07:46:30 -08001212 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -07001213 int32_t* const outTemp = state->outputTemp;
1214 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001215
1216 size_t numFrames = state->frameCount;
1217
1218 uint32_t e0 = state->enabledTracks;
1219 while (e0) {
1220 // process by group of tracks with same output buffer
1221 // to optimize cache use
1222 uint32_t e1 = e0, e2 = e0;
1223 int j = 31 - __builtin_clz(e1);
1224 track_t& t1 = state->tracks[j];
1225 e2 &= ~(1<<j);
1226 while (e2) {
1227 j = 31 - __builtin_clz(e2);
1228 e2 &= ~(1<<j);
1229 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001230 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001231 e1 &= ~(1<<j);
1232 }
1233 }
1234 e0 &= ~(e1);
1235 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +01001236 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001237 while (e1) {
1238 const int i = 31 - __builtin_clz(e1);
1239 e1 &= ~(1<<i);
1240 track_t& t = state->tracks[i];
1241 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001242 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001243 aux = t.auxBuffer;
1244 }
1245
1246 // this is a little goofy, on the resampling case we don't
1247 // acquire/release the buffers because it's done by
1248 // the resampler.
Glenn Kastend6fadf02013-10-30 14:37:29 -07001249 if (t.needs & NEEDS_RESAMPLE) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001250 t.resampler->setPTS(pts);
Glenn Kastena1117922012-01-26 10:53:32 -08001251 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001252 } else {
1253
1254 size_t outFrames = 0;
1255
1256 while (outFrames < numFrames) {
1257 t.buffer.frameCount = numFrames - outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001258 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
1259 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001260 t.in = t.buffer.raw;
1261 // t.in == NULL can happen if the track was flushed just after having
1262 // been enabled for mixing.
1263 if (t.in == NULL) break;
1264
Glenn Kastenf6b16782011-12-15 09:51:17 -08001265 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001266 aux += outFrames;
1267 }
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001268 t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount,
1269 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001270 outFrames += t.buffer.frameCount;
1271 t.bufferProvider->releaseBuffer(&t.buffer);
1272 }
1273 }
1274 }
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001275 switch (t1.mSinkFormat) {
1276 case AUDIO_FORMAT_PCM_FLOAT:
1277 memcpy_to_float_from_q19_12(reinterpret_cast<float*>(out), outTemp, numFrames*2);
1278 break;
1279 case AUDIO_FORMAT_PCM_16_BIT:
1280 ditherAndClamp(out, outTemp, numFrames);
1281 break;
1282 default:
1283 LOG_ALWAYS_FATAL("bad sink format: %d", t1.mSinkFormat);
1284 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001285 }
1286}
1287
1288// one track, 16 bits stereo without resampling is the most common case
John Grossman4ff14ba2012-02-08 16:37:41 -08001289void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
1290 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001291{
Glenn Kasten99e53b82012-01-19 08:59:58 -08001292 // This method is only called when state->enabledTracks has exactly
1293 // one bit set. The asserts below would verify this, but are commented out
1294 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001295 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001296 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001297 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001298 const track_t& t = state->tracks[i];
1299
1300 AudioBufferProvider::Buffer& b(t.buffer);
1301
1302 int32_t* out = t.mainBuffer;
1303 size_t numFrames = state->frameCount;
1304
1305 const int16_t vl = t.volume[0];
1306 const int16_t vr = t.volume[1];
1307 const uint32_t vrl = t.volumeRL;
1308 while (numFrames) {
1309 b.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001310 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
1311 t.bufferProvider->getNextBuffer(&b, outputPTS);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001312 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001313
1314 // in == NULL can happen if the track was flushed just after having
1315 // been enabled for mixing.
1316 if (in == NULL || ((unsigned long)in & 3)) {
1317 memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001318 ALOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: "
1319 "buffer %p track %d, channels %d, needs %08x",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001320 in, i, t.channelCount, t.needs);
1321 return;
1322 }
1323 size_t outFrames = b.frameCount;
1324
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001325 switch (t.mSinkFormat) {
1326 case AUDIO_FORMAT_PCM_FLOAT: {
1327 float *fout = reinterpret_cast<float*>(out);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001328 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001329 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001330 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001331 int32_t l = mulRL(1, rl, vrl);
1332 int32_t r = mulRL(0, rl, vrl);
Andy Hung3375bde2014-02-28 15:51:47 -08001333 *fout++ = float_from_q19_12(l);
1334 *fout++ = float_from_q19_12(r);
1335 // Note: In case of later int16_t sink output,
1336 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001337 } while (--outFrames);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001338 } break;
1339 case AUDIO_FORMAT_PCM_16_BIT:
1340 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
1341 // volume is boosted, so we might need to clamp even though
1342 // we process only one track.
1343 do {
1344 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1345 in += 2;
1346 int32_t l = mulRL(1, rl, vrl) >> 12;
1347 int32_t r = mulRL(0, rl, vrl) >> 12;
1348 // clamping...
1349 l = clamp16(l);
1350 r = clamp16(r);
1351 *out++ = (r<<16) | (l & 0xFFFF);
1352 } while (--outFrames);
1353 } else {
1354 do {
1355 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1356 in += 2;
1357 int32_t l = mulRL(1, rl, vrl) >> 12;
1358 int32_t r = mulRL(0, rl, vrl) >> 12;
1359 *out++ = (r<<16) | (l & 0xFFFF);
1360 } while (--outFrames);
1361 }
1362 break;
1363 default:
1364 LOG_ALWAYS_FATAL("bad sink format: %d", t.mSinkFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001365 }
1366 numFrames -= b.frameCount;
1367 t.bufferProvider->releaseBuffer(&b);
1368 }
1369}
1370
Glenn Kasten81a028f2011-12-15 09:53:12 -08001371#if 0
Mathias Agopian65ab4712010-07-14 17:59:35 -07001372// 2 tracks is also a common case
1373// NEVER used in current implementation of process__validate()
1374// only use if the 2 tracks have the same output buffer
John Grossman4ff14ba2012-02-08 16:37:41 -08001375void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state,
1376 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001377{
1378 int i;
1379 uint32_t en = state->enabledTracks;
1380
1381 i = 31 - __builtin_clz(en);
1382 const track_t& t0 = state->tracks[i];
1383 AudioBufferProvider::Buffer& b0(t0.buffer);
1384
1385 en &= ~(1<<i);
1386 i = 31 - __builtin_clz(en);
1387 const track_t& t1 = state->tracks[i];
1388 AudioBufferProvider::Buffer& b1(t1.buffer);
1389
Glenn Kasten54c3b662012-01-06 07:46:30 -08001390 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001391 const int16_t vl0 = t0.volume[0];
1392 const int16_t vr0 = t0.volume[1];
1393 size_t frameCount0 = 0;
1394
Glenn Kasten54c3b662012-01-06 07:46:30 -08001395 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001396 const int16_t vl1 = t1.volume[0];
1397 const int16_t vr1 = t1.volume[1];
1398 size_t frameCount1 = 0;
1399
1400 //FIXME: only works if two tracks use same buffer
1401 int32_t* out = t0.mainBuffer;
1402 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001403 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001404
1405
1406 while (numFrames) {
1407
1408 if (frameCount0 == 0) {
1409 b0.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001410 int64_t outputPTS = calculateOutputPTS(t0, pts,
1411 out - t0.mainBuffer);
1412 t0.bufferProvider->getNextBuffer(&b0, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001413 if (b0.i16 == NULL) {
1414 if (buff == NULL) {
1415 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1416 }
1417 in0 = buff;
1418 b0.frameCount = numFrames;
1419 } else {
1420 in0 = b0.i16;
1421 }
1422 frameCount0 = b0.frameCount;
1423 }
1424 if (frameCount1 == 0) {
1425 b1.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001426 int64_t outputPTS = calculateOutputPTS(t1, pts,
1427 out - t0.mainBuffer);
1428 t1.bufferProvider->getNextBuffer(&b1, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001429 if (b1.i16 == NULL) {
1430 if (buff == NULL) {
1431 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1432 }
1433 in1 = buff;
1434 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001435 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001436 in1 = b1.i16;
1437 }
1438 frameCount1 = b1.frameCount;
1439 }
1440
1441 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1442
1443 numFrames -= outFrames;
1444 frameCount0 -= outFrames;
1445 frameCount1 -= outFrames;
1446
1447 do {
1448 int32_t l0 = *in0++;
1449 int32_t r0 = *in0++;
1450 l0 = mul(l0, vl0);
1451 r0 = mul(r0, vr0);
1452 int32_t l = *in1++;
1453 int32_t r = *in1++;
1454 l = mulAdd(l, vl1, l0) >> 12;
1455 r = mulAdd(r, vr1, r0) >> 12;
1456 // clamping...
1457 l = clamp16(l);
1458 r = clamp16(r);
1459 *out++ = (r<<16) | (l & 0xFFFF);
1460 } while (--outFrames);
1461
1462 if (frameCount0 == 0) {
1463 t0.bufferProvider->releaseBuffer(&b0);
1464 }
1465 if (frameCount1 == 0) {
1466 t1.bufferProvider->releaseBuffer(&b1);
1467 }
1468 }
1469
Glenn Kastene9dd0172012-01-27 18:08:45 -08001470 delete [] buff;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001471}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001472#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001473
John Grossman4ff14ba2012-02-08 16:37:41 -08001474int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1475 int outputFrameIndex)
1476{
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001477 if (AudioBufferProvider::kInvalidPTS == basePTS) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001478 return AudioBufferProvider::kInvalidPTS;
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001479 }
John Grossman4ff14ba2012-02-08 16:37:41 -08001480
Glenn Kasten52008f82012-03-18 09:34:41 -07001481 return basePTS + ((outputFrameIndex * sLocalTimeFreq) / t.sampleRate);
1482}
1483
1484/*static*/ uint64_t AudioMixer::sLocalTimeFreq;
1485/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1486
1487/*static*/ void AudioMixer::sInitRoutine()
1488{
1489 LocalClock lc;
1490 sLocalTimeFreq = lc.getLocalFreq();
Glenn Kasten49c34ac2013-10-30 14:37:01 -07001491
1492 // find multichannel downmix effect if we have to play multichannel content
1493 uint32_t numEffects = 0;
1494 int ret = EffectQueryNumberEffects(&numEffects);
1495 if (ret != 0) {
1496 ALOGE("AudioMixer() error %d querying number of effects", ret);
1497 return;
1498 }
1499 ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects);
1500
1501 for (uint32_t i = 0 ; i < numEffects ; i++) {
1502 if (EffectQueryEffect(i, &sDwnmFxDesc) == 0) {
1503 ALOGV("effect %d is called %s", i, sDwnmFxDesc.name);
1504 if (memcmp(&sDwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) {
1505 ALOGI("found effect \"%s\" from %s",
1506 sDwnmFxDesc.name, sDwnmFxDesc.implementor);
1507 sIsMultichannelCapable = true;
1508 break;
1509 }
1510 }
1511 }
1512 ALOGW_IF(!sIsMultichannelCapable, "unable to find downmix effect");
John Grossman4ff14ba2012-02-08 16:37:41 -08001513}
1514
Mathias Agopian65ab4712010-07-14 17:59:35 -07001515// ----------------------------------------------------------------------------
1516}; // namespace android