blob: 407694bf2014b6dbf26daa0efc4e087fc1770a75 [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;
268 t->volume[0] = UNITY_GAIN;
269 t->volume[1] = UNITY_GAIN;
270 // 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 *
546 * @param newValue new volume target in U4.12.
547 * @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 */
554static inline bool setVolumeRampVariables(int32_t newValue, int32_t ramp,
555 int16_t &volume, int32_t &prevVolume, int32_t &volumeInc) {
556 if (newValue == volume) {
557 return false;
558 }
559 if (ramp != 0) {
560 volumeInc = ((newValue - volume) << 16) / ramp;
561 prevVolume = (volumeInc == 0 ? newValue : volume) << 16;
562 } else {
563 volumeInc = 0;
564 prevVolume = newValue << 16;
565 }
566 volume = newValue;
567 return true;
568}
569
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800570void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700571{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800572 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800573 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800574 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700575
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000576 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
577 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700578
579 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700580
Mathias Agopian65ab4712010-07-14 17:59:35 -0700581 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800582 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700583 case CHANNEL_MASK: {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000584 audio_channel_mask_t mask =
585 static_cast<audio_channel_mask_t>(reinterpret_cast<uintptr_t>(value));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800586 if (track.channelMask != mask) {
Andy Hunge5412692014-05-16 11:25:07 -0700587 uint32_t channelCount = audio_channel_count_from_out_mask(mask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700588 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800589 track.channelMask = mask;
590 track.channelCount = channelCount;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700591 // the mask has changed, does this track need a downmixer?
592 initTrackDownmix(&mState.tracks[name], name, mask);
Glenn Kasten788040c2011-05-05 08:19:00 -0700593 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800594 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700595 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700596 } break;
597 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800598 if (track.mainBuffer != valueBuf) {
599 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100600 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
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 AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800605 if (track.auxBuffer != valueBuf) {
606 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100607 ALOGV("setParameter(TRACK, AUX_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;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700611 case FORMAT: {
612 audio_format_t format = static_cast<audio_format_t>(valueInt);
613 if (track.mFormat != format) {
614 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
615 track.mFormat = format;
616 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
617 //if (track.mFormat != track.mMixerInFormat)
618 {
619 ALOGD("Reformatting!");
620 prepareTrackForReformat(&track, name);
621 }
622 invalidateState(1 << name);
623 }
624 } break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700625 // FIXME do we want to support setting the downmix type from AudioFlinger?
626 // for a specific track? or per mixer?
627 /* case DOWNMIX_TYPE:
628 break */
Andy Hung78820702014-02-28 16:23:02 -0800629 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800630 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung78820702014-02-28 16:23:02 -0800631 if (track.mMixerFormat != format) {
632 track.mMixerFormat = format;
633 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800634 }
635 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700636 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800637 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700638 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700639 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700640
Mathias Agopian65ab4712010-07-14 17:59:35 -0700641 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800642 switch (param) {
643 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800644 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700645 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
646 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
647 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800648 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700649 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800650 break;
651 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800652 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800653 invalidateState(1 << name);
654 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700655 case REMOVE:
656 delete track.resampler;
657 track.resampler = NULL;
658 track.sampleRate = mSampleRate;
659 invalidateState(1 << name);
660 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700661 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800662 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800663 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700664 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700665
Mathias Agopian65ab4712010-07-14 17:59:35 -0700666 case RAMP_VOLUME:
667 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800668 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700669 case VOLUME0:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800670 case VOLUME1:
Andy Hung5866a3b2014-05-29 21:33:13 -0700671 if (setVolumeRampVariables(valueInt,
672 target == RAMP_VOLUME ? mState.frameCount : 0,
673 track.volume[param - VOLUME0], track.prevVolume[param - VOLUME0],
674 track.volumeInc[param - VOLUME0])) {
675 ALOGV("setParameter(%s, VOLUME%d: %04x)",
676 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0, valueInt);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800677 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700678 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800679 break;
680 case AUXLEVEL:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800681 //ALOG_ASSERT(0 <= valueInt && valueInt <= MAX_GAIN_INT, "bad aux level %d", valueInt);
Andy Hung5866a3b2014-05-29 21:33:13 -0700682 if (setVolumeRampVariables(valueInt,
683 target == RAMP_VOLUME ? mState.frameCount : 0,
684 track.auxLevel, track.prevAuxLevel, track.auxInc)) {
685 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
686 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", valueInt);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800687 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700688 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800689 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700690 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800691 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700692 }
693 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700694
695 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800696 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700697 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700698}
699
700bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
701{
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700702 if (value != devSampleRate || resampler != NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700703 if (sampleRate != value) {
704 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800705 if (resampler == NULL) {
Glenn Kastenac602052012-10-01 14:04:31 -0700706 ALOGV("creating resampler from track %d Hz to device %d Hz", value, devSampleRate);
707 AudioResampler::src_quality quality;
708 // force lowest quality level resampler if use case isn't music or video
709 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
710 // quality level based on the initial ratio, but that could change later.
711 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
712 if (!((value == 44100 && devSampleRate == 48000) ||
713 (value == 48000 && devSampleRate == 44100))) {
Andy Hung9e0308c2014-01-30 14:32:31 -0800714 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700715 } else {
716 quality = AudioResampler::DEFAULT_QUALITY;
717 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700718 const int bits = mMixerInFormat == AUDIO_FORMAT_PCM_16_BIT ? 16 : /* FLOAT */ 32;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700719 resampler = AudioResampler::create(
Andy Hungef7c7fb2014-05-12 16:51:41 -0700720 bits,
Jean-Michel Triviacb86cc2012-04-16 12:43:57 -0700721 // the resampler sees the number of channels after the downmixer, if any
Glenn Kastenf551e992013-08-19 18:45:42 -0700722 (int) (downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount),
Glenn Kastenac602052012-10-01 14:04:31 -0700723 devSampleRate, quality);
Glenn Kasten52008f82012-03-18 09:34:41 -0700724 resampler->setLocalTimeFreq(sLocalTimeFreq);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700725 }
726 return true;
727 }
728 }
729 return false;
730}
731
Mathias Agopian65ab4712010-07-14 17:59:35 -0700732inline
733void AudioMixer::track_t::adjustVolumeRamp(bool aux)
734{
Glenn Kastenf9a27772012-01-06 07:47:26 -0800735 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700736 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
737 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
738 volumeInc[i] = 0;
739 prevVolume[i] = volume[i]<<16;
740 }
741 }
742 if (aux) {
743 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
744 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
745 auxInc = 0;
746 prevAuxLevel = auxLevel<<16;
747 }
748 }
749}
750
Glenn Kastenc59c0042012-02-02 14:06:11 -0800751size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800752{
753 name -= TRACK0;
754 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800755 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800756 }
757 return 0;
758}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700759
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800760void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700761{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800762 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800763 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700764
Andy Hung1d26ddf2014-05-29 15:53:09 -0700765 if (mState.tracks[name].mInputBufferProvider == bufferProvider) {
766 return; // don't reset any buffer providers if identical.
767 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700768 if (mState.tracks[name].mReformatBufferProvider != NULL) {
769 mState.tracks[name].mReformatBufferProvider->reset();
770 } else if (mState.tracks[name].downmixerBufferProvider != NULL) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700771 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700772
773 mState.tracks[name].mInputBufferProvider = bufferProvider;
774 reconfigureBufferProviders(&mState.tracks[name]);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700775}
776
777
John Grossman4ff14ba2012-02-08 16:37:41 -0800778void AudioMixer::process(int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700779{
John Grossman4ff14ba2012-02-08 16:37:41 -0800780 mState.hook(&mState, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700781}
782
783
John Grossman4ff14ba2012-02-08 16:37:41 -0800784void AudioMixer::process__validate(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700785{
Steve Block5ff1dd52012-01-05 23:22:43 +0000786 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700787 "in process__validate() but nothing's invalid");
788
789 uint32_t changed = state->needsChanged;
790 state->needsChanged = 0; // clear the validation flag
791
792 // recompute which tracks are enabled / disabled
793 uint32_t enabled = 0;
794 uint32_t disabled = 0;
795 while (changed) {
796 const int i = 31 - __builtin_clz(changed);
797 const uint32_t mask = 1<<i;
798 changed &= ~mask;
799 track_t& t = state->tracks[i];
800 (t.enabled ? enabled : disabled) |= mask;
801 }
802 state->enabledTracks &= ~disabled;
803 state->enabledTracks |= enabled;
804
805 // compute everything we need...
806 int countActiveTracks = 0;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800807 bool all16BitsStereoNoResample = true;
808 bool resampling = false;
809 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700810 uint32_t en = state->enabledTracks;
811 while (en) {
812 const int i = 31 - __builtin_clz(en);
813 en &= ~(1<<i);
814
815 countActiveTracks++;
816 track_t& t = state->tracks[i];
817 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700818 // FIXME can overflow (mask is only 3 bits)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700819 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700820 if (t.doesResample()) {
821 n |= NEEDS_RESAMPLE;
822 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700823 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700824 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700825 }
826
827 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800828 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700829 } else if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700830 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700831 }
832 t.needs = n;
833
Glenn Kastend6fadf02013-10-30 14:37:29 -0700834 if (n & NEEDS_MUTE) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700835 t.hook = track__nop;
836 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700837 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800838 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700839 }
Glenn Kastend6fadf02013-10-30 14:37:29 -0700840 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800841 all16BitsStereoNoResample = false;
842 resampling = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700843 t.hook = track__genericResample;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700844 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700845 "Track %d needs downmix + resample", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700846 } else {
847 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
848 t.hook = track__16BitsMono;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800849 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700850 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700851 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Mathias Agopian65ab4712010-07-14 17:59:35 -0700852 t.hook = track__16BitsStereo;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700853 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700854 "Track %d needs downmix", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700855 }
856 }
857 }
858 }
859
860 // select the processing hooks
861 state->hook = process__nop;
Glenn Kasten34fca342013-08-13 09:48:14 -0700862 if (countActiveTracks > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700863 if (resampling) {
864 if (!state->outputTemp) {
865 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
866 }
867 if (!state->resampleTemp) {
868 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
869 }
870 state->hook = process__genericResampling;
871 } else {
872 if (state->outputTemp) {
873 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800874 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700875 }
876 if (state->resampleTemp) {
877 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800878 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700879 }
880 state->hook = process__genericNoResampling;
881 if (all16BitsStereoNoResample && !volumeRamp) {
882 if (countActiveTracks == 1) {
883 state->hook = process__OneTrack16BitsStereoNoResampling;
884 }
885 }
886 }
887 }
888
Steve Block3856b092011-10-20 11:56:00 +0100889 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700890 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
891 countActiveTracks, state->enabledTracks,
892 all16BitsStereoNoResample, resampling, volumeRamp);
893
John Grossman4ff14ba2012-02-08 16:37:41 -0800894 state->hook(state, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700895
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800896 // Now that the volume ramp has been done, set optimal state and
897 // track hooks for subsequent mixer process
Glenn Kasten34fca342013-08-13 09:48:14 -0700898 if (countActiveTracks > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800899 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800900 uint32_t en = state->enabledTracks;
901 while (en) {
902 const int i = 31 - __builtin_clz(en);
903 en &= ~(1<<i);
904 track_t& t = state->tracks[i];
Glenn Kasten6e2ebe92013-08-13 09:14:51 -0700905 if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700906 t.needs |= NEEDS_MUTE;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800907 t.hook = track__nop;
908 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800909 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800910 }
911 }
912 if (allMuted) {
913 state->hook = process__nop;
914 } else if (all16BitsStereoNoResample) {
915 if (countActiveTracks == 1) {
916 state->hook = process__OneTrack16BitsStereoNoResampling;
917 }
918 }
919 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700920}
921
Mathias Agopian65ab4712010-07-14 17:59:35 -0700922
Glenn Kasten85ab62c2012-11-01 11:11:38 -0700923void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount,
924 int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700925{
926 t->resampler->setSampleRate(t->sampleRate);
927
928 // ramp gain - resample to temp buffer and scale/mix in 2nd step
929 if (aux != NULL) {
930 // always resample with unity gain when sending to auxiliary buffer to be able
931 // to apply send level after resampling
932 // TODO: modify each resampler to support aux channel?
933 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
934 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
935 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -0800936 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700937 volumeRampStereo(t, out, outFrameCount, temp, aux);
938 } else {
939 volumeStereo(t, out, outFrameCount, temp, aux);
940 }
941 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -0800942 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700943 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
944 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
945 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
946 volumeRampStereo(t, out, outFrameCount, temp, aux);
947 }
948
949 // constant gain
950 else {
951 t->resampler->setVolume(t->volume[0], t->volume[1]);
952 t->resampler->resample(out, outFrameCount, t->bufferProvider);
953 }
954 }
955}
956
Andy Hungee931ff2014-01-28 13:44:14 -0800957void AudioMixer::track__nop(track_t* t __unused, int32_t* out __unused,
958 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700959{
960}
961
Glenn Kasten85ab62c2012-11-01 11:11:38 -0700962void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
963 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700964{
965 int32_t vl = t->prevVolume[0];
966 int32_t vr = t->prevVolume[1];
967 const int32_t vlInc = t->volumeInc[0];
968 const int32_t vrInc = t->volumeInc[1];
969
Steve Blockb8a80522011-12-20 16:23:08 +0000970 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700971 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
972 // (vl + vlInc*frameCount)/65536.0f, frameCount);
973
974 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -0800975 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700976 int32_t va = t->prevAuxLevel;
977 const int32_t vaInc = t->auxInc;
978 int32_t l;
979 int32_t r;
980
981 do {
982 l = (*temp++ >> 12);
983 r = (*temp++ >> 12);
984 *out++ += (vl >> 16) * l;
985 *out++ += (vr >> 16) * r;
986 *aux++ += (va >> 17) * (l + r);
987 vl += vlInc;
988 vr += vrInc;
989 va += vaInc;
990 } while (--frameCount);
991 t->prevAuxLevel = va;
992 } else {
993 do {
994 *out++ += (vl >> 16) * (*temp++ >> 12);
995 *out++ += (vr >> 16) * (*temp++ >> 12);
996 vl += vlInc;
997 vr += vrInc;
998 } while (--frameCount);
999 }
1000 t->prevVolume[0] = vl;
1001 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -08001002 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001003}
1004
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001005void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1006 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001007{
1008 const int16_t vl = t->volume[0];
1009 const int16_t vr = t->volume[1];
1010
Glenn Kastenf6b16782011-12-15 09:51:17 -08001011 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -08001012 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001013 do {
1014 int16_t l = (int16_t)(*temp++ >> 12);
1015 int16_t r = (int16_t)(*temp++ >> 12);
1016 out[0] = mulAdd(l, vl, out[0]);
1017 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
1018 out[1] = mulAdd(r, vr, out[1]);
1019 out += 2;
1020 aux[0] = mulAdd(a, va, aux[0]);
1021 aux++;
1022 } while (--frameCount);
1023 } else {
1024 do {
1025 int16_t l = (int16_t)(*temp++ >> 12);
1026 int16_t r = (int16_t)(*temp++ >> 12);
1027 out[0] = mulAdd(l, vl, out[0]);
1028 out[1] = mulAdd(r, vr, out[1]);
1029 out += 2;
1030 } while (--frameCount);
1031 }
1032}
1033
Andy Hungee931ff2014-01-28 13:44:14 -08001034void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount,
1035 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001036{
Glenn Kasten54c3b662012-01-06 07:46:30 -08001037 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001038
Glenn Kastenf6b16782011-12-15 09:51:17 -08001039 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001040 int32_t l;
1041 int32_t r;
1042 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001043 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001044 int32_t vl = t->prevVolume[0];
1045 int32_t vr = t->prevVolume[1];
1046 int32_t va = t->prevAuxLevel;
1047 const int32_t vlInc = t->volumeInc[0];
1048 const int32_t vrInc = t->volumeInc[1];
1049 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +00001050 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001051 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1052 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1053
1054 do {
1055 l = (int32_t)*in++;
1056 r = (int32_t)*in++;
1057 *out++ += (vl >> 16) * l;
1058 *out++ += (vr >> 16) * r;
1059 *aux++ += (va >> 17) * (l + r);
1060 vl += vlInc;
1061 vr += vrInc;
1062 va += vaInc;
1063 } while (--frameCount);
1064
1065 t->prevVolume[0] = vl;
1066 t->prevVolume[1] = vr;
1067 t->prevAuxLevel = va;
1068 t->adjustVolumeRamp(true);
1069 }
1070
1071 // constant gain
1072 else {
1073 const uint32_t vrl = t->volumeRL;
1074 const int16_t va = (int16_t)t->auxLevel;
1075 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001076 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001077 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
1078 in += 2;
1079 out[0] = mulAddRL(1, rl, vrl, out[0]);
1080 out[1] = mulAddRL(0, rl, vrl, out[1]);
1081 out += 2;
1082 aux[0] = mulAdd(a, va, aux[0]);
1083 aux++;
1084 } while (--frameCount);
1085 }
1086 } else {
1087 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001088 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001089 int32_t vl = t->prevVolume[0];
1090 int32_t vr = t->prevVolume[1];
1091 const int32_t vlInc = t->volumeInc[0];
1092 const int32_t vrInc = t->volumeInc[1];
1093
Steve Blockb8a80522011-12-20 16:23:08 +00001094 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001095 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1096 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1097
1098 do {
1099 *out++ += (vl >> 16) * (int32_t) *in++;
1100 *out++ += (vr >> 16) * (int32_t) *in++;
1101 vl += vlInc;
1102 vr += vrInc;
1103 } while (--frameCount);
1104
1105 t->prevVolume[0] = vl;
1106 t->prevVolume[1] = vr;
1107 t->adjustVolumeRamp(false);
1108 }
1109
1110 // constant gain
1111 else {
1112 const uint32_t vrl = t->volumeRL;
1113 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001114 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001115 in += 2;
1116 out[0] = mulAddRL(1, rl, vrl, out[0]);
1117 out[1] = mulAddRL(0, rl, vrl, out[1]);
1118 out += 2;
1119 } while (--frameCount);
1120 }
1121 }
1122 t->in = in;
1123}
1124
Andy Hungee931ff2014-01-28 13:44:14 -08001125void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount,
1126 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001127{
Glenn Kasten54c3b662012-01-06 07:46:30 -08001128 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001129
Glenn Kastenf6b16782011-12-15 09:51:17 -08001130 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001131 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001132 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001133 int32_t vl = t->prevVolume[0];
1134 int32_t vr = t->prevVolume[1];
1135 int32_t va = t->prevAuxLevel;
1136 const int32_t vlInc = t->volumeInc[0];
1137 const int32_t vrInc = t->volumeInc[1];
1138 const int32_t vaInc = t->auxInc;
1139
Steve Blockb8a80522011-12-20 16:23:08 +00001140 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001141 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1142 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1143
1144 do {
1145 int32_t l = *in++;
1146 *out++ += (vl >> 16) * l;
1147 *out++ += (vr >> 16) * l;
1148 *aux++ += (va >> 16) * l;
1149 vl += vlInc;
1150 vr += vrInc;
1151 va += vaInc;
1152 } while (--frameCount);
1153
1154 t->prevVolume[0] = vl;
1155 t->prevVolume[1] = vr;
1156 t->prevAuxLevel = va;
1157 t->adjustVolumeRamp(true);
1158 }
1159 // constant gain
1160 else {
1161 const int16_t vl = t->volume[0];
1162 const int16_t vr = t->volume[1];
1163 const int16_t va = (int16_t)t->auxLevel;
1164 do {
1165 int16_t l = *in++;
1166 out[0] = mulAdd(l, vl, out[0]);
1167 out[1] = mulAdd(l, vr, out[1]);
1168 out += 2;
1169 aux[0] = mulAdd(l, va, aux[0]);
1170 aux++;
1171 } while (--frameCount);
1172 }
1173 } else {
1174 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001175 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001176 int32_t vl = t->prevVolume[0];
1177 int32_t vr = t->prevVolume[1];
1178 const int32_t vlInc = t->volumeInc[0];
1179 const int32_t vrInc = t->volumeInc[1];
1180
Steve Blockb8a80522011-12-20 16:23:08 +00001181 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001182 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1183 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1184
1185 do {
1186 int32_t l = *in++;
1187 *out++ += (vl >> 16) * l;
1188 *out++ += (vr >> 16) * l;
1189 vl += vlInc;
1190 vr += vrInc;
1191 } while (--frameCount);
1192
1193 t->prevVolume[0] = vl;
1194 t->prevVolume[1] = vr;
1195 t->adjustVolumeRamp(false);
1196 }
1197 // constant gain
1198 else {
1199 const int16_t vl = t->volume[0];
1200 const int16_t vr = t->volume[1];
1201 do {
1202 int16_t l = *in++;
1203 out[0] = mulAdd(l, vl, out[0]);
1204 out[1] = mulAdd(l, vr, out[1]);
1205 out += 2;
1206 } while (--frameCount);
1207 }
1208 }
1209 t->in = in;
1210}
1211
Mathias Agopian65ab4712010-07-14 17:59:35 -07001212// no-op case
John Grossman4ff14ba2012-02-08 16:37:41 -08001213void AudioMixer::process__nop(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001214{
1215 uint32_t e0 = state->enabledTracks;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001216 size_t sampleCount = state->frameCount * MAX_NUM_CHANNELS;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001217 while (e0) {
1218 // process by group of tracks with same output buffer to
1219 // avoid multiple memset() on same buffer
1220 uint32_t e1 = e0, e2 = e0;
1221 int i = 31 - __builtin_clz(e1);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001222 {
1223 track_t& t1 = state->tracks[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001224 e2 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001225 while (e2) {
1226 i = 31 - __builtin_clz(e2);
1227 e2 &= ~(1<<i);
1228 track_t& t2 = state->tracks[i];
1229 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1230 e1 &= ~(1<<i);
1231 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001232 }
Glenn Kastenfc900c92013-02-18 12:47:49 -08001233 e0 &= ~(e1);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001234
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001235 memset(t1.mainBuffer, 0, sampleCount
Andy Hung78820702014-02-28 16:23:02 -08001236 * audio_bytes_per_sample(t1.mMixerFormat));
Glenn Kastenfc900c92013-02-18 12:47:49 -08001237 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001238
1239 while (e1) {
1240 i = 31 - __builtin_clz(e1);
1241 e1 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001242 {
1243 track_t& t3 = state->tracks[i];
1244 size_t outFrames = state->frameCount;
1245 while (outFrames) {
1246 t3.buffer.frameCount = outFrames;
1247 int64_t outputPTS = calculateOutputPTS(
1248 t3, pts, state->frameCount - outFrames);
1249 t3.bufferProvider->getNextBuffer(&t3.buffer, outputPTS);
1250 if (t3.buffer.raw == NULL) break;
1251 outFrames -= t3.buffer.frameCount;
1252 t3.bufferProvider->releaseBuffer(&t3.buffer);
1253 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001254 }
1255 }
1256 }
1257}
1258
1259// generic code without resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001260void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001261{
1262 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1263
1264 // acquire each track's buffer
1265 uint32_t enabledTracks = state->enabledTracks;
1266 uint32_t e0 = enabledTracks;
1267 while (e0) {
1268 const int i = 31 - __builtin_clz(e0);
1269 e0 &= ~(1<<i);
1270 track_t& t = state->tracks[i];
1271 t.buffer.frameCount = state->frameCount;
John Grossman4ff14ba2012-02-08 16:37:41 -08001272 t.bufferProvider->getNextBuffer(&t.buffer, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001273 t.frameCount = t.buffer.frameCount;
1274 t.in = t.buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001275 }
1276
1277 e0 = enabledTracks;
1278 while (e0) {
1279 // process by group of tracks with same output buffer to
1280 // optimize cache use
1281 uint32_t e1 = e0, e2 = e0;
1282 int j = 31 - __builtin_clz(e1);
1283 track_t& t1 = state->tracks[j];
1284 e2 &= ~(1<<j);
1285 while (e2) {
1286 j = 31 - __builtin_clz(e2);
1287 e2 &= ~(1<<j);
1288 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001289 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001290 e1 &= ~(1<<j);
1291 }
1292 }
1293 e0 &= ~(e1);
1294 // this assumes output 16 bits stereo, no resampling
1295 int32_t *out = t1.mainBuffer;
1296 size_t numFrames = 0;
1297 do {
1298 memset(outTemp, 0, sizeof(outTemp));
1299 e2 = e1;
1300 while (e2) {
1301 const int i = 31 - __builtin_clz(e2);
1302 e2 &= ~(1<<i);
1303 track_t& t = state->tracks[i];
1304 size_t outFrames = BLOCKSIZE;
1305 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001306 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001307 aux = t.auxBuffer + numFrames;
1308 }
1309 while (outFrames) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301310 // t.in == NULL can happen if the track was flushed just after having
1311 // been enabled for mixing.
1312 if (t.in == NULL) {
1313 enabledTracks &= ~(1<<i);
1314 e1 &= ~(1<<i);
1315 break;
1316 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001317 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001318 if (inFrames > 0) {
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001319 t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames,
1320 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001321 t.frameCount -= inFrames;
1322 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001323 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001324 aux += inFrames;
1325 }
1326 }
1327 if (t.frameCount == 0 && outFrames) {
1328 t.bufferProvider->releaseBuffer(&t.buffer);
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001329 t.buffer.frameCount = (state->frameCount - numFrames) -
1330 (BLOCKSIZE - outFrames);
John Grossman4ff14ba2012-02-08 16:37:41 -08001331 int64_t outputPTS = calculateOutputPTS(
1332 t, pts, numFrames + (BLOCKSIZE - outFrames));
1333 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001334 t.in = t.buffer.raw;
1335 if (t.in == NULL) {
1336 enabledTracks &= ~(1<<i);
1337 e1 &= ~(1<<i);
1338 break;
1339 }
1340 t.frameCount = t.buffer.frameCount;
1341 }
1342 }
1343 }
Andy Hung78820702014-02-28 16:23:02 -08001344 switch (t1.mMixerFormat) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001345 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung84a0c6e2014-04-02 11:24:53 -07001346 memcpy_to_float_from_q4_27(reinterpret_cast<float *>(out), outTemp, BLOCKSIZE * 2);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001347 out += BLOCKSIZE * 2; // output is 2 floats/frame.
1348 break;
1349 case AUDIO_FORMAT_PCM_16_BIT:
1350 ditherAndClamp(out, outTemp, BLOCKSIZE);
1351 out += BLOCKSIZE; // output is 1 int32_t (2 int16_t samples)/frame
1352 break;
1353 default:
Andy Hung78820702014-02-28 16:23:02 -08001354 LOG_ALWAYS_FATAL("bad mixer format: %d", t1.mMixerFormat);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001355 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001356 numFrames += BLOCKSIZE;
1357 } while (numFrames < state->frameCount);
1358 }
1359
1360 // release each track's buffer
1361 e0 = enabledTracks;
1362 while (e0) {
1363 const int i = 31 - __builtin_clz(e0);
1364 e0 &= ~(1<<i);
1365 track_t& t = state->tracks[i];
1366 t.bufferProvider->releaseBuffer(&t.buffer);
1367 }
1368}
1369
1370
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001371// generic code with resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001372void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001373{
Glenn Kasten54c3b662012-01-06 07:46:30 -08001374 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -07001375 int32_t* const outTemp = state->outputTemp;
1376 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001377
1378 size_t numFrames = state->frameCount;
1379
1380 uint32_t e0 = state->enabledTracks;
1381 while (e0) {
1382 // process by group of tracks with same output buffer
1383 // to optimize cache use
1384 uint32_t e1 = e0, e2 = e0;
1385 int j = 31 - __builtin_clz(e1);
1386 track_t& t1 = state->tracks[j];
1387 e2 &= ~(1<<j);
1388 while (e2) {
1389 j = 31 - __builtin_clz(e2);
1390 e2 &= ~(1<<j);
1391 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001392 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001393 e1 &= ~(1<<j);
1394 }
1395 }
1396 e0 &= ~(e1);
1397 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +01001398 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001399 while (e1) {
1400 const int i = 31 - __builtin_clz(e1);
1401 e1 &= ~(1<<i);
1402 track_t& t = state->tracks[i];
1403 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001404 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001405 aux = t.auxBuffer;
1406 }
1407
1408 // this is a little goofy, on the resampling case we don't
1409 // acquire/release the buffers because it's done by
1410 // the resampler.
Glenn Kastend6fadf02013-10-30 14:37:29 -07001411 if (t.needs & NEEDS_RESAMPLE) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001412 t.resampler->setPTS(pts);
Glenn Kastena1117922012-01-26 10:53:32 -08001413 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001414 } else {
1415
1416 size_t outFrames = 0;
1417
1418 while (outFrames < numFrames) {
1419 t.buffer.frameCount = numFrames - outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001420 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
1421 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001422 t.in = t.buffer.raw;
1423 // t.in == NULL can happen if the track was flushed just after having
1424 // been enabled for mixing.
1425 if (t.in == NULL) break;
1426
Glenn Kastenf6b16782011-12-15 09:51:17 -08001427 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001428 aux += outFrames;
1429 }
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001430 t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount,
1431 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001432 outFrames += t.buffer.frameCount;
1433 t.bufferProvider->releaseBuffer(&t.buffer);
1434 }
1435 }
1436 }
Andy Hung78820702014-02-28 16:23:02 -08001437 switch (t1.mMixerFormat) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001438 case AUDIO_FORMAT_PCM_FLOAT:
Andy Hung84a0c6e2014-04-02 11:24:53 -07001439 memcpy_to_float_from_q4_27(reinterpret_cast<float*>(out), outTemp, numFrames*2);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001440 break;
1441 case AUDIO_FORMAT_PCM_16_BIT:
1442 ditherAndClamp(out, outTemp, numFrames);
1443 break;
1444 default:
Andy Hung78820702014-02-28 16:23:02 -08001445 LOG_ALWAYS_FATAL("bad mixer format: %d", t1.mMixerFormat);
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001446 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001447 }
1448}
1449
1450// one track, 16 bits stereo without resampling is the most common case
John Grossman4ff14ba2012-02-08 16:37:41 -08001451void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
1452 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001453{
Glenn Kasten99e53b82012-01-19 08:59:58 -08001454 // This method is only called when state->enabledTracks has exactly
1455 // one bit set. The asserts below would verify this, but are commented out
1456 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001457 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001458 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001459 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001460 const track_t& t = state->tracks[i];
1461
1462 AudioBufferProvider::Buffer& b(t.buffer);
1463
1464 int32_t* out = t.mainBuffer;
Andy Hungf8a106a2014-05-29 18:52:38 -07001465 float *fout = reinterpret_cast<float*>(out);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001466 size_t numFrames = state->frameCount;
1467
1468 const int16_t vl = t.volume[0];
1469 const int16_t vr = t.volume[1];
1470 const uint32_t vrl = t.volumeRL;
1471 while (numFrames) {
1472 b.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001473 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
1474 t.bufferProvider->getNextBuffer(&b, outputPTS);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001475 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001476
1477 // in == NULL can happen if the track was flushed just after having
1478 // been enabled for mixing.
Andy Hungf8a106a2014-05-29 18:52:38 -07001479 if (in == NULL || (((uintptr_t)in) & 3)) {
1480 memset(out, 0, numFrames
1481 * MAX_NUM_CHANNELS * audio_bytes_per_sample(t.mMixerFormat));
1482 ALOGE_IF((((uintptr_t)in) & 3), "process stereo track: input buffer alignment pb: "
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001483 "buffer %p track %d, channels %d, needs %08x",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001484 in, i, t.channelCount, t.needs);
1485 return;
1486 }
1487 size_t outFrames = b.frameCount;
1488
Andy Hung78820702014-02-28 16:23:02 -08001489 switch (t.mMixerFormat) {
Andy Hungf8a106a2014-05-29 18:52:38 -07001490 case AUDIO_FORMAT_PCM_FLOAT:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001491 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001492 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001493 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001494 int32_t l = mulRL(1, rl, vrl);
1495 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001496 *fout++ = float_from_q4_27(l);
1497 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001498 // Note: In case of later int16_t sink output,
1499 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001500 } while (--outFrames);
Andy Hungf8a106a2014-05-29 18:52:38 -07001501 break;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001502 case AUDIO_FORMAT_PCM_16_BIT:
1503 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
1504 // volume is boosted, so we might need to clamp even though
1505 // we process only one track.
1506 do {
1507 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1508 in += 2;
1509 int32_t l = mulRL(1, rl, vrl) >> 12;
1510 int32_t r = mulRL(0, rl, vrl) >> 12;
1511 // clamping...
1512 l = clamp16(l);
1513 r = clamp16(r);
1514 *out++ = (r<<16) | (l & 0xFFFF);
1515 } while (--outFrames);
1516 } else {
1517 do {
1518 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1519 in += 2;
1520 int32_t l = mulRL(1, rl, vrl) >> 12;
1521 int32_t r = mulRL(0, rl, vrl) >> 12;
1522 *out++ = (r<<16) | (l & 0xFFFF);
1523 } while (--outFrames);
1524 }
1525 break;
1526 default:
Andy Hung78820702014-02-28 16:23:02 -08001527 LOG_ALWAYS_FATAL("bad mixer format: %d", t.mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001528 }
1529 numFrames -= b.frameCount;
1530 t.bufferProvider->releaseBuffer(&b);
1531 }
1532}
1533
Glenn Kasten81a028f2011-12-15 09:53:12 -08001534#if 0
Mathias Agopian65ab4712010-07-14 17:59:35 -07001535// 2 tracks is also a common case
1536// NEVER used in current implementation of process__validate()
1537// only use if the 2 tracks have the same output buffer
John Grossman4ff14ba2012-02-08 16:37:41 -08001538void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state,
1539 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001540{
1541 int i;
1542 uint32_t en = state->enabledTracks;
1543
1544 i = 31 - __builtin_clz(en);
1545 const track_t& t0 = state->tracks[i];
1546 AudioBufferProvider::Buffer& b0(t0.buffer);
1547
1548 en &= ~(1<<i);
1549 i = 31 - __builtin_clz(en);
1550 const track_t& t1 = state->tracks[i];
1551 AudioBufferProvider::Buffer& b1(t1.buffer);
1552
Glenn Kasten54c3b662012-01-06 07:46:30 -08001553 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001554 const int16_t vl0 = t0.volume[0];
1555 const int16_t vr0 = t0.volume[1];
1556 size_t frameCount0 = 0;
1557
Glenn Kasten54c3b662012-01-06 07:46:30 -08001558 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001559 const int16_t vl1 = t1.volume[0];
1560 const int16_t vr1 = t1.volume[1];
1561 size_t frameCount1 = 0;
1562
1563 //FIXME: only works if two tracks use same buffer
1564 int32_t* out = t0.mainBuffer;
1565 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001566 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001567
1568
1569 while (numFrames) {
1570
1571 if (frameCount0 == 0) {
1572 b0.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001573 int64_t outputPTS = calculateOutputPTS(t0, pts,
1574 out - t0.mainBuffer);
1575 t0.bufferProvider->getNextBuffer(&b0, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001576 if (b0.i16 == NULL) {
1577 if (buff == NULL) {
1578 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1579 }
1580 in0 = buff;
1581 b0.frameCount = numFrames;
1582 } else {
1583 in0 = b0.i16;
1584 }
1585 frameCount0 = b0.frameCount;
1586 }
1587 if (frameCount1 == 0) {
1588 b1.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001589 int64_t outputPTS = calculateOutputPTS(t1, pts,
1590 out - t0.mainBuffer);
1591 t1.bufferProvider->getNextBuffer(&b1, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001592 if (b1.i16 == NULL) {
1593 if (buff == NULL) {
1594 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1595 }
1596 in1 = buff;
1597 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001598 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001599 in1 = b1.i16;
1600 }
1601 frameCount1 = b1.frameCount;
1602 }
1603
1604 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1605
1606 numFrames -= outFrames;
1607 frameCount0 -= outFrames;
1608 frameCount1 -= outFrames;
1609
1610 do {
1611 int32_t l0 = *in0++;
1612 int32_t r0 = *in0++;
1613 l0 = mul(l0, vl0);
1614 r0 = mul(r0, vr0);
1615 int32_t l = *in1++;
1616 int32_t r = *in1++;
1617 l = mulAdd(l, vl1, l0) >> 12;
1618 r = mulAdd(r, vr1, r0) >> 12;
1619 // clamping...
1620 l = clamp16(l);
1621 r = clamp16(r);
1622 *out++ = (r<<16) | (l & 0xFFFF);
1623 } while (--outFrames);
1624
1625 if (frameCount0 == 0) {
1626 t0.bufferProvider->releaseBuffer(&b0);
1627 }
1628 if (frameCount1 == 0) {
1629 t1.bufferProvider->releaseBuffer(&b1);
1630 }
1631 }
1632
Glenn Kastene9dd0172012-01-27 18:08:45 -08001633 delete [] buff;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001634}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001635#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001636
John Grossman4ff14ba2012-02-08 16:37:41 -08001637int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1638 int outputFrameIndex)
1639{
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001640 if (AudioBufferProvider::kInvalidPTS == basePTS) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001641 return AudioBufferProvider::kInvalidPTS;
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001642 }
John Grossman4ff14ba2012-02-08 16:37:41 -08001643
Glenn Kasten52008f82012-03-18 09:34:41 -07001644 return basePTS + ((outputFrameIndex * sLocalTimeFreq) / t.sampleRate);
1645}
1646
1647/*static*/ uint64_t AudioMixer::sLocalTimeFreq;
1648/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1649
1650/*static*/ void AudioMixer::sInitRoutine()
1651{
1652 LocalClock lc;
1653 sLocalTimeFreq = lc.getLocalFreq();
Glenn Kasten49c34ac2013-10-30 14:37:01 -07001654
1655 // find multichannel downmix effect if we have to play multichannel content
1656 uint32_t numEffects = 0;
1657 int ret = EffectQueryNumberEffects(&numEffects);
1658 if (ret != 0) {
1659 ALOGE("AudioMixer() error %d querying number of effects", ret);
1660 return;
1661 }
1662 ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects);
1663
1664 for (uint32_t i = 0 ; i < numEffects ; i++) {
1665 if (EffectQueryEffect(i, &sDwnmFxDesc) == 0) {
1666 ALOGV("effect %d is called %s", i, sDwnmFxDesc.name);
1667 if (memcmp(&sDwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) {
1668 ALOGI("found effect \"%s\" from %s",
1669 sDwnmFxDesc.name, sDwnmFxDesc.implementor);
1670 sIsMultichannelCapable = true;
1671 break;
1672 }
1673 }
1674 }
1675 ALOGW_IF(!sIsMultichannelCapable, "unable to find downmix effect");
John Grossman4ff14ba2012-02-08 16:37:41 -08001676}
1677
Mathias Agopian65ab4712010-07-14 17:59:35 -07001678// ----------------------------------------------------------------------------
1679}; // namespace android