blob: d73292efa520555db29ed359e722ce2b06f51549 [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>
Andy Hungef7c7fb2014-05-12 16:51:41 -070037#include <audio_utils/format.h>
John Grossman4ff14ba2012-02-08 16:37:41 -080038#include <common_time/local_clock.h>
39#include <common_time/cc_helper.h>
Glenn Kasten3b21c502011-12-15 09:52:39 -080040
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070041#include <media/EffectsFactoryApi.h>
42
Mathias Agopian65ab4712010-07-14 17:59:35 -070043#include "AudioMixer.h"
44
45namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070046
47// ----------------------------------------------------------------------------
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070048AudioMixer::DownmixerBufferProvider::DownmixerBufferProvider() : AudioBufferProvider(),
49 mTrackBufferProvider(NULL), mDownmixHandle(NULL)
50{
51}
52
53AudioMixer::DownmixerBufferProvider::~DownmixerBufferProvider()
54{
55 ALOGV("AudioMixer deleting DownmixerBufferProvider (%p)", this);
56 EffectRelease(mDownmixHandle);
57}
58
59status_t AudioMixer::DownmixerBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer,
60 int64_t pts) {
61 //ALOGV("DownmixerBufferProvider::getNextBuffer()");
Glenn Kasten8f325372013-10-30 14:36:47 -070062 if (mTrackBufferProvider != NULL) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070063 status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts);
64 if (res == OK) {
65 mDownmixConfig.inputCfg.buffer.frameCount = pBuffer->frameCount;
66 mDownmixConfig.inputCfg.buffer.raw = pBuffer->raw;
67 mDownmixConfig.outputCfg.buffer.frameCount = pBuffer->frameCount;
68 mDownmixConfig.outputCfg.buffer.raw = mDownmixConfig.inputCfg.buffer.raw;
69 // in-place so overwrite the buffer contents, has been set in prepareTrackForDownmix()
70 //mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
71
72 res = (*mDownmixHandle)->process(mDownmixHandle,
73 &mDownmixConfig.inputCfg.buffer, &mDownmixConfig.outputCfg.buffer);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -070074 //ALOGV("getNextBuffer is downmixing");
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070075 }
76 return res;
77 } else {
78 ALOGE("DownmixerBufferProvider::getNextBuffer() error: NULL track buffer provider");
79 return NO_INIT;
80 }
81}
82
83void AudioMixer::DownmixerBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -070084 //ALOGV("DownmixerBufferProvider::releaseBuffer()");
Glenn Kasten8f325372013-10-30 14:36:47 -070085 if (mTrackBufferProvider != NULL) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070086 mTrackBufferProvider->releaseBuffer(pBuffer);
87 } else {
88 ALOGE("DownmixerBufferProvider::releaseBuffer() error: NULL track buffer provider");
89 }
90}
91
Andy Hungef7c7fb2014-05-12 16:51:41 -070092template <typename T>
93T min(const T& a, const T& b)
94{
95 return a < b ? a : b;
96}
97
98AudioMixer::ReformatBufferProvider::ReformatBufferProvider(int32_t channels,
99 audio_format_t inputFormat, audio_format_t outputFormat) :
100 mTrackBufferProvider(NULL),
101 mChannels(channels),
102 mInputFormat(inputFormat),
103 mOutputFormat(outputFormat),
104 mInputFrameSize(channels * audio_bytes_per_sample(inputFormat)),
105 mOutputFrameSize(channels * audio_bytes_per_sample(outputFormat)),
106 mOutputData(NULL),
107 mOutputCount(0),
108 mConsumed(0)
109{
110 ALOGV("ReformatBufferProvider(%p)(%d, %#x, %#x)", this, channels, inputFormat, outputFormat);
111 if (requiresInternalBuffers()) {
112 mOutputCount = 256;
113 (void)posix_memalign(&mOutputData, 32, mOutputCount * mOutputFrameSize);
114 }
115 mBuffer.frameCount = 0;
116}
117
118AudioMixer::ReformatBufferProvider::~ReformatBufferProvider()
119{
120 ALOGV("~ReformatBufferProvider(%p)", this);
121 if (mBuffer.frameCount != 0) {
122 mTrackBufferProvider->releaseBuffer(&mBuffer);
123 }
124 free(mOutputData);
125}
126
127status_t AudioMixer::ReformatBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer,
128 int64_t pts) {
129 //ALOGV("ReformatBufferProvider(%p)::getNextBuffer(%p (%zu), %lld)",
130 // this, pBuffer, pBuffer->frameCount, pts);
131 if (!requiresInternalBuffers()) {
132 status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts);
133 if (res == OK) {
134 memcpy_by_audio_format(pBuffer->raw, mOutputFormat, pBuffer->raw, mInputFormat,
135 pBuffer->frameCount * mChannels);
136 }
137 return res;
138 }
139 if (mBuffer.frameCount == 0) {
140 mBuffer.frameCount = pBuffer->frameCount;
141 status_t res = mTrackBufferProvider->getNextBuffer(&mBuffer, pts);
142 // TODO: Track down a bug in the upstream provider
143 // LOG_ALWAYS_FATAL_IF(res == OK && mBuffer.frameCount == 0,
144 // "ReformatBufferProvider::getNextBuffer():"
145 // " Invalid zero framecount returned from getNextBuffer()");
146 if (res != OK || mBuffer.frameCount == 0) {
147 pBuffer->raw = NULL;
148 pBuffer->frameCount = 0;
149 return res;
150 }
151 }
152 ALOG_ASSERT(mConsumed < mBuffer.frameCount);
153 size_t count = min(mOutputCount, mBuffer.frameCount - mConsumed);
154 count = min(count, pBuffer->frameCount);
155 pBuffer->raw = mOutputData;
156 pBuffer->frameCount = count;
157 //ALOGV("reformatting %d frames from %#x to %#x, %d chan",
158 // pBuffer->frameCount, mInputFormat, mOutputFormat, mChannels);
159 memcpy_by_audio_format(pBuffer->raw, mOutputFormat,
160 (uint8_t*)mBuffer.raw + mConsumed * mInputFrameSize, mInputFormat,
161 pBuffer->frameCount * mChannels);
162 return OK;
163}
164
165void AudioMixer::ReformatBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
166 //ALOGV("ReformatBufferProvider(%p)::releaseBuffer(%p(%zu))",
167 // this, pBuffer, pBuffer->frameCount);
168 if (!requiresInternalBuffers()) {
169 mTrackBufferProvider->releaseBuffer(pBuffer);
170 return;
171 }
172 // LOG_ALWAYS_FATAL_IF(pBuffer->frameCount == 0, "Invalid framecount");
173 mConsumed += pBuffer->frameCount; // TODO: update for efficiency to reuse existing content
174 if (mConsumed != 0 && mConsumed >= mBuffer.frameCount) {
175 mConsumed = 0;
176 mTrackBufferProvider->releaseBuffer(&mBuffer);
177 // ALOG_ASSERT(mBuffer.frameCount == 0);
178 }
179 pBuffer->raw = NULL;
180 pBuffer->frameCount = 0;
181}
182
183void AudioMixer::ReformatBufferProvider::reset() {
184 if (mBuffer.frameCount != 0) {
185 mTrackBufferProvider->releaseBuffer(&mBuffer);
186 }
187 mConsumed = 0;
188}
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700189
190// ----------------------------------------------------------------------------
Glenn Kasten49c34ac2013-10-30 14:37:01 -0700191bool AudioMixer::sIsMultichannelCapable = false;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700192
Glenn Kasten49c34ac2013-10-30 14:37:01 -0700193effect_descriptor_t AudioMixer::sDwnmFxDesc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700194
Paul Lind3c0a0e82012-08-01 18:49:49 -0700195// Ensure mConfiguredNames bitmask is initialized properly on all architectures.
196// The value of 1 << x is undefined in C when x >= 32.
197
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700198AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks)
Paul Lind3c0a0e82012-08-01 18:49:49 -0700199 : mTrackNames(0), mConfiguredNames((maxNumTracks >= 32 ? 0 : 1 << maxNumTracks) - 1),
Glenn Kasten7f5d3352013-02-15 23:55:04 +0000200 mSampleRate(sampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700201{
Glenn Kasten788040c2011-05-05 08:19:00 -0700202 // AudioMixer is not yet capable of multi-channel beyond stereo
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800203 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(2 == MAX_NUM_CHANNELS);
Jean-Michel Triviacb86cc2012-04-16 12:43:57 -0700204
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700205 ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u",
206 maxNumTracks, MAX_NUM_TRACKS);
207
Glenn Kasten599fabc2012-03-08 12:33:37 -0800208 // AudioMixer is not yet capable of more than 32 active track inputs
209 ALOG_ASSERT(32 >= MAX_NUM_TRACKS, "bad MAX_NUM_TRACKS %d", MAX_NUM_TRACKS);
210
211 // AudioMixer is not yet capable of multi-channel output beyond stereo
212 ALOG_ASSERT(2 == MAX_NUM_CHANNELS, "bad MAX_NUM_CHANNELS %d", MAX_NUM_CHANNELS);
213
Glenn Kasten52008f82012-03-18 09:34:41 -0700214 pthread_once(&sOnceControl, &sInitRoutine);
215
Mathias Agopian65ab4712010-07-14 17:59:35 -0700216 mState.enabledTracks= 0;
217 mState.needsChanged = 0;
218 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800219 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -0800220 mState.outputTemp = NULL;
221 mState.resampleTemp = NULL;
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800222 mState.mLog = &mDummyLog;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800223 // mState.reserved
Glenn Kasten17a736c2012-02-14 08:52:15 -0800224
225 // FIXME Most of the following initialization is probably redundant since
226 // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0
227 // and mTrackNames is initially 0. However, leave it here until that's verified.
Mathias Agopian65ab4712010-07-14 17:59:35 -0700228 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800229 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Eric Laurenta5e82142012-04-16 13:47:17 -0700230 t->resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700231 t->downmixerBufferProvider = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700232 t++;
233 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700234
Mathias Agopian65ab4712010-07-14 17:59:35 -0700235}
236
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800237AudioMixer::~AudioMixer()
238{
239 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800240 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800241 delete t->resampler;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700242 delete t->downmixerBufferProvider;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800243 t++;
244 }
245 delete [] mState.outputTemp;
246 delete [] mState.resampleTemp;
247}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700248
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800249void AudioMixer::setLog(NBLog::Writer *log)
250{
251 mState.mLog = log;
252}
253
Andy Hunge8a1ced2014-05-09 15:02:21 -0700254int AudioMixer::getTrackName(audio_channel_mask_t channelMask,
255 audio_format_t format, int sessionId)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800256{
Andy Hunge8a1ced2014-05-09 15:02:21 -0700257 if (!isValidPcmTrackFormat(format)) {
258 ALOGE("AudioMixer::getTrackName invalid format (%#x)", format);
259 return -1;
260 }
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700261 uint32_t names = (~mTrackNames) & mConfiguredNames;
Glenn Kasten98dd5422011-12-15 14:38:29 -0800262 if (names != 0) {
263 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100264 ALOGV("add track (%d)", n);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700265 // assume default parameters for the track, except where noted below
266 track_t* t = &mState.tracks[n];
267 t->needs = 0;
Andy Hung97ae8242014-05-30 10:35:47 -0700268 t->volume[0] = UNITY_GAIN_INT;
269 t->volume[1] = UNITY_GAIN_INT;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700270 // no initialization needed
271 // t->prevVolume[0]
272 // t->prevVolume[1]
273 t->volumeInc[0] = 0;
274 t->volumeInc[1] = 0;
275 t->auxLevel = 0;
276 t->auxInc = 0;
277 // no initialization needed
278 // t->prevAuxLevel
279 // t->frameCount
Andy Hung68112fc2014-05-14 14:13:23 -0700280 t->channelCount = audio_channel_count_from_out_mask(channelMask);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700281 t->enabled = false;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700282 ALOGV_IF(channelMask != AUDIO_CHANNEL_OUT_STEREO,
283 "Non-stereo channel mask: %d\n", channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700284 t->channelMask = channelMask;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700285 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700286 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
287 t->bufferProvider = NULL;
288 t->buffer.raw = NULL;
289 // no initialization needed
290 // t->buffer.frameCount
291 t->hook = NULL;
292 t->in = NULL;
293 t->resampler = NULL;
294 t->sampleRate = mSampleRate;
295 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
296 t->mainBuffer = NULL;
297 t->auxBuffer = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700298 t->mInputBufferProvider = NULL;
299 t->mReformatBufferProvider = NULL;
Glenn Kasten52008f82012-03-18 09:34:41 -0700300 t->downmixerBufferProvider = NULL;
Andy Hung78820702014-02-28 16:23:02 -0800301 t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
Andy Hunge8a1ced2014-05-09 15:02:21 -0700302 t->mFormat = format;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700303 t->mMixerInFormat = AUDIO_FORMAT_PCM_16_BIT;
304 if (t->mFormat != t->mMixerInFormat) {
305 prepareTrackForReformat(t, n);
306 }
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700307 status_t status = initTrackDownmix(&mState.tracks[n], n, channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700308 if (status != OK) {
309 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
310 return -1;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700311 }
Andy Hung68112fc2014-05-14 14:13:23 -0700312 mTrackNames |= 1 << n;
313 return TRACK0 + n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700314 }
Andy Hung68112fc2014-05-14 14:13:23 -0700315 ALOGE("AudioMixer::getTrackName out of available tracks");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700316 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800317}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700318
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800319void AudioMixer::invalidateState(uint32_t mask)
320{
Glenn Kasten34fca342013-08-13 09:48:14 -0700321 if (mask != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700322 mState.needsChanged |= mask;
323 mState.hook = process__validate;
324 }
325 }
326
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700327status_t AudioMixer::initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask)
328{
Andy Hunge5412692014-05-16 11:25:07 -0700329 uint32_t channelCount = audio_channel_count_from_out_mask(mask);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700330 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
331 status_t status = OK;
332 if (channelCount > MAX_NUM_CHANNELS) {
333 pTrack->channelMask = mask;
334 pTrack->channelCount = channelCount;
335 ALOGV("initTrackDownmix(track=%d, mask=0x%x) calls prepareTrackForDownmix()",
336 trackNum, mask);
337 status = prepareTrackForDownmix(pTrack, trackNum);
338 } else {
339 unprepareTrackForDownmix(pTrack, trackNum);
340 }
341 return status;
342}
343
Andy Hungee931ff2014-01-28 13:44:14 -0800344void AudioMixer::unprepareTrackForDownmix(track_t* pTrack, int trackName __unused) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700345 ALOGV("AudioMixer::unprepareTrackForDownmix(%d)", trackName);
346
347 if (pTrack->downmixerBufferProvider != NULL) {
348 // this track had previously been configured with a downmixer, delete it
349 ALOGV(" deleting old downmixer");
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700350 delete pTrack->downmixerBufferProvider;
351 pTrack->downmixerBufferProvider = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700352 reconfigureBufferProviders(pTrack);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700353 } else {
354 ALOGV(" nothing to do, no downmixer to delete");
355 }
356}
357
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700358status_t AudioMixer::prepareTrackForDownmix(track_t* pTrack, int trackName)
359{
360 ALOGV("AudioMixer::prepareTrackForDownmix(%d) with mask 0x%x", trackName, pTrack->channelMask);
361
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700362 // discard the previous downmixer if there was one
363 unprepareTrackForDownmix(pTrack, trackName);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700364
365 DownmixerBufferProvider* pDbp = new DownmixerBufferProvider();
366 int32_t status;
367
Glenn Kasten49c34ac2013-10-30 14:37:01 -0700368 if (!sIsMultichannelCapable) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700369 ALOGE("prepareTrackForDownmix(%d) fails: mixer doesn't support multichannel content",
370 trackName);
371 goto noDownmixForActiveTrack;
372 }
373
Glenn Kasten49c34ac2013-10-30 14:37:01 -0700374 if (EffectCreate(&sDwnmFxDesc.uuid,
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700375 pTrack->sessionId /*sessionId*/, -2 /*ioId not relevant here, using random value*/,
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700376 &pDbp->mDownmixHandle/*pHandle*/) != 0) {
377 ALOGE("prepareTrackForDownmix(%d) fails: error creating downmixer effect", trackName);
378 goto noDownmixForActiveTrack;
379 }
380
381 // channel input configuration will be overridden per-track
382 pDbp->mDownmixConfig.inputCfg.channels = pTrack->channelMask;
383 pDbp->mDownmixConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
384 pDbp->mDownmixConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
385 pDbp->mDownmixConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
386 pDbp->mDownmixConfig.inputCfg.samplingRate = pTrack->sampleRate;
387 pDbp->mDownmixConfig.outputCfg.samplingRate = pTrack->sampleRate;
388 pDbp->mDownmixConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
389 pDbp->mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
390 // input and output buffer provider, and frame count will not be used as the downmix effect
391 // process() function is called directly (see DownmixerBufferProvider::getNextBuffer())
392 pDbp->mDownmixConfig.inputCfg.mask = EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS |
393 EFFECT_CONFIG_FORMAT | EFFECT_CONFIG_ACC_MODE;
394 pDbp->mDownmixConfig.outputCfg.mask = pDbp->mDownmixConfig.inputCfg.mask;
395
396 {// scope for local variables that are not used in goto label "noDownmixForActiveTrack"
397 int cmdStatus;
398 uint32_t replySize = sizeof(int);
399
400 // Configure and enable downmixer
401 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
402 EFFECT_CMD_SET_CONFIG /*cmdCode*/, sizeof(effect_config_t) /*cmdSize*/,
403 &pDbp->mDownmixConfig /*pCmdData*/,
404 &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
405 if ((status != 0) || (cmdStatus != 0)) {
406 ALOGE("error %d while configuring downmixer for track %d", status, trackName);
407 goto noDownmixForActiveTrack;
408 }
409 replySize = sizeof(int);
410 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
411 EFFECT_CMD_ENABLE /*cmdCode*/, 0 /*cmdSize*/, NULL /*pCmdData*/,
412 &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
413 if ((status != 0) || (cmdStatus != 0)) {
414 ALOGE("error %d while enabling downmixer for track %d", status, trackName);
415 goto noDownmixForActiveTrack;
416 }
417
418 // Set downmix type
419 // parameter size rounded for padding on 32bit boundary
420 const int psizePadded = ((sizeof(downmix_params_t) - 1)/sizeof(int) + 1) * sizeof(int);
421 const int downmixParamSize =
422 sizeof(effect_param_t) + psizePadded + sizeof(downmix_type_t);
423 effect_param_t * const param = (effect_param_t *) malloc(downmixParamSize);
424 param->psize = sizeof(downmix_params_t);
425 const downmix_params_t downmixParam = DOWNMIX_PARAM_TYPE;
426 memcpy(param->data, &downmixParam, param->psize);
427 const downmix_type_t downmixType = DOWNMIX_TYPE_FOLD;
428 param->vsize = sizeof(downmix_type_t);
429 memcpy(param->data + psizePadded, &downmixType, param->vsize);
430
431 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
432 EFFECT_CMD_SET_PARAM /* cmdCode */, downmixParamSize/* cmdSize */,
433 param /*pCmndData*/, &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
434
435 free(param);
436
437 if ((status != 0) || (cmdStatus != 0)) {
438 ALOGE("error %d while setting downmix type for track %d", status, trackName);
439 goto noDownmixForActiveTrack;
440 } else {
441 ALOGV("downmix type set to %d for track %d", (int) downmixType, trackName);
442 }
443 }// end of scope for local variables that are not used in goto label "noDownmixForActiveTrack"
444
445 // initialization successful:
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700446 pTrack->downmixerBufferProvider = pDbp;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700447 reconfigureBufferProviders(pTrack);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700448 return NO_ERROR;
449
450noDownmixForActiveTrack:
451 delete pDbp;
452 pTrack->downmixerBufferProvider = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700453 reconfigureBufferProviders(pTrack);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700454 return NO_INIT;
455}
456
Andy Hungef7c7fb2014-05-12 16:51:41 -0700457void AudioMixer::unprepareTrackForReformat(track_t* pTrack, int trackName __unused) {
458 ALOGV("AudioMixer::unprepareTrackForReformat(%d)", trackName);
459 if (pTrack->mReformatBufferProvider != NULL) {
460 delete pTrack->mReformatBufferProvider;
461 pTrack->mReformatBufferProvider = NULL;
462 reconfigureBufferProviders(pTrack);
463 }
464}
465
466status_t AudioMixer::prepareTrackForReformat(track_t* pTrack, int trackName)
467{
468 ALOGV("AudioMixer::prepareTrackForReformat(%d) with format %#x", trackName, pTrack->mFormat);
469 // discard the previous reformatter if there was one
470 unprepareTrackForReformat(pTrack, trackName);
471 pTrack->mReformatBufferProvider = new ReformatBufferProvider(
472 audio_channel_count_from_out_mask(pTrack->channelMask),
473 pTrack->mFormat, pTrack->mMixerInFormat);
474 reconfigureBufferProviders(pTrack);
475 return NO_ERROR;
476}
477
478void AudioMixer::reconfigureBufferProviders(track_t* pTrack)
479{
480 pTrack->bufferProvider = pTrack->mInputBufferProvider;
481 if (pTrack->mReformatBufferProvider) {
482 pTrack->mReformatBufferProvider->mTrackBufferProvider = pTrack->bufferProvider;
483 pTrack->bufferProvider = pTrack->mReformatBufferProvider;
484 }
485 if (pTrack->downmixerBufferProvider) {
486 pTrack->downmixerBufferProvider->mTrackBufferProvider = pTrack->bufferProvider;
487 pTrack->bufferProvider = pTrack->downmixerBufferProvider;
488 }
489}
490
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800491void AudioMixer::deleteTrackName(int name)
492{
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700493 ALOGV("AudioMixer::deleteTrackName(%d)", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700494 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800495 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800496 ALOGV("deleteTrackName(%d)", name);
497 track_t& track(mState.tracks[ name ]);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800498 if (track.enabled) {
499 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800500 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700501 }
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700502 // delete the resampler
503 delete track.resampler;
504 track.resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700505 // delete the downmixer
506 unprepareTrackForDownmix(&mState.tracks[name], name);
Andy Hungef7c7fb2014-05-12 16:51:41 -0700507 // delete the reformatter
508 unprepareTrackForReformat(&mState.tracks[name], name);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700509
Glenn Kasten237a6242011-12-15 15:32:27 -0800510 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800511}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700512
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800513void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700514{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800515 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800516 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800517 track_t& track = mState.tracks[name];
518
Glenn Kasten4c340c62012-01-27 12:33:54 -0800519 if (!track.enabled) {
520 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800521 ALOGV("enable(%d)", name);
522 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700523 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700524}
525
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800526void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700527{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800528 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800529 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800530 track_t& track = mState.tracks[name];
531
Glenn Kasten4c340c62012-01-27 12:33:54 -0800532 if (track.enabled) {
533 track.enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800534 ALOGV("disable(%d)", name);
535 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700536 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700537}
538
Andy Hung5866a3b2014-05-29 21:33:13 -0700539/* Sets the volume ramp variables for the AudioMixer.
540 *
541 * The volume ramp variables are used to transition between the previous
542 * volume to the target volume. The duration of the transition is
543 * set by ramp, which is either 0 for immediate, or typically one state
544 * framecount period.
545 *
Andy Hung6be49402014-05-30 10:42:03 -0700546 * @param newFloatValue new volume target in float [0.0, 1.0].
Andy Hung5866a3b2014-05-29 21:33:13 -0700547 * @param ramp number of frames to increment over. ramp is 0 if the volume
548 * should be set immediately.
549 * @param volume reference to the U4.12 target volume, set on return.
550 * @param prevVolume reference to the U4.27 previous volume, set on return.
551 * @param volumeInc reference to the increment per output audio frame, set on return.
552 * @return true if the volume has changed, false if volume is same.
553 */
Andy Hung6be49402014-05-30 10:42:03 -0700554static inline bool setVolumeRampVariables(float newFloatValue, int32_t ramp,
Andy Hung5866a3b2014-05-29 21:33:13 -0700555 int16_t &volume, int32_t &prevVolume, int32_t &volumeInc) {
Andy Hung6be49402014-05-30 10:42:03 -0700556 int32_t newValue = newFloatValue * AudioMixer::UNITY_GAIN_INT;
557 if (newValue > AudioMixer::UNITY_GAIN_INT) {
558 newValue = AudioMixer::UNITY_GAIN_INT;
559 } else if (newValue < 0) {
560 ALOGE("negative volume %.7g", newFloatValue);
561 newValue = 0; // should never happen, but for safety check.
562 }
Andy Hung5866a3b2014-05-29 21:33:13 -0700563 if (newValue == volume) {
564 return false;
565 }
566 if (ramp != 0) {
567 volumeInc = ((newValue - volume) << 16) / ramp;
568 prevVolume = (volumeInc == 0 ? newValue : volume) << 16;
569 } else {
570 volumeInc = 0;
571 prevVolume = newValue << 16;
572 }
573 volume = newValue;
574 return true;
575}
576
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800577void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700578{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800579 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800580 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800581 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700582
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000583 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
584 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700585
586 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700587
Mathias Agopian65ab4712010-07-14 17:59:35 -0700588 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800589 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700590 case CHANNEL_MASK: {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000591 audio_channel_mask_t mask =
592 static_cast<audio_channel_mask_t>(reinterpret_cast<uintptr_t>(value));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800593 if (track.channelMask != mask) {
Andy Hunge5412692014-05-16 11:25:07 -0700594 uint32_t channelCount = audio_channel_count_from_out_mask(mask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700595 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800596 track.channelMask = mask;
597 track.channelCount = channelCount;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700598 // the mask has changed, does this track need a downmixer?
599 initTrackDownmix(&mState.tracks[name], name, mask);
Glenn Kasten788040c2011-05-05 08:19:00 -0700600 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800601 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700602 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700603 } break;
604 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800605 if (track.mainBuffer != valueBuf) {
606 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100607 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800608 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700609 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700610 break;
611 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800612 if (track.auxBuffer != valueBuf) {
613 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100614 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800615 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700616 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700617 break;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700618 case FORMAT: {
619 audio_format_t format = static_cast<audio_format_t>(valueInt);
620 if (track.mFormat != format) {
621 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
622 track.mFormat = format;
623 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
624 //if (track.mFormat != track.mMixerInFormat)
625 {
626 ALOGD("Reformatting!");
627 prepareTrackForReformat(&track, name);
628 }
629 invalidateState(1 << name);
630 }
631 } break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700632 // FIXME do we want to support setting the downmix type from AudioFlinger?
633 // for a specific track? or per mixer?
634 /* case DOWNMIX_TYPE:
635 break */
Andy Hung78820702014-02-28 16:23:02 -0800636 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800637 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung78820702014-02-28 16:23:02 -0800638 if (track.mMixerFormat != format) {
639 track.mMixerFormat = format;
640 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800641 }
642 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700643 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800644 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700645 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700646 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700647
Mathias Agopian65ab4712010-07-14 17:59:35 -0700648 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800649 switch (param) {
650 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800651 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700652 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
653 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
654 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800655 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700656 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800657 break;
658 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800659 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800660 invalidateState(1 << name);
661 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700662 case REMOVE:
663 delete track.resampler;
664 track.resampler = NULL;
665 track.sampleRate = mSampleRate;
666 invalidateState(1 << name);
667 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700668 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800669 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800670 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700671 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700672
Mathias Agopian65ab4712010-07-14 17:59:35 -0700673 case RAMP_VOLUME:
674 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800675 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700676 case VOLUME0:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800677 case VOLUME1:
Andy Hung6be49402014-05-30 10:42:03 -0700678 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung5866a3b2014-05-29 21:33:13 -0700679 target == RAMP_VOLUME ? mState.frameCount : 0,
680 track.volume[param - VOLUME0], track.prevVolume[param - VOLUME0],
681 track.volumeInc[param - VOLUME0])) {
682 ALOGV("setParameter(%s, VOLUME%d: %04x)",
Andy Hung6be49402014-05-30 10:42:03 -0700683 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
684 track.volume[param - VOLUME0]);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800685 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700686 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800687 break;
688 case AUXLEVEL:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800689 //ALOG_ASSERT(0 <= valueInt && valueInt <= MAX_GAIN_INT, "bad aux level %d", valueInt);
Andy Hung6be49402014-05-30 10:42:03 -0700690 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung5866a3b2014-05-29 21:33:13 -0700691 target == RAMP_VOLUME ? mState.frameCount : 0,
692 track.auxLevel, track.prevAuxLevel, track.auxInc)) {
693 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
Andy Hung6be49402014-05-30 10:42:03 -0700694 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track.auxLevel);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800695 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700696 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800697 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700698 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800699 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700700 }
701 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700702
703 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800704 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700705 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700706}
707
708bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
709{
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700710 if (value != devSampleRate || resampler != NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700711 if (sampleRate != value) {
712 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800713 if (resampler == NULL) {
Glenn Kastenac602052012-10-01 14:04:31 -0700714 ALOGV("creating resampler from track %d Hz to device %d Hz", value, devSampleRate);
715 AudioResampler::src_quality quality;
716 // force lowest quality level resampler if use case isn't music or video
717 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
718 // quality level based on the initial ratio, but that could change later.
719 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
720 if (!((value == 44100 && devSampleRate == 48000) ||
721 (value == 48000 && devSampleRate == 44100))) {
Andy Hung9e0308c2014-01-30 14:32:31 -0800722 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700723 } else {
724 quality = AudioResampler::DEFAULT_QUALITY;
725 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700726 const int bits = mMixerInFormat == AUDIO_FORMAT_PCM_16_BIT ? 16 : /* FLOAT */ 32;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700727 resampler = AudioResampler::create(
Andy Hungef7c7fb2014-05-12 16:51:41 -0700728 bits,
Jean-Michel Triviacb86cc2012-04-16 12:43:57 -0700729 // the resampler sees the number of channels after the downmixer, if any
Glenn Kastenf551e992013-08-19 18:45:42 -0700730 (int) (downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount),
Glenn Kastenac602052012-10-01 14:04:31 -0700731 devSampleRate, quality);
Glenn Kasten52008f82012-03-18 09:34:41 -0700732 resampler->setLocalTimeFreq(sLocalTimeFreq);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700733 }
734 return true;
735 }
736 }
737 return false;
738}
739
Mathias Agopian65ab4712010-07-14 17:59:35 -0700740inline
741void AudioMixer::track_t::adjustVolumeRamp(bool aux)
742{
Glenn Kastenf9a27772012-01-06 07:47:26 -0800743 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700744 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
745 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
746 volumeInc[i] = 0;
747 prevVolume[i] = volume[i]<<16;
748 }
749 }
750 if (aux) {
751 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
752 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
753 auxInc = 0;
754 prevAuxLevel = auxLevel<<16;
755 }
756 }
757}
758
Glenn Kastenc59c0042012-02-02 14:06:11 -0800759size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800760{
761 name -= TRACK0;
762 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800763 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800764 }
765 return 0;
766}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700767
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800768void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700769{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800770 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800771 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700772
Andy Hung1d26ddf2014-05-29 15:53:09 -0700773 if (mState.tracks[name].mInputBufferProvider == bufferProvider) {
774 return; // don't reset any buffer providers if identical.
775 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700776 if (mState.tracks[name].mReformatBufferProvider != NULL) {
777 mState.tracks[name].mReformatBufferProvider->reset();
778 } else if (mState.tracks[name].downmixerBufferProvider != NULL) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700779 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700780
781 mState.tracks[name].mInputBufferProvider = bufferProvider;
782 reconfigureBufferProviders(&mState.tracks[name]);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700783}
784
785
John Grossman4ff14ba2012-02-08 16:37:41 -0800786void AudioMixer::process(int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700787{
John Grossman4ff14ba2012-02-08 16:37:41 -0800788 mState.hook(&mState, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700789}
790
791
John Grossman4ff14ba2012-02-08 16:37:41 -0800792void AudioMixer::process__validate(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700793{
Steve Block5ff1dd52012-01-05 23:22:43 +0000794 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700795 "in process__validate() but nothing's invalid");
796
797 uint32_t changed = state->needsChanged;
798 state->needsChanged = 0; // clear the validation flag
799
800 // recompute which tracks are enabled / disabled
801 uint32_t enabled = 0;
802 uint32_t disabled = 0;
803 while (changed) {
804 const int i = 31 - __builtin_clz(changed);
805 const uint32_t mask = 1<<i;
806 changed &= ~mask;
807 track_t& t = state->tracks[i];
808 (t.enabled ? enabled : disabled) |= mask;
809 }
810 state->enabledTracks &= ~disabled;
811 state->enabledTracks |= enabled;
812
813 // compute everything we need...
814 int countActiveTracks = 0;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800815 bool all16BitsStereoNoResample = true;
816 bool resampling = false;
817 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700818 uint32_t en = state->enabledTracks;
819 while (en) {
820 const int i = 31 - __builtin_clz(en);
821 en &= ~(1<<i);
822
823 countActiveTracks++;
824 track_t& t = state->tracks[i];
825 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700826 // FIXME can overflow (mask is only 3 bits)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700827 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700828 if (t.doesResample()) {
829 n |= NEEDS_RESAMPLE;
830 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700831 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700832 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700833 }
834
835 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800836 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700837 } else if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700838 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700839 }
840 t.needs = n;
841
Glenn Kastend6fadf02013-10-30 14:37:29 -0700842 if (n & NEEDS_MUTE) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700843 t.hook = track__nop;
844 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700845 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800846 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700847 }
Glenn Kastend6fadf02013-10-30 14:37:29 -0700848 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800849 all16BitsStereoNoResample = false;
850 resampling = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700851 t.hook = track__genericResample;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700852 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700853 "Track %d needs downmix + resample", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700854 } else {
855 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
856 t.hook = track__16BitsMono;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800857 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700858 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700859 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Mathias Agopian65ab4712010-07-14 17:59:35 -0700860 t.hook = track__16BitsStereo;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700861 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700862 "Track %d needs downmix", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700863 }
864 }
865 }
866 }
867
868 // select the processing hooks
869 state->hook = process__nop;
Glenn Kasten34fca342013-08-13 09:48:14 -0700870 if (countActiveTracks > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700871 if (resampling) {
872 if (!state->outputTemp) {
873 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
874 }
875 if (!state->resampleTemp) {
876 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
877 }
878 state->hook = process__genericResampling;
879 } else {
880 if (state->outputTemp) {
881 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800882 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700883 }
884 if (state->resampleTemp) {
885 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800886 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700887 }
888 state->hook = process__genericNoResampling;
889 if (all16BitsStereoNoResample && !volumeRamp) {
890 if (countActiveTracks == 1) {
891 state->hook = process__OneTrack16BitsStereoNoResampling;
892 }
893 }
894 }
895 }
896
Steve Block3856b092011-10-20 11:56:00 +0100897 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700898 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
899 countActiveTracks, state->enabledTracks,
900 all16BitsStereoNoResample, resampling, volumeRamp);
901
John Grossman4ff14ba2012-02-08 16:37:41 -0800902 state->hook(state, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700903
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800904 // Now that the volume ramp has been done, set optimal state and
905 // track hooks for subsequent mixer process
Glenn Kasten34fca342013-08-13 09:48:14 -0700906 if (countActiveTracks > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800907 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800908 uint32_t en = state->enabledTracks;
909 while (en) {
910 const int i = 31 - __builtin_clz(en);
911 en &= ~(1<<i);
912 track_t& t = state->tracks[i];
Glenn Kasten6e2ebe92013-08-13 09:14:51 -0700913 if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700914 t.needs |= NEEDS_MUTE;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800915 t.hook = track__nop;
916 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800917 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800918 }
919 }
920 if (allMuted) {
921 state->hook = process__nop;
922 } else if (all16BitsStereoNoResample) {
923 if (countActiveTracks == 1) {
924 state->hook = process__OneTrack16BitsStereoNoResampling;
925 }
926 }
927 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700928}
929
Mathias Agopian65ab4712010-07-14 17:59:35 -0700930
Glenn Kasten85ab62c2012-11-01 11:11:38 -0700931void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount,
932 int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700933{
934 t->resampler->setSampleRate(t->sampleRate);
935
936 // ramp gain - resample to temp buffer and scale/mix in 2nd step
937 if (aux != NULL) {
938 // always resample with unity gain when sending to auxiliary buffer to be able
939 // to apply send level after resampling
940 // TODO: modify each resampler to support aux channel?
Andy Hung97ae8242014-05-30 10:35:47 -0700941 t->resampler->setVolume(UNITY_GAIN_INT, UNITY_GAIN_INT);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700942 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
943 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -0800944 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700945 volumeRampStereo(t, out, outFrameCount, temp, aux);
946 } else {
947 volumeStereo(t, out, outFrameCount, temp, aux);
948 }
949 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -0800950 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Andy Hung97ae8242014-05-30 10:35:47 -0700951 t->resampler->setVolume(UNITY_GAIN_INT, UNITY_GAIN_INT);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700952 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
953 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
954 volumeRampStereo(t, out, outFrameCount, temp, aux);
955 }
956
957 // constant gain
958 else {
959 t->resampler->setVolume(t->volume[0], t->volume[1]);
960 t->resampler->resample(out, outFrameCount, t->bufferProvider);
961 }
962 }
963}
964
Andy Hungee931ff2014-01-28 13:44:14 -0800965void AudioMixer::track__nop(track_t* t __unused, int32_t* out __unused,
966 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700967{
968}
969
Glenn Kasten85ab62c2012-11-01 11:11:38 -0700970void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
971 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700972{
973 int32_t vl = t->prevVolume[0];
974 int32_t vr = t->prevVolume[1];
975 const int32_t vlInc = t->volumeInc[0];
976 const int32_t vrInc = t->volumeInc[1];
977
Steve Blockb8a80522011-12-20 16:23:08 +0000978 //ALOGD("[0] %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 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -0800983 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700984 int32_t va = t->prevAuxLevel;
985 const int32_t vaInc = t->auxInc;
986 int32_t l;
987 int32_t r;
988
989 do {
990 l = (*temp++ >> 12);
991 r = (*temp++ >> 12);
992 *out++ += (vl >> 16) * l;
993 *out++ += (vr >> 16) * r;
994 *aux++ += (va >> 17) * (l + r);
995 vl += vlInc;
996 vr += vrInc;
997 va += vaInc;
998 } while (--frameCount);
999 t->prevAuxLevel = va;
1000 } else {
1001 do {
1002 *out++ += (vl >> 16) * (*temp++ >> 12);
1003 *out++ += (vr >> 16) * (*temp++ >> 12);
1004 vl += vlInc;
1005 vr += vrInc;
1006 } while (--frameCount);
1007 }
1008 t->prevVolume[0] = vl;
1009 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -08001010 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001011}
1012
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001013void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1014 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001015{
1016 const int16_t vl = t->volume[0];
1017 const int16_t vr = t->volume[1];
1018
Glenn Kastenf6b16782011-12-15 09:51:17 -08001019 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -08001020 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001021 do {
1022 int16_t l = (int16_t)(*temp++ >> 12);
1023 int16_t r = (int16_t)(*temp++ >> 12);
1024 out[0] = mulAdd(l, vl, out[0]);
1025 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
1026 out[1] = mulAdd(r, vr, out[1]);
1027 out += 2;
1028 aux[0] = mulAdd(a, va, aux[0]);
1029 aux++;
1030 } while (--frameCount);
1031 } else {
1032 do {
1033 int16_t l = (int16_t)(*temp++ >> 12);
1034 int16_t r = (int16_t)(*temp++ >> 12);
1035 out[0] = mulAdd(l, vl, out[0]);
1036 out[1] = mulAdd(r, vr, out[1]);
1037 out += 2;
1038 } while (--frameCount);
1039 }
1040}
1041
Andy Hungee931ff2014-01-28 13:44:14 -08001042void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount,
1043 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001044{
Glenn Kasten54c3b662012-01-06 07:46:30 -08001045 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001046
Glenn Kastenf6b16782011-12-15 09:51:17 -08001047 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001048 int32_t l;
1049 int32_t r;
1050 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001051 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001052 int32_t vl = t->prevVolume[0];
1053 int32_t vr = t->prevVolume[1];
1054 int32_t va = t->prevAuxLevel;
1055 const int32_t vlInc = t->volumeInc[0];
1056 const int32_t vrInc = t->volumeInc[1];
1057 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +00001058 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001059 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1060 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1061
1062 do {
1063 l = (int32_t)*in++;
1064 r = (int32_t)*in++;
1065 *out++ += (vl >> 16) * l;
1066 *out++ += (vr >> 16) * r;
1067 *aux++ += (va >> 17) * (l + r);
1068 vl += vlInc;
1069 vr += vrInc;
1070 va += vaInc;
1071 } while (--frameCount);
1072
1073 t->prevVolume[0] = vl;
1074 t->prevVolume[1] = vr;
1075 t->prevAuxLevel = va;
1076 t->adjustVolumeRamp(true);
1077 }
1078
1079 // constant gain
1080 else {
1081 const uint32_t vrl = t->volumeRL;
1082 const int16_t va = (int16_t)t->auxLevel;
1083 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001084 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001085 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
1086 in += 2;
1087 out[0] = mulAddRL(1, rl, vrl, out[0]);
1088 out[1] = mulAddRL(0, rl, vrl, out[1]);
1089 out += 2;
1090 aux[0] = mulAdd(a, va, aux[0]);
1091 aux++;
1092 } while (--frameCount);
1093 }
1094 } else {
1095 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001096 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001097 int32_t vl = t->prevVolume[0];
1098 int32_t vr = t->prevVolume[1];
1099 const int32_t vlInc = t->volumeInc[0];
1100 const int32_t vrInc = t->volumeInc[1];
1101
Steve Blockb8a80522011-12-20 16:23:08 +00001102 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001103 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1104 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1105
1106 do {
1107 *out++ += (vl >> 16) * (int32_t) *in++;
1108 *out++ += (vr >> 16) * (int32_t) *in++;
1109 vl += vlInc;
1110 vr += vrInc;
1111 } while (--frameCount);
1112
1113 t->prevVolume[0] = vl;
1114 t->prevVolume[1] = vr;
1115 t->adjustVolumeRamp(false);
1116 }
1117
1118 // constant gain
1119 else {
1120 const uint32_t vrl = t->volumeRL;
1121 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001122 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001123 in += 2;
1124 out[0] = mulAddRL(1, rl, vrl, out[0]);
1125 out[1] = mulAddRL(0, rl, vrl, out[1]);
1126 out += 2;
1127 } while (--frameCount);
1128 }
1129 }
1130 t->in = in;
1131}
1132
Andy Hungee931ff2014-01-28 13:44:14 -08001133void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount,
1134 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001135{
Glenn Kasten54c3b662012-01-06 07:46:30 -08001136 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001137
Glenn Kastenf6b16782011-12-15 09:51:17 -08001138 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001139 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001140 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001141 int32_t vl = t->prevVolume[0];
1142 int32_t vr = t->prevVolume[1];
1143 int32_t va = t->prevAuxLevel;
1144 const int32_t vlInc = t->volumeInc[0];
1145 const int32_t vrInc = t->volumeInc[1];
1146 const int32_t vaInc = t->auxInc;
1147
Steve Blockb8a80522011-12-20 16:23:08 +00001148 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001149 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1150 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1151
1152 do {
1153 int32_t l = *in++;
1154 *out++ += (vl >> 16) * l;
1155 *out++ += (vr >> 16) * l;
1156 *aux++ += (va >> 16) * l;
1157 vl += vlInc;
1158 vr += vrInc;
1159 va += vaInc;
1160 } while (--frameCount);
1161
1162 t->prevVolume[0] = vl;
1163 t->prevVolume[1] = vr;
1164 t->prevAuxLevel = va;
1165 t->adjustVolumeRamp(true);
1166 }
1167 // constant gain
1168 else {
1169 const int16_t vl = t->volume[0];
1170 const int16_t vr = t->volume[1];
1171 const int16_t va = (int16_t)t->auxLevel;
1172 do {
1173 int16_t l = *in++;
1174 out[0] = mulAdd(l, vl, out[0]);
1175 out[1] = mulAdd(l, vr, out[1]);
1176 out += 2;
1177 aux[0] = mulAdd(l, va, aux[0]);
1178 aux++;
1179 } while (--frameCount);
1180 }
1181 } else {
1182 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001183 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001184 int32_t vl = t->prevVolume[0];
1185 int32_t vr = t->prevVolume[1];
1186 const int32_t vlInc = t->volumeInc[0];
1187 const int32_t vrInc = t->volumeInc[1];
1188
Steve Blockb8a80522011-12-20 16:23:08 +00001189 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001190 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1191 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1192
1193 do {
1194 int32_t l = *in++;
1195 *out++ += (vl >> 16) * l;
1196 *out++ += (vr >> 16) * l;
1197 vl += vlInc;
1198 vr += vrInc;
1199 } while (--frameCount);
1200
1201 t->prevVolume[0] = vl;
1202 t->prevVolume[1] = vr;
1203 t->adjustVolumeRamp(false);
1204 }
1205 // constant gain
1206 else {
1207 const int16_t vl = t->volume[0];
1208 const int16_t vr = t->volume[1];
1209 do {
1210 int16_t l = *in++;
1211 out[0] = mulAdd(l, vl, out[0]);
1212 out[1] = mulAdd(l, vr, out[1]);
1213 out += 2;
1214 } while (--frameCount);
1215 }
1216 }
1217 t->in = in;
1218}
1219
Mathias Agopian65ab4712010-07-14 17:59:35 -07001220// no-op case
John Grossman4ff14ba2012-02-08 16:37:41 -08001221void AudioMixer::process__nop(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001222{
1223 uint32_t e0 = state->enabledTracks;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001224 size_t sampleCount = state->frameCount * MAX_NUM_CHANNELS;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001225 while (e0) {
1226 // process by group of tracks with same output buffer to
1227 // avoid multiple memset() on same buffer
1228 uint32_t e1 = e0, e2 = e0;
1229 int i = 31 - __builtin_clz(e1);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001230 {
1231 track_t& t1 = state->tracks[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001232 e2 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001233 while (e2) {
1234 i = 31 - __builtin_clz(e2);
1235 e2 &= ~(1<<i);
1236 track_t& t2 = state->tracks[i];
1237 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1238 e1 &= ~(1<<i);
1239 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001240 }
Glenn Kastenfc900c92013-02-18 12:47:49 -08001241 e0 &= ~(e1);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001242
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001243 memset(t1.mainBuffer, 0, sampleCount
Andy Hung78820702014-02-28 16:23:02 -08001244 * audio_bytes_per_sample(t1.mMixerFormat));
Glenn Kastenfc900c92013-02-18 12:47:49 -08001245 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001246
1247 while (e1) {
1248 i = 31 - __builtin_clz(e1);
1249 e1 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001250 {
1251 track_t& t3 = state->tracks[i];
1252 size_t outFrames = state->frameCount;
1253 while (outFrames) {
1254 t3.buffer.frameCount = outFrames;
1255 int64_t outputPTS = calculateOutputPTS(
1256 t3, pts, state->frameCount - outFrames);
1257 t3.bufferProvider->getNextBuffer(&t3.buffer, outputPTS);
1258 if (t3.buffer.raw == NULL) break;
1259 outFrames -= t3.buffer.frameCount;
1260 t3.bufferProvider->releaseBuffer(&t3.buffer);
1261 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001262 }
1263 }
1264 }
1265}
1266
1267// generic code without resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001268void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001269{
1270 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1271
1272 // acquire each track's buffer
1273 uint32_t enabledTracks = state->enabledTracks;
1274 uint32_t e0 = enabledTracks;
1275 while (e0) {
1276 const int i = 31 - __builtin_clz(e0);
1277 e0 &= ~(1<<i);
1278 track_t& t = state->tracks[i];
1279 t.buffer.frameCount = state->frameCount;
John Grossman4ff14ba2012-02-08 16:37:41 -08001280 t.bufferProvider->getNextBuffer(&t.buffer, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001281 t.frameCount = t.buffer.frameCount;
1282 t.in = t.buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001283 }
1284
1285 e0 = enabledTracks;
1286 while (e0) {
1287 // process by group of tracks with same output buffer to
1288 // optimize cache use
1289 uint32_t e1 = e0, e2 = e0;
1290 int j = 31 - __builtin_clz(e1);
1291 track_t& t1 = state->tracks[j];
1292 e2 &= ~(1<<j);
1293 while (e2) {
1294 j = 31 - __builtin_clz(e2);
1295 e2 &= ~(1<<j);
1296 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001297 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001298 e1 &= ~(1<<j);
1299 }
1300 }
1301 e0 &= ~(e1);
1302 // this assumes output 16 bits stereo, no resampling
1303 int32_t *out = t1.mainBuffer;
1304 size_t numFrames = 0;
1305 do {
1306 memset(outTemp, 0, sizeof(outTemp));
1307 e2 = e1;
1308 while (e2) {
1309 const int i = 31 - __builtin_clz(e2);
1310 e2 &= ~(1<<i);
1311 track_t& t = state->tracks[i];
1312 size_t outFrames = BLOCKSIZE;
1313 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001314 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001315 aux = t.auxBuffer + numFrames;
1316 }
1317 while (outFrames) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301318 // t.in == NULL can happen if the track was flushed just after having
1319 // been enabled for mixing.
1320 if (t.in == NULL) {
1321 enabledTracks &= ~(1<<i);
1322 e1 &= ~(1<<i);
1323 break;
1324 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001325 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001326 if (inFrames > 0) {
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001327 t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames,
1328 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001329 t.frameCount -= inFrames;
1330 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001331 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001332 aux += inFrames;
1333 }
1334 }
1335 if (t.frameCount == 0 && outFrames) {
1336 t.bufferProvider->releaseBuffer(&t.buffer);
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001337 t.buffer.frameCount = (state->frameCount - numFrames) -
1338 (BLOCKSIZE - outFrames);
John Grossman4ff14ba2012-02-08 16:37:41 -08001339 int64_t outputPTS = calculateOutputPTS(
1340 t, pts, numFrames + (BLOCKSIZE - outFrames));
1341 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001342 t.in = t.buffer.raw;
1343 if (t.in == NULL) {
1344 enabledTracks &= ~(1<<i);
1345 e1 &= ~(1<<i);
1346 break;
1347 }
1348 t.frameCount = t.buffer.frameCount;
1349 }
1350 }
1351 }
Andy Hung78820702014-02-28 16:23:02 -08001352 switch (t1.mMixerFormat) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001353 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung84a0c6e2014-04-02 11:24:53 -07001354 memcpy_to_float_from_q4_27(reinterpret_cast<float *>(out), outTemp, BLOCKSIZE * 2);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001355 out += BLOCKSIZE * 2; // output is 2 floats/frame.
1356 break;
1357 case AUDIO_FORMAT_PCM_16_BIT:
1358 ditherAndClamp(out, outTemp, BLOCKSIZE);
1359 out += BLOCKSIZE; // output is 1 int32_t (2 int16_t samples)/frame
1360 break;
1361 default:
Andy Hung78820702014-02-28 16:23:02 -08001362 LOG_ALWAYS_FATAL("bad mixer format: %d", t1.mMixerFormat);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001363 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001364 numFrames += BLOCKSIZE;
1365 } while (numFrames < state->frameCount);
1366 }
1367
1368 // release each track's buffer
1369 e0 = enabledTracks;
1370 while (e0) {
1371 const int i = 31 - __builtin_clz(e0);
1372 e0 &= ~(1<<i);
1373 track_t& t = state->tracks[i];
1374 t.bufferProvider->releaseBuffer(&t.buffer);
1375 }
1376}
1377
1378
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001379// generic code with resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001380void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001381{
Glenn Kasten54c3b662012-01-06 07:46:30 -08001382 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -07001383 int32_t* const outTemp = state->outputTemp;
1384 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001385
1386 size_t numFrames = state->frameCount;
1387
1388 uint32_t e0 = state->enabledTracks;
1389 while (e0) {
1390 // process by group of tracks with same output buffer
1391 // to optimize cache use
1392 uint32_t e1 = e0, e2 = e0;
1393 int j = 31 - __builtin_clz(e1);
1394 track_t& t1 = state->tracks[j];
1395 e2 &= ~(1<<j);
1396 while (e2) {
1397 j = 31 - __builtin_clz(e2);
1398 e2 &= ~(1<<j);
1399 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001400 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001401 e1 &= ~(1<<j);
1402 }
1403 }
1404 e0 &= ~(e1);
1405 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +01001406 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001407 while (e1) {
1408 const int i = 31 - __builtin_clz(e1);
1409 e1 &= ~(1<<i);
1410 track_t& t = state->tracks[i];
1411 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001412 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001413 aux = t.auxBuffer;
1414 }
1415
1416 // this is a little goofy, on the resampling case we don't
1417 // acquire/release the buffers because it's done by
1418 // the resampler.
Glenn Kastend6fadf02013-10-30 14:37:29 -07001419 if (t.needs & NEEDS_RESAMPLE) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001420 t.resampler->setPTS(pts);
Glenn Kastena1117922012-01-26 10:53:32 -08001421 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001422 } else {
1423
1424 size_t outFrames = 0;
1425
1426 while (outFrames < numFrames) {
1427 t.buffer.frameCount = numFrames - outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001428 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
1429 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001430 t.in = t.buffer.raw;
1431 // t.in == NULL can happen if the track was flushed just after having
1432 // been enabled for mixing.
1433 if (t.in == NULL) break;
1434
Glenn Kastenf6b16782011-12-15 09:51:17 -08001435 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001436 aux += outFrames;
1437 }
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001438 t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount,
1439 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001440 outFrames += t.buffer.frameCount;
1441 t.bufferProvider->releaseBuffer(&t.buffer);
1442 }
1443 }
1444 }
Andy Hung78820702014-02-28 16:23:02 -08001445 switch (t1.mMixerFormat) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001446 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung84a0c6e2014-04-02 11:24:53 -07001447 memcpy_to_float_from_q4_27(reinterpret_cast<float*>(out), outTemp, numFrames*2);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001448 break;
1449 case AUDIO_FORMAT_PCM_16_BIT:
1450 ditherAndClamp(out, outTemp, numFrames);
1451 break;
1452 default:
Andy Hung78820702014-02-28 16:23:02 -08001453 LOG_ALWAYS_FATAL("bad mixer format: %d", t1.mMixerFormat);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001454 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001455 }
1456}
1457
1458// one track, 16 bits stereo without resampling is the most common case
John Grossman4ff14ba2012-02-08 16:37:41 -08001459void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
1460 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001461{
Glenn Kasten99e53b82012-01-19 08:59:58 -08001462 // This method is only called when state->enabledTracks has exactly
1463 // one bit set. The asserts below would verify this, but are commented out
1464 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001465 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001466 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001467 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001468 const track_t& t = state->tracks[i];
1469
1470 AudioBufferProvider::Buffer& b(t.buffer);
1471
1472 int32_t* out = t.mainBuffer;
Andy Hungf8a106a2014-05-29 18:52:38 -07001473 float *fout = reinterpret_cast<float*>(out);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001474 size_t numFrames = state->frameCount;
1475
1476 const int16_t vl = t.volume[0];
1477 const int16_t vr = t.volume[1];
1478 const uint32_t vrl = t.volumeRL;
1479 while (numFrames) {
1480 b.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001481 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
1482 t.bufferProvider->getNextBuffer(&b, outputPTS);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001483 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001484
1485 // in == NULL can happen if the track was flushed just after having
1486 // been enabled for mixing.
Andy Hungf8a106a2014-05-29 18:52:38 -07001487 if (in == NULL || (((uintptr_t)in) & 3)) {
1488 memset(out, 0, numFrames
1489 * MAX_NUM_CHANNELS * audio_bytes_per_sample(t.mMixerFormat));
1490 ALOGE_IF((((uintptr_t)in) & 3), "process stereo track: input buffer alignment pb: "
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001491 "buffer %p track %d, channels %d, needs %08x",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001492 in, i, t.channelCount, t.needs);
1493 return;
1494 }
1495 size_t outFrames = b.frameCount;
1496
Andy Hung78820702014-02-28 16:23:02 -08001497 switch (t.mMixerFormat) {
Andy Hungf8a106a2014-05-29 18:52:38 -07001498 case AUDIO_FORMAT_PCM_FLOAT:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001499 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001500 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001501 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001502 int32_t l = mulRL(1, rl, vrl);
1503 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001504 *fout++ = float_from_q4_27(l);
1505 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001506 // Note: In case of later int16_t sink output,
1507 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001508 } while (--outFrames);
Andy Hungf8a106a2014-05-29 18:52:38 -07001509 break;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001510 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung97ae8242014-05-30 10:35:47 -07001511 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001512 // volume is boosted, so we might need to clamp even though
1513 // we process only one track.
1514 do {
1515 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1516 in += 2;
1517 int32_t l = mulRL(1, rl, vrl) >> 12;
1518 int32_t r = mulRL(0, rl, vrl) >> 12;
1519 // clamping...
1520 l = clamp16(l);
1521 r = clamp16(r);
1522 *out++ = (r<<16) | (l & 0xFFFF);
1523 } while (--outFrames);
1524 } else {
1525 do {
1526 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1527 in += 2;
1528 int32_t l = mulRL(1, rl, vrl) >> 12;
1529 int32_t r = mulRL(0, rl, vrl) >> 12;
1530 *out++ = (r<<16) | (l & 0xFFFF);
1531 } while (--outFrames);
1532 }
1533 break;
1534 default:
Andy Hung78820702014-02-28 16:23:02 -08001535 LOG_ALWAYS_FATAL("bad mixer format: %d", t.mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001536 }
1537 numFrames -= b.frameCount;
1538 t.bufferProvider->releaseBuffer(&b);
1539 }
1540}
1541
Glenn Kasten81a028f2011-12-15 09:53:12 -08001542#if 0
Mathias Agopian65ab4712010-07-14 17:59:35 -07001543// 2 tracks is also a common case
1544// NEVER used in current implementation of process__validate()
1545// only use if the 2 tracks have the same output buffer
John Grossman4ff14ba2012-02-08 16:37:41 -08001546void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state,
1547 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001548{
1549 int i;
1550 uint32_t en = state->enabledTracks;
1551
1552 i = 31 - __builtin_clz(en);
1553 const track_t& t0 = state->tracks[i];
1554 AudioBufferProvider::Buffer& b0(t0.buffer);
1555
1556 en &= ~(1<<i);
1557 i = 31 - __builtin_clz(en);
1558 const track_t& t1 = state->tracks[i];
1559 AudioBufferProvider::Buffer& b1(t1.buffer);
1560
Glenn Kasten54c3b662012-01-06 07:46:30 -08001561 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001562 const int16_t vl0 = t0.volume[0];
1563 const int16_t vr0 = t0.volume[1];
1564 size_t frameCount0 = 0;
1565
Glenn Kasten54c3b662012-01-06 07:46:30 -08001566 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001567 const int16_t vl1 = t1.volume[0];
1568 const int16_t vr1 = t1.volume[1];
1569 size_t frameCount1 = 0;
1570
1571 //FIXME: only works if two tracks use same buffer
1572 int32_t* out = t0.mainBuffer;
1573 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001574 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001575
1576
1577 while (numFrames) {
1578
1579 if (frameCount0 == 0) {
1580 b0.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001581 int64_t outputPTS = calculateOutputPTS(t0, pts,
1582 out - t0.mainBuffer);
1583 t0.bufferProvider->getNextBuffer(&b0, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001584 if (b0.i16 == NULL) {
1585 if (buff == NULL) {
1586 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1587 }
1588 in0 = buff;
1589 b0.frameCount = numFrames;
1590 } else {
1591 in0 = b0.i16;
1592 }
1593 frameCount0 = b0.frameCount;
1594 }
1595 if (frameCount1 == 0) {
1596 b1.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001597 int64_t outputPTS = calculateOutputPTS(t1, pts,
1598 out - t0.mainBuffer);
1599 t1.bufferProvider->getNextBuffer(&b1, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001600 if (b1.i16 == NULL) {
1601 if (buff == NULL) {
1602 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1603 }
1604 in1 = buff;
1605 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001606 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001607 in1 = b1.i16;
1608 }
1609 frameCount1 = b1.frameCount;
1610 }
1611
1612 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1613
1614 numFrames -= outFrames;
1615 frameCount0 -= outFrames;
1616 frameCount1 -= outFrames;
1617
1618 do {
1619 int32_t l0 = *in0++;
1620 int32_t r0 = *in0++;
1621 l0 = mul(l0, vl0);
1622 r0 = mul(r0, vr0);
1623 int32_t l = *in1++;
1624 int32_t r = *in1++;
1625 l = mulAdd(l, vl1, l0) >> 12;
1626 r = mulAdd(r, vr1, r0) >> 12;
1627 // clamping...
1628 l = clamp16(l);
1629 r = clamp16(r);
1630 *out++ = (r<<16) | (l & 0xFFFF);
1631 } while (--outFrames);
1632
1633 if (frameCount0 == 0) {
1634 t0.bufferProvider->releaseBuffer(&b0);
1635 }
1636 if (frameCount1 == 0) {
1637 t1.bufferProvider->releaseBuffer(&b1);
1638 }
1639 }
1640
Glenn Kastene9dd0172012-01-27 18:08:45 -08001641 delete [] buff;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001642}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001643#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001644
John Grossman4ff14ba2012-02-08 16:37:41 -08001645int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1646 int outputFrameIndex)
1647{
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001648 if (AudioBufferProvider::kInvalidPTS == basePTS) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001649 return AudioBufferProvider::kInvalidPTS;
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001650 }
John Grossman4ff14ba2012-02-08 16:37:41 -08001651
Glenn Kasten52008f82012-03-18 09:34:41 -07001652 return basePTS + ((outputFrameIndex * sLocalTimeFreq) / t.sampleRate);
1653}
1654
1655/*static*/ uint64_t AudioMixer::sLocalTimeFreq;
1656/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1657
1658/*static*/ void AudioMixer::sInitRoutine()
1659{
1660 LocalClock lc;
1661 sLocalTimeFreq = lc.getLocalFreq();
Glenn Kasten49c34ac2013-10-30 14:37:01 -07001662
1663 // find multichannel downmix effect if we have to play multichannel content
1664 uint32_t numEffects = 0;
1665 int ret = EffectQueryNumberEffects(&numEffects);
1666 if (ret != 0) {
1667 ALOGE("AudioMixer() error %d querying number of effects", ret);
1668 return;
1669 }
1670 ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects);
1671
1672 for (uint32_t i = 0 ; i < numEffects ; i++) {
1673 if (EffectQueryEffect(i, &sDwnmFxDesc) == 0) {
1674 ALOGV("effect %d is called %s", i, sDwnmFxDesc.name);
1675 if (memcmp(&sDwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) {
1676 ALOGI("found effect \"%s\" from %s",
1677 sDwnmFxDesc.name, sDwnmFxDesc.implementor);
1678 sIsMultichannelCapable = true;
1679 break;
1680 }
1681 }
1682 }
1683 ALOGW_IF(!sIsMultichannelCapable, "unable to find downmix effect");
John Grossman4ff14ba2012-02-08 16:37:41 -08001684}
1685
Mathias Agopian65ab4712010-07-14 17:59:35 -07001686// ----------------------------------------------------------------------------
1687}; // namespace android