blob: e57cb8aa51001a30df9fad24a4f83e5a0c986a9b [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>
Andy Hung5e58b0a2014-06-23 19:07:29 -070025#include <math.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070026#include <sys/types.h>
27
28#include <utils/Errors.h>
29#include <utils/Log.h>
30
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070031#include <cutils/bitops.h>
Glenn Kastenf6b16782011-12-15 09:51:17 -080032#include <cutils/compiler.h>
Glenn Kasten5798d4e2012-03-08 12:18:35 -080033#include <utils/Debug.h>
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070034
35#include <system/audio.h>
36
Glenn Kasten3b21c502011-12-15 09:52:39 -080037#include <audio_utils/primitives.h>
Andy Hungef7c7fb2014-05-12 16:51:41 -070038#include <audio_utils/format.h>
John Grossman4ff14ba2012-02-08 16:37:41 -080039#include <common_time/local_clock.h>
40#include <common_time/cc_helper.h>
Glenn Kasten3b21c502011-12-15 09:52:39 -080041
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070042#include <media/EffectsFactoryApi.h>
43
Andy Hung296b7412014-06-17 15:25:47 -070044#include "AudioMixerOps.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070045#include "AudioMixer.h"
46
Andy Hung296b7412014-06-17 15:25:47 -070047// Use the FCC_2 macro for code assuming Fixed Channel Count of 2 and
48// whose stereo assumption may need to be revisited later.
49#ifndef FCC_2
50#define FCC_2 2
51#endif
52
53/* VERY_VERY_VERBOSE_LOGGING will show exactly which process hook and track hook is
54 * being used. This is a considerable amount of log spam, so don't enable unless you
55 * are verifying the hook based code.
56 */
57//#define VERY_VERY_VERBOSE_LOGGING
58#ifdef VERY_VERY_VERBOSE_LOGGING
59#define ALOGVV ALOGV
60//define ALOGVV printf // for test-mixer.cpp
61#else
62#define ALOGVV(a...) do { } while (0)
63#endif
64
65// Set kUseNewMixer to true to use the new mixer engine. Otherwise the
66// original code will be used. This is false for now.
67static const bool kUseNewMixer = false;
68
69// Set kUseFloat to true to allow floating input into the mixer engine.
70// If kUseNewMixer is false, this is ignored or may be overridden internally
71// because of downmix/upmix support.
72static const bool kUseFloat = true;
73
Mathias Agopian65ab4712010-07-14 17:59:35 -070074namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070075
76// ----------------------------------------------------------------------------
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070077AudioMixer::DownmixerBufferProvider::DownmixerBufferProvider() : AudioBufferProvider(),
78 mTrackBufferProvider(NULL), mDownmixHandle(NULL)
79{
80}
81
82AudioMixer::DownmixerBufferProvider::~DownmixerBufferProvider()
83{
84 ALOGV("AudioMixer deleting DownmixerBufferProvider (%p)", this);
85 EffectRelease(mDownmixHandle);
86}
87
88status_t AudioMixer::DownmixerBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer,
89 int64_t pts) {
90 //ALOGV("DownmixerBufferProvider::getNextBuffer()");
Glenn Kasten8f325372013-10-30 14:36:47 -070091 if (mTrackBufferProvider != NULL) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -070092 status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts);
93 if (res == OK) {
94 mDownmixConfig.inputCfg.buffer.frameCount = pBuffer->frameCount;
95 mDownmixConfig.inputCfg.buffer.raw = pBuffer->raw;
96 mDownmixConfig.outputCfg.buffer.frameCount = pBuffer->frameCount;
97 mDownmixConfig.outputCfg.buffer.raw = mDownmixConfig.inputCfg.buffer.raw;
98 // in-place so overwrite the buffer contents, has been set in prepareTrackForDownmix()
99 //mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
100
101 res = (*mDownmixHandle)->process(mDownmixHandle,
102 &mDownmixConfig.inputCfg.buffer, &mDownmixConfig.outputCfg.buffer);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700103 //ALOGV("getNextBuffer is downmixing");
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700104 }
105 return res;
106 } else {
107 ALOGE("DownmixerBufferProvider::getNextBuffer() error: NULL track buffer provider");
108 return NO_INIT;
109 }
110}
111
112void AudioMixer::DownmixerBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700113 //ALOGV("DownmixerBufferProvider::releaseBuffer()");
Glenn Kasten8f325372013-10-30 14:36:47 -0700114 if (mTrackBufferProvider != NULL) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700115 mTrackBufferProvider->releaseBuffer(pBuffer);
116 } else {
117 ALOGE("DownmixerBufferProvider::releaseBuffer() error: NULL track buffer provider");
118 }
119}
120
Andy Hungef7c7fb2014-05-12 16:51:41 -0700121template <typename T>
122T min(const T& a, const T& b)
123{
124 return a < b ? a : b;
125}
126
127AudioMixer::ReformatBufferProvider::ReformatBufferProvider(int32_t channels,
128 audio_format_t inputFormat, audio_format_t outputFormat) :
129 mTrackBufferProvider(NULL),
130 mChannels(channels),
131 mInputFormat(inputFormat),
132 mOutputFormat(outputFormat),
133 mInputFrameSize(channels * audio_bytes_per_sample(inputFormat)),
134 mOutputFrameSize(channels * audio_bytes_per_sample(outputFormat)),
135 mOutputData(NULL),
136 mOutputCount(0),
137 mConsumed(0)
138{
139 ALOGV("ReformatBufferProvider(%p)(%d, %#x, %#x)", this, channels, inputFormat, outputFormat);
140 if (requiresInternalBuffers()) {
141 mOutputCount = 256;
142 (void)posix_memalign(&mOutputData, 32, mOutputCount * mOutputFrameSize);
143 }
144 mBuffer.frameCount = 0;
145}
146
147AudioMixer::ReformatBufferProvider::~ReformatBufferProvider()
148{
149 ALOGV("~ReformatBufferProvider(%p)", this);
150 if (mBuffer.frameCount != 0) {
151 mTrackBufferProvider->releaseBuffer(&mBuffer);
152 }
153 free(mOutputData);
154}
155
156status_t AudioMixer::ReformatBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer,
157 int64_t pts) {
158 //ALOGV("ReformatBufferProvider(%p)::getNextBuffer(%p (%zu), %lld)",
159 // this, pBuffer, pBuffer->frameCount, pts);
160 if (!requiresInternalBuffers()) {
161 status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts);
162 if (res == OK) {
163 memcpy_by_audio_format(pBuffer->raw, mOutputFormat, pBuffer->raw, mInputFormat,
164 pBuffer->frameCount * mChannels);
165 }
166 return res;
167 }
168 if (mBuffer.frameCount == 0) {
169 mBuffer.frameCount = pBuffer->frameCount;
170 status_t res = mTrackBufferProvider->getNextBuffer(&mBuffer, pts);
171 // TODO: Track down a bug in the upstream provider
172 // LOG_ALWAYS_FATAL_IF(res == OK && mBuffer.frameCount == 0,
173 // "ReformatBufferProvider::getNextBuffer():"
174 // " Invalid zero framecount returned from getNextBuffer()");
175 if (res != OK || mBuffer.frameCount == 0) {
176 pBuffer->raw = NULL;
177 pBuffer->frameCount = 0;
178 return res;
179 }
180 }
181 ALOG_ASSERT(mConsumed < mBuffer.frameCount);
182 size_t count = min(mOutputCount, mBuffer.frameCount - mConsumed);
183 count = min(count, pBuffer->frameCount);
184 pBuffer->raw = mOutputData;
185 pBuffer->frameCount = count;
186 //ALOGV("reformatting %d frames from %#x to %#x, %d chan",
187 // pBuffer->frameCount, mInputFormat, mOutputFormat, mChannels);
188 memcpy_by_audio_format(pBuffer->raw, mOutputFormat,
189 (uint8_t*)mBuffer.raw + mConsumed * mInputFrameSize, mInputFormat,
190 pBuffer->frameCount * mChannels);
191 return OK;
192}
193
194void AudioMixer::ReformatBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
195 //ALOGV("ReformatBufferProvider(%p)::releaseBuffer(%p(%zu))",
196 // this, pBuffer, pBuffer->frameCount);
197 if (!requiresInternalBuffers()) {
198 mTrackBufferProvider->releaseBuffer(pBuffer);
199 return;
200 }
201 // LOG_ALWAYS_FATAL_IF(pBuffer->frameCount == 0, "Invalid framecount");
202 mConsumed += pBuffer->frameCount; // TODO: update for efficiency to reuse existing content
203 if (mConsumed != 0 && mConsumed >= mBuffer.frameCount) {
204 mConsumed = 0;
205 mTrackBufferProvider->releaseBuffer(&mBuffer);
206 // ALOG_ASSERT(mBuffer.frameCount == 0);
207 }
208 pBuffer->raw = NULL;
209 pBuffer->frameCount = 0;
210}
211
212void AudioMixer::ReformatBufferProvider::reset() {
213 if (mBuffer.frameCount != 0) {
214 mTrackBufferProvider->releaseBuffer(&mBuffer);
215 }
216 mConsumed = 0;
217}
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700218
219// ----------------------------------------------------------------------------
Glenn Kasten49c34ac2013-10-30 14:37:01 -0700220bool AudioMixer::sIsMultichannelCapable = false;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700221
Glenn Kasten49c34ac2013-10-30 14:37:01 -0700222effect_descriptor_t AudioMixer::sDwnmFxDesc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700223
Paul Lind3c0a0e82012-08-01 18:49:49 -0700224// Ensure mConfiguredNames bitmask is initialized properly on all architectures.
225// The value of 1 << x is undefined in C when x >= 32.
226
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700227AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks)
Paul Lind3c0a0e82012-08-01 18:49:49 -0700228 : mTrackNames(0), mConfiguredNames((maxNumTracks >= 32 ? 0 : 1 << maxNumTracks) - 1),
Glenn Kasten7f5d3352013-02-15 23:55:04 +0000229 mSampleRate(sampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700230{
Glenn Kasten788040c2011-05-05 08:19:00 -0700231 // AudioMixer is not yet capable of multi-channel beyond stereo
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800232 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(2 == MAX_NUM_CHANNELS);
Jean-Michel Triviacb86cc2012-04-16 12:43:57 -0700233
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700234 ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u",
235 maxNumTracks, MAX_NUM_TRACKS);
236
Glenn Kasten599fabc2012-03-08 12:33:37 -0800237 // AudioMixer is not yet capable of more than 32 active track inputs
238 ALOG_ASSERT(32 >= MAX_NUM_TRACKS, "bad MAX_NUM_TRACKS %d", MAX_NUM_TRACKS);
239
240 // AudioMixer is not yet capable of multi-channel output beyond stereo
241 ALOG_ASSERT(2 == MAX_NUM_CHANNELS, "bad MAX_NUM_CHANNELS %d", MAX_NUM_CHANNELS);
242
Glenn Kasten52008f82012-03-18 09:34:41 -0700243 pthread_once(&sOnceControl, &sInitRoutine);
244
Mathias Agopian65ab4712010-07-14 17:59:35 -0700245 mState.enabledTracks= 0;
246 mState.needsChanged = 0;
247 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800248 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -0800249 mState.outputTemp = NULL;
250 mState.resampleTemp = NULL;
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800251 mState.mLog = &mDummyLog;
Glenn Kasten84afa3b2012-01-25 15:28:08 -0800252 // mState.reserved
Glenn Kasten17a736c2012-02-14 08:52:15 -0800253
254 // FIXME Most of the following initialization is probably redundant since
255 // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0
256 // and mTrackNames is initially 0. However, leave it here until that's verified.
Mathias Agopian65ab4712010-07-14 17:59:35 -0700257 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800258 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Eric Laurenta5e82142012-04-16 13:47:17 -0700259 t->resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700260 t->downmixerBufferProvider = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700261 t++;
262 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700263
Mathias Agopian65ab4712010-07-14 17:59:35 -0700264}
265
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800266AudioMixer::~AudioMixer()
267{
268 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800269 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800270 delete t->resampler;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700271 delete t->downmixerBufferProvider;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800272 t++;
273 }
274 delete [] mState.outputTemp;
275 delete [] mState.resampleTemp;
276}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700277
Glenn Kastenab7d72f2013-02-27 09:05:28 -0800278void AudioMixer::setLog(NBLog::Writer *log)
279{
280 mState.mLog = log;
281}
282
Andy Hunge8a1ced2014-05-09 15:02:21 -0700283int AudioMixer::getTrackName(audio_channel_mask_t channelMask,
284 audio_format_t format, int sessionId)
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800285{
Andy Hunge8a1ced2014-05-09 15:02:21 -0700286 if (!isValidPcmTrackFormat(format)) {
287 ALOGE("AudioMixer::getTrackName invalid format (%#x)", format);
288 return -1;
289 }
Glenn Kasten5c94b6c2012-03-20 17:01:29 -0700290 uint32_t names = (~mTrackNames) & mConfiguredNames;
Glenn Kasten98dd5422011-12-15 14:38:29 -0800291 if (names != 0) {
292 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100293 ALOGV("add track (%d)", n);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700294 // assume default parameters for the track, except where noted below
295 track_t* t = &mState.tracks[n];
296 t->needs = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700297
298 // Integer volume.
299 // Currently integer volume is kept for the legacy integer mixer.
300 // Will be removed when the legacy mixer path is removed.
Andy Hung97ae8242014-05-30 10:35:47 -0700301 t->volume[0] = UNITY_GAIN_INT;
302 t->volume[1] = UNITY_GAIN_INT;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700303 t->prevVolume[0] = UNITY_GAIN_INT << 16;
304 t->prevVolume[1] = UNITY_GAIN_INT << 16;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700305 t->volumeInc[0] = 0;
306 t->volumeInc[1] = 0;
307 t->auxLevel = 0;
308 t->auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700309 t->prevAuxLevel = 0;
310
311 // Floating point volume.
312 t->mVolume[0] = UNITY_GAIN_FLOAT;
313 t->mVolume[1] = UNITY_GAIN_FLOAT;
314 t->mPrevVolume[0] = UNITY_GAIN_FLOAT;
315 t->mPrevVolume[1] = UNITY_GAIN_FLOAT;
316 t->mVolumeInc[0] = 0.;
317 t->mVolumeInc[1] = 0.;
318 t->mAuxLevel = 0.;
319 t->mAuxInc = 0.;
320 t->mPrevAuxLevel = 0.;
321
Glenn Kastendeeb1282012-03-25 11:59:31 -0700322 // no initialization needed
Glenn Kastendeeb1282012-03-25 11:59:31 -0700323 // t->frameCount
Andy Hung68112fc2014-05-14 14:13:23 -0700324 t->channelCount = audio_channel_count_from_out_mask(channelMask);
Glenn Kastendeeb1282012-03-25 11:59:31 -0700325 t->enabled = false;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700326 ALOGV_IF(channelMask != AUDIO_CHANNEL_OUT_STEREO,
327 "Non-stereo channel mask: %d\n", channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700328 t->channelMask = channelMask;
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700329 t->sessionId = sessionId;
Glenn Kastendeeb1282012-03-25 11:59:31 -0700330 // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
331 t->bufferProvider = NULL;
332 t->buffer.raw = NULL;
333 // no initialization needed
334 // t->buffer.frameCount
335 t->hook = NULL;
336 t->in = NULL;
337 t->resampler = NULL;
338 t->sampleRate = mSampleRate;
339 // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
340 t->mainBuffer = NULL;
341 t->auxBuffer = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700342 t->mInputBufferProvider = NULL;
343 t->mReformatBufferProvider = NULL;
Glenn Kasten52008f82012-03-18 09:34:41 -0700344 t->downmixerBufferProvider = NULL;
Andy Hung78820702014-02-28 16:23:02 -0800345 t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
Andy Hunge8a1ced2014-05-09 15:02:21 -0700346 t->mFormat = format;
Andy Hung296b7412014-06-17 15:25:47 -0700347 t->mMixerInFormat = kUseFloat && kUseNewMixer
348 ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
349 // Check the downmixing (or upmixing) requirements.
350 status_t status = initTrackDownmix(t, n, channelMask);
Andy Hung68112fc2014-05-14 14:13:23 -0700351 if (status != OK) {
352 ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
353 return -1;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700354 }
Andy Hung296b7412014-06-17 15:25:47 -0700355 // initTrackDownmix() may change the input format requirement.
356 // If you desire floating point input to the mixer, it may change
357 // to integer because the downmixer requires integer to process.
358 ALOGVV("mMixerFormat:%#x mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
359 prepareTrackForReformat(t, n);
Andy Hung68112fc2014-05-14 14:13:23 -0700360 mTrackNames |= 1 << n;
361 return TRACK0 + n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700362 }
Andy Hung68112fc2014-05-14 14:13:23 -0700363 ALOGE("AudioMixer::getTrackName out of available tracks");
Mathias Agopian65ab4712010-07-14 17:59:35 -0700364 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800365}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700366
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800367void AudioMixer::invalidateState(uint32_t mask)
368{
Glenn Kasten34fca342013-08-13 09:48:14 -0700369 if (mask != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700370 mState.needsChanged |= mask;
371 mState.hook = process__validate;
372 }
373 }
374
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700375status_t AudioMixer::initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask)
376{
Andy Hunge5412692014-05-16 11:25:07 -0700377 uint32_t channelCount = audio_channel_count_from_out_mask(mask);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700378 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
379 status_t status = OK;
380 if (channelCount > MAX_NUM_CHANNELS) {
381 pTrack->channelMask = mask;
382 pTrack->channelCount = channelCount;
383 ALOGV("initTrackDownmix(track=%d, mask=0x%x) calls prepareTrackForDownmix()",
384 trackNum, mask);
385 status = prepareTrackForDownmix(pTrack, trackNum);
386 } else {
387 unprepareTrackForDownmix(pTrack, trackNum);
388 }
389 return status;
390}
391
Andy Hungee931ff2014-01-28 13:44:14 -0800392void AudioMixer::unprepareTrackForDownmix(track_t* pTrack, int trackName __unused) {
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700393 ALOGV("AudioMixer::unprepareTrackForDownmix(%d)", trackName);
394
395 if (pTrack->downmixerBufferProvider != NULL) {
396 // this track had previously been configured with a downmixer, delete it
397 ALOGV(" deleting old downmixer");
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700398 delete pTrack->downmixerBufferProvider;
399 pTrack->downmixerBufferProvider = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700400 reconfigureBufferProviders(pTrack);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700401 } else {
402 ALOGV(" nothing to do, no downmixer to delete");
403 }
404}
405
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700406status_t AudioMixer::prepareTrackForDownmix(track_t* pTrack, int trackName)
407{
408 ALOGV("AudioMixer::prepareTrackForDownmix(%d) with mask 0x%x", trackName, pTrack->channelMask);
409
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700410 // discard the previous downmixer if there was one
411 unprepareTrackForDownmix(pTrack, trackName);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700412
413 DownmixerBufferProvider* pDbp = new DownmixerBufferProvider();
414 int32_t status;
415
Glenn Kasten49c34ac2013-10-30 14:37:01 -0700416 if (!sIsMultichannelCapable) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700417 ALOGE("prepareTrackForDownmix(%d) fails: mixer doesn't support multichannel content",
418 trackName);
419 goto noDownmixForActiveTrack;
420 }
421
Glenn Kasten49c34ac2013-10-30 14:37:01 -0700422 if (EffectCreate(&sDwnmFxDesc.uuid,
Jean-Michel Trivid06e1322012-09-12 15:47:07 -0700423 pTrack->sessionId /*sessionId*/, -2 /*ioId not relevant here, using random value*/,
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700424 &pDbp->mDownmixHandle/*pHandle*/) != 0) {
425 ALOGE("prepareTrackForDownmix(%d) fails: error creating downmixer effect", trackName);
426 goto noDownmixForActiveTrack;
427 }
428
429 // channel input configuration will be overridden per-track
430 pDbp->mDownmixConfig.inputCfg.channels = pTrack->channelMask;
431 pDbp->mDownmixConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
432 pDbp->mDownmixConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
433 pDbp->mDownmixConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
434 pDbp->mDownmixConfig.inputCfg.samplingRate = pTrack->sampleRate;
435 pDbp->mDownmixConfig.outputCfg.samplingRate = pTrack->sampleRate;
436 pDbp->mDownmixConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
437 pDbp->mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
438 // input and output buffer provider, and frame count will not be used as the downmix effect
439 // process() function is called directly (see DownmixerBufferProvider::getNextBuffer())
440 pDbp->mDownmixConfig.inputCfg.mask = EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS |
441 EFFECT_CONFIG_FORMAT | EFFECT_CONFIG_ACC_MODE;
442 pDbp->mDownmixConfig.outputCfg.mask = pDbp->mDownmixConfig.inputCfg.mask;
443
444 {// scope for local variables that are not used in goto label "noDownmixForActiveTrack"
445 int cmdStatus;
446 uint32_t replySize = sizeof(int);
447
448 // Configure and enable downmixer
449 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
450 EFFECT_CMD_SET_CONFIG /*cmdCode*/, sizeof(effect_config_t) /*cmdSize*/,
451 &pDbp->mDownmixConfig /*pCmdData*/,
452 &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
453 if ((status != 0) || (cmdStatus != 0)) {
454 ALOGE("error %d while configuring downmixer for track %d", status, trackName);
455 goto noDownmixForActiveTrack;
456 }
457 replySize = sizeof(int);
458 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
459 EFFECT_CMD_ENABLE /*cmdCode*/, 0 /*cmdSize*/, NULL /*pCmdData*/,
460 &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
461 if ((status != 0) || (cmdStatus != 0)) {
462 ALOGE("error %d while enabling downmixer for track %d", status, trackName);
463 goto noDownmixForActiveTrack;
464 }
465
466 // Set downmix type
467 // parameter size rounded for padding on 32bit boundary
468 const int psizePadded = ((sizeof(downmix_params_t) - 1)/sizeof(int) + 1) * sizeof(int);
469 const int downmixParamSize =
470 sizeof(effect_param_t) + psizePadded + sizeof(downmix_type_t);
471 effect_param_t * const param = (effect_param_t *) malloc(downmixParamSize);
472 param->psize = sizeof(downmix_params_t);
473 const downmix_params_t downmixParam = DOWNMIX_PARAM_TYPE;
474 memcpy(param->data, &downmixParam, param->psize);
475 const downmix_type_t downmixType = DOWNMIX_TYPE_FOLD;
476 param->vsize = sizeof(downmix_type_t);
477 memcpy(param->data + psizePadded, &downmixType, param->vsize);
478
479 status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
480 EFFECT_CMD_SET_PARAM /* cmdCode */, downmixParamSize/* cmdSize */,
481 param /*pCmndData*/, &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
482
483 free(param);
484
485 if ((status != 0) || (cmdStatus != 0)) {
486 ALOGE("error %d while setting downmix type for track %d", status, trackName);
487 goto noDownmixForActiveTrack;
488 } else {
489 ALOGV("downmix type set to %d for track %d", (int) downmixType, trackName);
490 }
491 }// end of scope for local variables that are not used in goto label "noDownmixForActiveTrack"
492
493 // initialization successful:
Andy Hung296b7412014-06-17 15:25:47 -0700494 pTrack->mMixerInFormat = AUDIO_FORMAT_PCM_16_BIT; // 16 bit input is required for downmix
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700495 pTrack->downmixerBufferProvider = pDbp;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700496 reconfigureBufferProviders(pTrack);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700497 return NO_ERROR;
498
499noDownmixForActiveTrack:
500 delete pDbp;
501 pTrack->downmixerBufferProvider = NULL;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700502 reconfigureBufferProviders(pTrack);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700503 return NO_INIT;
504}
505
Andy Hungef7c7fb2014-05-12 16:51:41 -0700506void AudioMixer::unprepareTrackForReformat(track_t* pTrack, int trackName __unused) {
507 ALOGV("AudioMixer::unprepareTrackForReformat(%d)", trackName);
508 if (pTrack->mReformatBufferProvider != NULL) {
509 delete pTrack->mReformatBufferProvider;
510 pTrack->mReformatBufferProvider = NULL;
511 reconfigureBufferProviders(pTrack);
512 }
513}
514
515status_t AudioMixer::prepareTrackForReformat(track_t* pTrack, int trackName)
516{
517 ALOGV("AudioMixer::prepareTrackForReformat(%d) with format %#x", trackName, pTrack->mFormat);
518 // discard the previous reformatter if there was one
Andy Hung296b7412014-06-17 15:25:47 -0700519 unprepareTrackForReformat(pTrack, trackName);
520 // only configure reformatter if needed
521 if (pTrack->mFormat != pTrack->mMixerInFormat) {
522 pTrack->mReformatBufferProvider = new ReformatBufferProvider(
523 audio_channel_count_from_out_mask(pTrack->channelMask),
524 pTrack->mFormat, pTrack->mMixerInFormat);
525 reconfigureBufferProviders(pTrack);
526 }
527 return NO_ERROR;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700528}
529
530void AudioMixer::reconfigureBufferProviders(track_t* pTrack)
531{
532 pTrack->bufferProvider = pTrack->mInputBufferProvider;
533 if (pTrack->mReformatBufferProvider) {
534 pTrack->mReformatBufferProvider->mTrackBufferProvider = pTrack->bufferProvider;
535 pTrack->bufferProvider = pTrack->mReformatBufferProvider;
536 }
537 if (pTrack->downmixerBufferProvider) {
538 pTrack->downmixerBufferProvider->mTrackBufferProvider = pTrack->bufferProvider;
539 pTrack->bufferProvider = pTrack->downmixerBufferProvider;
540 }
541}
542
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800543void AudioMixer::deleteTrackName(int name)
544{
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700545 ALOGV("AudioMixer::deleteTrackName(%d)", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700546 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800547 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten237a6242011-12-15 15:32:27 -0800548 ALOGV("deleteTrackName(%d)", name);
549 track_t& track(mState.tracks[ name ]);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800550 if (track.enabled) {
551 track.enabled = false;
Glenn Kasten237a6242011-12-15 15:32:27 -0800552 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700553 }
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700554 // delete the resampler
555 delete track.resampler;
556 track.resampler = NULL;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700557 // delete the downmixer
558 unprepareTrackForDownmix(&mState.tracks[name], name);
Andy Hungef7c7fb2014-05-12 16:51:41 -0700559 // delete the reformatter
560 unprepareTrackForReformat(&mState.tracks[name], name);
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700561
Glenn Kasten237a6242011-12-15 15:32:27 -0800562 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800563}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700564
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800565void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700566{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800567 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800568 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800569 track_t& track = mState.tracks[name];
570
Glenn Kasten4c340c62012-01-27 12:33:54 -0800571 if (!track.enabled) {
572 track.enabled = true;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800573 ALOGV("enable(%d)", name);
574 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700575 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700576}
577
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800578void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700579{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800580 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800581 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800582 track_t& track = mState.tracks[name];
583
Glenn Kasten4c340c62012-01-27 12:33:54 -0800584 if (track.enabled) {
585 track.enabled = false;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800586 ALOGV("disable(%d)", name);
587 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700588 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700589}
590
Andy Hung5866a3b2014-05-29 21:33:13 -0700591/* Sets the volume ramp variables for the AudioMixer.
592 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700593 * The volume ramp variables are used to transition from the previous
594 * volume to the set volume. ramp controls the duration of the transition.
595 * Its value is typically one state framecount period, but may also be 0,
596 * meaning "immediate."
Andy Hung5866a3b2014-05-29 21:33:13 -0700597 *
Andy Hung5e58b0a2014-06-23 19:07:29 -0700598 * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
599 * even if there is a nonzero floating point increment (in that case, the volume
600 * change is immediate). This restriction should be changed when the legacy mixer
601 * is removed (see #2).
602 * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
603 * when no longer needed.
604 *
605 * @param newVolume set volume target in floating point [0.0, 1.0].
606 * @param ramp number of frames to increment over. if ramp is 0, the volume
607 * should be set immediately. Currently ramp should not exceed 65535 (frames).
608 * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
609 * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
610 * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
611 * @param pSetVolume pointer to the float target volume, set on return.
612 * @param pPrevVolume pointer to the float previous volume, set on return.
613 * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
Andy Hung5866a3b2014-05-29 21:33:13 -0700614 * @return true if the volume has changed, false if volume is same.
615 */
Andy Hung5e58b0a2014-06-23 19:07:29 -0700616static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
617 int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
618 float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
619 if (newVolume == *pSetVolume) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700620 return false;
621 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700622 /* set the floating point volume variables */
Andy Hung5866a3b2014-05-29 21:33:13 -0700623 if (ramp != 0) {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700624 *pVolumeInc = (newVolume - *pSetVolume) / ramp;
625 *pPrevVolume = *pSetVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700626 } else {
Andy Hung5e58b0a2014-06-23 19:07:29 -0700627 *pVolumeInc = 0;
628 *pPrevVolume = newVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700629 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700630 *pSetVolume = newVolume;
631
632 /* set the legacy integer volume variables */
633 int32_t intVolume = newVolume * AudioMixer::UNITY_GAIN_INT;
634 if (intVolume > AudioMixer::UNITY_GAIN_INT) {
635 intVolume = AudioMixer::UNITY_GAIN_INT;
636 } else if (intVolume < 0) {
637 ALOGE("negative volume %.7g", newVolume);
638 intVolume = 0; // should never happen, but for safety check.
639 }
640 if (intVolume == *pIntSetVolume) {
641 *pIntVolumeInc = 0;
642 /* TODO: integer/float workaround: ignore floating volume ramp */
643 *pVolumeInc = 0;
644 *pPrevVolume = newVolume;
645 return true;
646 }
647 if (ramp != 0) {
648 *pIntVolumeInc = ((intVolume - *pIntSetVolume) << 16) / ramp;
649 *pIntPrevVolume = (*pIntVolumeInc == 0 ? intVolume : *pIntSetVolume) << 16;
650 } else {
651 *pIntVolumeInc = 0;
652 *pIntPrevVolume = intVolume << 16;
653 }
654 *pIntSetVolume = intVolume;
Andy Hung5866a3b2014-05-29 21:33:13 -0700655 return true;
656}
657
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800658void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700659{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800660 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800661 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800662 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700663
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000664 int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
665 int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700666
667 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700668
Mathias Agopian65ab4712010-07-14 17:59:35 -0700669 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800670 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700671 case CHANNEL_MASK: {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000672 audio_channel_mask_t mask =
673 static_cast<audio_channel_mask_t>(reinterpret_cast<uintptr_t>(value));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800674 if (track.channelMask != mask) {
Andy Hunge5412692014-05-16 11:25:07 -0700675 uint32_t channelCount = audio_channel_count_from_out_mask(mask);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700676 ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800677 track.channelMask = mask;
678 track.channelCount = channelCount;
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700679 // the mask has changed, does this track need a downmixer?
Andy Hung296b7412014-06-17 15:25:47 -0700680 // update to try using our desired format (if we aren't already using it)
681 track.mMixerInFormat = kUseFloat && kUseNewMixer
682 ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
683 status_t status = initTrackDownmix(&mState.tracks[name], name, mask);
684 ALOGE_IF(status != OK,
685 "Invalid channel mask %#x, initTrackDownmix returned %d",
686 mask, status);
Glenn Kasten788040c2011-05-05 08:19:00 -0700687 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Andy Hung296b7412014-06-17 15:25:47 -0700688 prepareTrackForReformat(&track, name); // format may have changed
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800689 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700690 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700691 } break;
692 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800693 if (track.mainBuffer != valueBuf) {
694 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100695 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800696 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700697 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700698 break;
699 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800700 if (track.auxBuffer != valueBuf) {
701 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100702 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800703 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700704 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700705 break;
Andy Hungef7c7fb2014-05-12 16:51:41 -0700706 case FORMAT: {
707 audio_format_t format = static_cast<audio_format_t>(valueInt);
708 if (track.mFormat != format) {
709 ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
710 track.mFormat = format;
711 ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
Andy Hung296b7412014-06-17 15:25:47 -0700712 prepareTrackForReformat(&track, name);
Andy Hungef7c7fb2014-05-12 16:51:41 -0700713 invalidateState(1 << name);
714 }
715 } break;
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700716 // FIXME do we want to support setting the downmix type from AudioFlinger?
717 // for a specific track? or per mixer?
718 /* case DOWNMIX_TYPE:
719 break */
Andy Hung78820702014-02-28 16:23:02 -0800720 case MIXER_FORMAT: {
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800721 audio_format_t format = static_cast<audio_format_t>(valueInt);
Andy Hung78820702014-02-28 16:23:02 -0800722 if (track.mMixerFormat != format) {
723 track.mMixerFormat = format;
724 ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
Andy Hunga1ab7cc2014-02-24 19:26:52 -0800725 }
726 } break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700727 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800728 LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700729 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700730 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700731
Mathias Agopian65ab4712010-07-14 17:59:35 -0700732 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800733 switch (param) {
734 case SAMPLE_RATE:
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800735 ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
Glenn Kasten788040c2011-05-05 08:19:00 -0700736 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
737 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
738 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800739 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700740 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800741 break;
742 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800743 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800744 invalidateState(1 << name);
745 break;
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700746 case REMOVE:
747 delete track.resampler;
748 track.resampler = NULL;
749 track.sampleRate = mSampleRate;
750 invalidateState(1 << name);
751 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700752 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800753 LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
Eric Laurent243f5f92011-02-28 16:52:51 -0800754 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700755 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700756
Mathias Agopian65ab4712010-07-14 17:59:35 -0700757 case RAMP_VOLUME:
758 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800759 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700760 case VOLUME0:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800761 case VOLUME1:
Andy Hung6be49402014-05-30 10:42:03 -0700762 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung5866a3b2014-05-29 21:33:13 -0700763 target == RAMP_VOLUME ? mState.frameCount : 0,
Andy Hung5e58b0a2014-06-23 19:07:29 -0700764 &track.volume[param - VOLUME0], &track.prevVolume[param - VOLUME0],
765 &track.volumeInc[param - VOLUME0],
766 &track.mVolume[param - VOLUME0], &track.mPrevVolume[param - VOLUME0],
767 &track.mVolumeInc[param - VOLUME0])) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700768 ALOGV("setParameter(%s, VOLUME%d: %04x)",
Andy Hung6be49402014-05-30 10:42:03 -0700769 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
770 track.volume[param - VOLUME0]);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800771 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700772 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800773 break;
774 case AUXLEVEL:
Andy Hung6be49402014-05-30 10:42:03 -0700775 if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
Andy Hung5866a3b2014-05-29 21:33:13 -0700776 target == RAMP_VOLUME ? mState.frameCount : 0,
Andy Hung5e58b0a2014-06-23 19:07:29 -0700777 &track.auxLevel, &track.prevAuxLevel, &track.auxInc,
778 &track.mAuxLevel, &track.mPrevAuxLevel, &track.mAuxInc)) {
Andy Hung5866a3b2014-05-29 21:33:13 -0700779 ALOGV("setParameter(%s, AUXLEVEL: %04x)",
Andy Hung6be49402014-05-30 10:42:03 -0700780 target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track.auxLevel);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800781 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700782 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800783 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700784 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800785 LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700786 }
787 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700788
789 default:
Glenn Kastenadad3d72014-02-21 14:51:43 -0800790 LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700791 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700792}
793
794bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
795{
Glenn Kasten4e2293f2012-04-12 09:39:07 -0700796 if (value != devSampleRate || resampler != NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700797 if (sampleRate != value) {
798 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800799 if (resampler == NULL) {
Glenn Kastenac602052012-10-01 14:04:31 -0700800 ALOGV("creating resampler from track %d Hz to device %d Hz", value, devSampleRate);
801 AudioResampler::src_quality quality;
802 // force lowest quality level resampler if use case isn't music or video
803 // FIXME this is flawed for dynamic sample rates, as we choose the resampler
804 // quality level based on the initial ratio, but that could change later.
805 // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
806 if (!((value == 44100 && devSampleRate == 48000) ||
807 (value == 48000 && devSampleRate == 44100))) {
Andy Hung9e0308c2014-01-30 14:32:31 -0800808 quality = AudioResampler::DYN_LOW_QUALITY;
Glenn Kastenac602052012-10-01 14:04:31 -0700809 } else {
810 quality = AudioResampler::DEFAULT_QUALITY;
811 }
Andy Hung296b7412014-06-17 15:25:47 -0700812
Andy Hung296b7412014-06-17 15:25:47 -0700813 ALOGVV("Creating resampler with %d bits\n", bits);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700814 resampler = AudioResampler::create(
Andy Hung3348e362014-07-07 10:21:44 -0700815 mMixerInFormat,
Jean-Michel Triviacb86cc2012-04-16 12:43:57 -0700816 // the resampler sees the number of channels after the downmixer, if any
Glenn Kastenf551e992013-08-19 18:45:42 -0700817 (int) (downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount),
Glenn Kastenac602052012-10-01 14:04:31 -0700818 devSampleRate, quality);
Glenn Kasten52008f82012-03-18 09:34:41 -0700819 resampler->setLocalTimeFreq(sLocalTimeFreq);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700820 }
821 return true;
822 }
823 }
824 return false;
825}
826
Andy Hung5e58b0a2014-06-23 19:07:29 -0700827/* Checks to see if the volume ramp has completed and clears the increment
828 * variables appropriately.
829 *
830 * FIXME: There is code to handle int/float ramp variable switchover should it not
831 * complete within a mixer buffer processing call, but it is preferred to avoid switchover
832 * due to precision issues. The switchover code is included for legacy code purposes
833 * and can be removed once the integer volume is removed.
834 *
835 * It is not sufficient to clear only the volumeInc integer variable because
836 * if one channel requires ramping, all channels are ramped.
837 *
838 * There is a bit of duplicated code here, but it keeps backward compatibility.
839 */
840inline void AudioMixer::track_t::adjustVolumeRamp(bool aux, bool useFloat)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700841{
Andy Hung5e58b0a2014-06-23 19:07:29 -0700842 if (useFloat) {
843 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
844 if (mVolumeInc[i] != 0 && fabs(mVolume[i] - mPrevVolume[i]) <= fabs(mVolumeInc[i])) {
845 volumeInc[i] = 0;
846 prevVolume[i] = volume[i] << 16;
847 mVolumeInc[i] = 0.;
848 mPrevVolume[i] = mVolume[i];
849
850 } else {
851 //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
852 prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
853 }
854 }
855 } else {
856 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
857 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
858 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
859 volumeInc[i] = 0;
860 prevVolume[i] = volume[i] << 16;
861 mVolumeInc[i] = 0.;
862 mPrevVolume[i] = mVolume[i];
863 } else {
864 //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
865 mPrevVolume[i] = float_from_u4_28(prevVolume[i]);
866 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700867 }
868 }
Andy Hung5e58b0a2014-06-23 19:07:29 -0700869 /* TODO: aux is always integer regardless of output buffer type */
Mathias Agopian65ab4712010-07-14 17:59:35 -0700870 if (aux) {
871 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
Andy Hung5e58b0a2014-06-23 19:07:29 -0700872 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700873 auxInc = 0;
Andy Hung5e58b0a2014-06-23 19:07:29 -0700874 prevAuxLevel = auxLevel << 16;
875 mAuxInc = 0.;
876 mPrevAuxLevel = mAuxLevel;
877 } else {
878 //ALOGV("aux ramp: %d %d %d", auxLevel << 16, prevAuxLevel, auxInc);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700879 }
880 }
881}
882
Glenn Kastenc59c0042012-02-02 14:06:11 -0800883size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800884{
885 name -= TRACK0;
886 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800887 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800888 }
889 return 0;
890}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700891
Glenn Kasten01c4ebf2012-02-22 10:47:35 -0800892void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700893{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800894 name -= TRACK0;
Glenn Kasten5798d4e2012-03-08 12:18:35 -0800895 ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700896
Andy Hung1d26ddf2014-05-29 15:53:09 -0700897 if (mState.tracks[name].mInputBufferProvider == bufferProvider) {
898 return; // don't reset any buffer providers if identical.
899 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700900 if (mState.tracks[name].mReformatBufferProvider != NULL) {
901 mState.tracks[name].mReformatBufferProvider->reset();
902 } else if (mState.tracks[name].downmixerBufferProvider != NULL) {
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700903 }
Andy Hungef7c7fb2014-05-12 16:51:41 -0700904
905 mState.tracks[name].mInputBufferProvider = bufferProvider;
906 reconfigureBufferProviders(&mState.tracks[name]);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700907}
908
909
John Grossman4ff14ba2012-02-08 16:37:41 -0800910void AudioMixer::process(int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700911{
John Grossman4ff14ba2012-02-08 16:37:41 -0800912 mState.hook(&mState, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700913}
914
915
John Grossman4ff14ba2012-02-08 16:37:41 -0800916void AudioMixer::process__validate(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700917{
Steve Block5ff1dd52012-01-05 23:22:43 +0000918 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700919 "in process__validate() but nothing's invalid");
920
921 uint32_t changed = state->needsChanged;
922 state->needsChanged = 0; // clear the validation flag
923
924 // recompute which tracks are enabled / disabled
925 uint32_t enabled = 0;
926 uint32_t disabled = 0;
927 while (changed) {
928 const int i = 31 - __builtin_clz(changed);
929 const uint32_t mask = 1<<i;
930 changed &= ~mask;
931 track_t& t = state->tracks[i];
932 (t.enabled ? enabled : disabled) |= mask;
933 }
934 state->enabledTracks &= ~disabled;
935 state->enabledTracks |= enabled;
936
937 // compute everything we need...
938 int countActiveTracks = 0;
Glenn Kasten4c340c62012-01-27 12:33:54 -0800939 bool all16BitsStereoNoResample = true;
940 bool resampling = false;
941 bool volumeRamp = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700942 uint32_t en = state->enabledTracks;
943 while (en) {
944 const int i = 31 - __builtin_clz(en);
945 en &= ~(1<<i);
946
947 countActiveTracks++;
948 track_t& t = state->tracks[i];
949 uint32_t n = 0;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700950 // FIXME can overflow (mask is only 3 bits)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700951 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
Glenn Kastend6fadf02013-10-30 14:37:29 -0700952 if (t.doesResample()) {
953 n |= NEEDS_RESAMPLE;
954 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700955 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700956 n |= NEEDS_AUX;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700957 }
958
959 if (t.volumeInc[0]|t.volumeInc[1]) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800960 volumeRamp = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700961 } else if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700962 n |= NEEDS_MUTE;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700963 }
964 t.needs = n;
965
Glenn Kastend6fadf02013-10-30 14:37:29 -0700966 if (n & NEEDS_MUTE) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700967 t.hook = track__nop;
968 } else {
Glenn Kastend6fadf02013-10-30 14:37:29 -0700969 if (n & NEEDS_AUX) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800970 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700971 }
Glenn Kastend6fadf02013-10-30 14:37:29 -0700972 if (n & NEEDS_RESAMPLE) {
Glenn Kasten4c340c62012-01-27 12:33:54 -0800973 all16BitsStereoNoResample = false;
974 resampling = true;
Andy Hung296b7412014-06-17 15:25:47 -0700975 t.hook = getTrackHook(TRACKTYPE_RESAMPLE, FCC_2,
976 t.mMixerInFormat, t.mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700977 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700978 "Track %d needs downmix + resample", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700979 } else {
980 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
Andy Hung296b7412014-06-17 15:25:47 -0700981 t.hook = getTrackHook(TRACKTYPE_NORESAMPLEMONO, FCC_2,
982 t.mMixerInFormat, t.mMixerFormat);
Glenn Kasten4c340c62012-01-27 12:33:54 -0800983 all16BitsStereoNoResample = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700984 }
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700985 if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
Andy Hung296b7412014-06-17 15:25:47 -0700986 t.hook = getTrackHook(TRACKTYPE_NORESAMPLE, FCC_2,
987 t.mMixerInFormat, t.mMixerFormat);
Jean-Michel Trivi7d5b2622012-04-04 18:54:36 -0700988 ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
Jean-Michel Trivi9bd23222012-04-16 13:43:48 -0700989 "Track %d needs downmix", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700990 }
991 }
992 }
993 }
994
995 // select the processing hooks
996 state->hook = process__nop;
Glenn Kasten34fca342013-08-13 09:48:14 -0700997 if (countActiveTracks > 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700998 if (resampling) {
999 if (!state->outputTemp) {
1000 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
1001 }
1002 if (!state->resampleTemp) {
1003 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
1004 }
1005 state->hook = process__genericResampling;
1006 } else {
1007 if (state->outputTemp) {
1008 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -08001009 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001010 }
1011 if (state->resampleTemp) {
1012 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -08001013 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001014 }
1015 state->hook = process__genericNoResampling;
1016 if (all16BitsStereoNoResample && !volumeRamp) {
1017 if (countActiveTracks == 1) {
Andy Hung296b7412014-06-17 15:25:47 -07001018 const int i = 31 - __builtin_clz(state->enabledTracks);
1019 track_t& t = state->tracks[i];
1020 state->hook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK, FCC_2,
1021 t.mMixerInFormat, t.mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001022 }
1023 }
1024 }
1025 }
1026
Steve Block3856b092011-10-20 11:56:00 +01001027 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001028 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
1029 countActiveTracks, state->enabledTracks,
1030 all16BitsStereoNoResample, resampling, volumeRamp);
1031
John Grossman4ff14ba2012-02-08 16:37:41 -08001032 state->hook(state, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001033
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001034 // Now that the volume ramp has been done, set optimal state and
1035 // track hooks for subsequent mixer process
Glenn Kasten34fca342013-08-13 09:48:14 -07001036 if (countActiveTracks > 0) {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001037 bool allMuted = true;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001038 uint32_t en = state->enabledTracks;
1039 while (en) {
1040 const int i = 31 - __builtin_clz(en);
1041 en &= ~(1<<i);
1042 track_t& t = state->tracks[i];
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001043 if (!t.doesResample() && t.volumeRL == 0) {
Glenn Kastend6fadf02013-10-30 14:37:29 -07001044 t.needs |= NEEDS_MUTE;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001045 t.hook = track__nop;
1046 } else {
Glenn Kasten4c340c62012-01-27 12:33:54 -08001047 allMuted = false;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001048 }
1049 }
1050 if (allMuted) {
1051 state->hook = process__nop;
1052 } else if (all16BitsStereoNoResample) {
1053 if (countActiveTracks == 1) {
1054 state->hook = process__OneTrack16BitsStereoNoResampling;
1055 }
1056 }
1057 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001058}
1059
Mathias Agopian65ab4712010-07-14 17:59:35 -07001060
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001061void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount,
1062 int32_t* temp, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001063{
Andy Hung296b7412014-06-17 15:25:47 -07001064 ALOGVV("track__genericResample\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001065 t->resampler->setSampleRate(t->sampleRate);
1066
1067 // ramp gain - resample to temp buffer and scale/mix in 2nd step
1068 if (aux != NULL) {
1069 // always resample with unity gain when sending to auxiliary buffer to be able
1070 // to apply send level after resampling
1071 // TODO: modify each resampler to support aux channel?
Andy Hung5e58b0a2014-06-23 19:07:29 -07001072 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001073 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
1074 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -08001075 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001076 volumeRampStereo(t, out, outFrameCount, temp, aux);
1077 } else {
1078 volumeStereo(t, out, outFrameCount, temp, aux);
1079 }
1080 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -08001081 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001082 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001083 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
1084 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
1085 volumeRampStereo(t, out, outFrameCount, temp, aux);
1086 }
1087
1088 // constant gain
1089 else {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001090 t->resampler->setVolume(t->mVolume[0], t->mVolume[1]);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001091 t->resampler->resample(out, outFrameCount, t->bufferProvider);
1092 }
1093 }
1094}
1095
Andy Hungee931ff2014-01-28 13:44:14 -08001096void AudioMixer::track__nop(track_t* t __unused, int32_t* out __unused,
1097 size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001098{
1099}
1100
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001101void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1102 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001103{
1104 int32_t vl = t->prevVolume[0];
1105 int32_t vr = t->prevVolume[1];
1106 const int32_t vlInc = t->volumeInc[0];
1107 const int32_t vrInc = t->volumeInc[1];
1108
Steve Blockb8a80522011-12-20 16:23:08 +00001109 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001110 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1111 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1112
1113 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -08001114 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001115 int32_t va = t->prevAuxLevel;
1116 const int32_t vaInc = t->auxInc;
1117 int32_t l;
1118 int32_t r;
1119
1120 do {
1121 l = (*temp++ >> 12);
1122 r = (*temp++ >> 12);
1123 *out++ += (vl >> 16) * l;
1124 *out++ += (vr >> 16) * r;
1125 *aux++ += (va >> 17) * (l + r);
1126 vl += vlInc;
1127 vr += vrInc;
1128 va += vaInc;
1129 } while (--frameCount);
1130 t->prevAuxLevel = va;
1131 } else {
1132 do {
1133 *out++ += (vl >> 16) * (*temp++ >> 12);
1134 *out++ += (vr >> 16) * (*temp++ >> 12);
1135 vl += vlInc;
1136 vr += vrInc;
1137 } while (--frameCount);
1138 }
1139 t->prevVolume[0] = vl;
1140 t->prevVolume[1] = vr;
Glenn Kastena1117922012-01-26 10:53:32 -08001141 t->adjustVolumeRamp(aux != NULL);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001142}
1143
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001144void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
1145 int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001146{
1147 const int16_t vl = t->volume[0];
1148 const int16_t vr = t->volume[1];
1149
Glenn Kastenf6b16782011-12-15 09:51:17 -08001150 if (CC_UNLIKELY(aux != NULL)) {
Glenn Kasten3b81aca2012-01-27 15:26:23 -08001151 const int16_t va = t->auxLevel;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001152 do {
1153 int16_t l = (int16_t)(*temp++ >> 12);
1154 int16_t r = (int16_t)(*temp++ >> 12);
1155 out[0] = mulAdd(l, vl, out[0]);
1156 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
1157 out[1] = mulAdd(r, vr, out[1]);
1158 out += 2;
1159 aux[0] = mulAdd(a, va, aux[0]);
1160 aux++;
1161 } while (--frameCount);
1162 } else {
1163 do {
1164 int16_t l = (int16_t)(*temp++ >> 12);
1165 int16_t r = (int16_t)(*temp++ >> 12);
1166 out[0] = mulAdd(l, vl, out[0]);
1167 out[1] = mulAdd(r, vr, out[1]);
1168 out += 2;
1169 } while (--frameCount);
1170 }
1171}
1172
Andy Hungee931ff2014-01-28 13:44:14 -08001173void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount,
1174 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001175{
Andy Hung296b7412014-06-17 15:25:47 -07001176 ALOGVV("track__16BitsStereo\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001177 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001178
Glenn Kastenf6b16782011-12-15 09:51:17 -08001179 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001180 int32_t l;
1181 int32_t r;
1182 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001183 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001184 int32_t vl = t->prevVolume[0];
1185 int32_t vr = t->prevVolume[1];
1186 int32_t va = t->prevAuxLevel;
1187 const int32_t vlInc = t->volumeInc[0];
1188 const int32_t vrInc = t->volumeInc[1];
1189 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +00001190 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001191 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1192 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1193
1194 do {
1195 l = (int32_t)*in++;
1196 r = (int32_t)*in++;
1197 *out++ += (vl >> 16) * l;
1198 *out++ += (vr >> 16) * r;
1199 *aux++ += (va >> 17) * (l + r);
1200 vl += vlInc;
1201 vr += vrInc;
1202 va += vaInc;
1203 } while (--frameCount);
1204
1205 t->prevVolume[0] = vl;
1206 t->prevVolume[1] = vr;
1207 t->prevAuxLevel = va;
1208 t->adjustVolumeRamp(true);
1209 }
1210
1211 // constant gain
1212 else {
1213 const uint32_t vrl = t->volumeRL;
1214 const int16_t va = (int16_t)t->auxLevel;
1215 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001216 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001217 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
1218 in += 2;
1219 out[0] = mulAddRL(1, rl, vrl, out[0]);
1220 out[1] = mulAddRL(0, rl, vrl, out[1]);
1221 out += 2;
1222 aux[0] = mulAdd(a, va, aux[0]);
1223 aux++;
1224 } while (--frameCount);
1225 }
1226 } else {
1227 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001228 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001229 int32_t vl = t->prevVolume[0];
1230 int32_t vr = t->prevVolume[1];
1231 const int32_t vlInc = t->volumeInc[0];
1232 const int32_t vrInc = t->volumeInc[1];
1233
Steve Blockb8a80522011-12-20 16:23:08 +00001234 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001235 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1236 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1237
1238 do {
1239 *out++ += (vl >> 16) * (int32_t) *in++;
1240 *out++ += (vr >> 16) * (int32_t) *in++;
1241 vl += vlInc;
1242 vr += vrInc;
1243 } while (--frameCount);
1244
1245 t->prevVolume[0] = vl;
1246 t->prevVolume[1] = vr;
1247 t->adjustVolumeRamp(false);
1248 }
1249
1250 // constant gain
1251 else {
1252 const uint32_t vrl = t->volumeRL;
1253 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001254 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001255 in += 2;
1256 out[0] = mulAddRL(1, rl, vrl, out[0]);
1257 out[1] = mulAddRL(0, rl, vrl, out[1]);
1258 out += 2;
1259 } while (--frameCount);
1260 }
1261 }
1262 t->in = in;
1263}
1264
Andy Hungee931ff2014-01-28 13:44:14 -08001265void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount,
1266 int32_t* temp __unused, int32_t* aux)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001267{
Andy Hung296b7412014-06-17 15:25:47 -07001268 ALOGVV("track__16BitsMono\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001269 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001270
Glenn Kastenf6b16782011-12-15 09:51:17 -08001271 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001272 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001273 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001274 int32_t vl = t->prevVolume[0];
1275 int32_t vr = t->prevVolume[1];
1276 int32_t va = t->prevAuxLevel;
1277 const int32_t vlInc = t->volumeInc[0];
1278 const int32_t vrInc = t->volumeInc[1];
1279 const int32_t vaInc = t->auxInc;
1280
Steve Blockb8a80522011-12-20 16:23:08 +00001281 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001282 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1283 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1284
1285 do {
1286 int32_t l = *in++;
1287 *out++ += (vl >> 16) * l;
1288 *out++ += (vr >> 16) * l;
1289 *aux++ += (va >> 16) * l;
1290 vl += vlInc;
1291 vr += vrInc;
1292 va += vaInc;
1293 } while (--frameCount);
1294
1295 t->prevVolume[0] = vl;
1296 t->prevVolume[1] = vr;
1297 t->prevAuxLevel = va;
1298 t->adjustVolumeRamp(true);
1299 }
1300 // constant gain
1301 else {
1302 const int16_t vl = t->volume[0];
1303 const int16_t vr = t->volume[1];
1304 const int16_t va = (int16_t)t->auxLevel;
1305 do {
1306 int16_t l = *in++;
1307 out[0] = mulAdd(l, vl, out[0]);
1308 out[1] = mulAdd(l, vr, out[1]);
1309 out += 2;
1310 aux[0] = mulAdd(l, va, aux[0]);
1311 aux++;
1312 } while (--frameCount);
1313 }
1314 } else {
1315 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -08001316 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001317 int32_t vl = t->prevVolume[0];
1318 int32_t vr = t->prevVolume[1];
1319 const int32_t vlInc = t->volumeInc[0];
1320 const int32_t vrInc = t->volumeInc[1];
1321
Steve Blockb8a80522011-12-20 16:23:08 +00001322 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001323 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1324 // (vl + vlInc*frameCount)/65536.0f, frameCount);
1325
1326 do {
1327 int32_t l = *in++;
1328 *out++ += (vl >> 16) * l;
1329 *out++ += (vr >> 16) * l;
1330 vl += vlInc;
1331 vr += vrInc;
1332 } while (--frameCount);
1333
1334 t->prevVolume[0] = vl;
1335 t->prevVolume[1] = vr;
1336 t->adjustVolumeRamp(false);
1337 }
1338 // constant gain
1339 else {
1340 const int16_t vl = t->volume[0];
1341 const int16_t vr = t->volume[1];
1342 do {
1343 int16_t l = *in++;
1344 out[0] = mulAdd(l, vl, out[0]);
1345 out[1] = mulAdd(l, vr, out[1]);
1346 out += 2;
1347 } while (--frameCount);
1348 }
1349 }
1350 t->in = in;
1351}
1352
Mathias Agopian65ab4712010-07-14 17:59:35 -07001353// no-op case
John Grossman4ff14ba2012-02-08 16:37:41 -08001354void AudioMixer::process__nop(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001355{
Andy Hung296b7412014-06-17 15:25:47 -07001356 ALOGVV("process__nop\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001357 uint32_t e0 = state->enabledTracks;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001358 size_t sampleCount = state->frameCount * MAX_NUM_CHANNELS;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001359 while (e0) {
1360 // process by group of tracks with same output buffer to
1361 // avoid multiple memset() on same buffer
1362 uint32_t e1 = e0, e2 = e0;
1363 int i = 31 - __builtin_clz(e1);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001364 {
1365 track_t& t1 = state->tracks[i];
Mathias Agopian65ab4712010-07-14 17:59:35 -07001366 e2 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001367 while (e2) {
1368 i = 31 - __builtin_clz(e2);
1369 e2 &= ~(1<<i);
1370 track_t& t2 = state->tracks[i];
1371 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1372 e1 &= ~(1<<i);
1373 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001374 }
Glenn Kastenfc900c92013-02-18 12:47:49 -08001375 e0 &= ~(e1);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001376
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001377 memset(t1.mainBuffer, 0, sampleCount
Andy Hung78820702014-02-28 16:23:02 -08001378 * audio_bytes_per_sample(t1.mMixerFormat));
Glenn Kastenfc900c92013-02-18 12:47:49 -08001379 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001380
1381 while (e1) {
1382 i = 31 - __builtin_clz(e1);
1383 e1 &= ~(1<<i);
Glenn Kastenfc900c92013-02-18 12:47:49 -08001384 {
1385 track_t& t3 = state->tracks[i];
1386 size_t outFrames = state->frameCount;
1387 while (outFrames) {
1388 t3.buffer.frameCount = outFrames;
1389 int64_t outputPTS = calculateOutputPTS(
1390 t3, pts, state->frameCount - outFrames);
1391 t3.bufferProvider->getNextBuffer(&t3.buffer, outputPTS);
1392 if (t3.buffer.raw == NULL) break;
1393 outFrames -= t3.buffer.frameCount;
1394 t3.bufferProvider->releaseBuffer(&t3.buffer);
1395 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001396 }
1397 }
1398 }
1399}
1400
1401// generic code without resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001402void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001403{
Andy Hung296b7412014-06-17 15:25:47 -07001404 ALOGVV("process__genericNoResampling\n");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001405 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1406
1407 // acquire each track's buffer
1408 uint32_t enabledTracks = state->enabledTracks;
1409 uint32_t e0 = enabledTracks;
1410 while (e0) {
1411 const int i = 31 - __builtin_clz(e0);
1412 e0 &= ~(1<<i);
1413 track_t& t = state->tracks[i];
1414 t.buffer.frameCount = state->frameCount;
John Grossman4ff14ba2012-02-08 16:37:41 -08001415 t.bufferProvider->getNextBuffer(&t.buffer, pts);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001416 t.frameCount = t.buffer.frameCount;
1417 t.in = t.buffer.raw;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001418 }
1419
1420 e0 = enabledTracks;
1421 while (e0) {
1422 // process by group of tracks with same output buffer to
1423 // optimize cache use
1424 uint32_t e1 = e0, e2 = e0;
1425 int j = 31 - __builtin_clz(e1);
1426 track_t& t1 = state->tracks[j];
1427 e2 &= ~(1<<j);
1428 while (e2) {
1429 j = 31 - __builtin_clz(e2);
1430 e2 &= ~(1<<j);
1431 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001432 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001433 e1 &= ~(1<<j);
1434 }
1435 }
1436 e0 &= ~(e1);
1437 // this assumes output 16 bits stereo, no resampling
1438 int32_t *out = t1.mainBuffer;
1439 size_t numFrames = 0;
1440 do {
1441 memset(outTemp, 0, sizeof(outTemp));
1442 e2 = e1;
1443 while (e2) {
1444 const int i = 31 - __builtin_clz(e2);
1445 e2 &= ~(1<<i);
1446 track_t& t = state->tracks[i];
1447 size_t outFrames = BLOCKSIZE;
1448 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001449 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001450 aux = t.auxBuffer + numFrames;
1451 }
1452 while (outFrames) {
Gaurav Kumar7e79cd22014-01-06 10:57:18 +05301453 // t.in == NULL can happen if the track was flushed just after having
1454 // been enabled for mixing.
1455 if (t.in == NULL) {
1456 enabledTracks &= ~(1<<i);
1457 e1 &= ~(1<<i);
1458 break;
1459 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001460 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
Glenn Kasten34fca342013-08-13 09:48:14 -07001461 if (inFrames > 0) {
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001462 t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames,
1463 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001464 t.frameCount -= inFrames;
1465 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -08001466 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001467 aux += inFrames;
1468 }
1469 }
1470 if (t.frameCount == 0 && outFrames) {
1471 t.bufferProvider->releaseBuffer(&t.buffer);
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001472 t.buffer.frameCount = (state->frameCount - numFrames) -
1473 (BLOCKSIZE - outFrames);
John Grossman4ff14ba2012-02-08 16:37:41 -08001474 int64_t outputPTS = calculateOutputPTS(
1475 t, pts, numFrames + (BLOCKSIZE - outFrames));
1476 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001477 t.in = t.buffer.raw;
1478 if (t.in == NULL) {
1479 enabledTracks &= ~(1<<i);
1480 e1 &= ~(1<<i);
1481 break;
1482 }
1483 t.frameCount = t.buffer.frameCount;
1484 }
1485 }
1486 }
Andy Hung296b7412014-06-17 15:25:47 -07001487
1488 convertMixerFormat(out, t1.mMixerFormat, outTemp, t1.mMixerInFormat,
1489 BLOCKSIZE * FCC_2);
1490 // TODO: fix ugly casting due to choice of out pointer type
1491 out = reinterpret_cast<int32_t*>((uint8_t*)out
1492 + BLOCKSIZE * FCC_2 * audio_bytes_per_sample(t1.mMixerFormat));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001493 numFrames += BLOCKSIZE;
1494 } while (numFrames < state->frameCount);
1495 }
1496
1497 // release each track's buffer
1498 e0 = enabledTracks;
1499 while (e0) {
1500 const int i = 31 - __builtin_clz(e0);
1501 e0 &= ~(1<<i);
1502 track_t& t = state->tracks[i];
1503 t.bufferProvider->releaseBuffer(&t.buffer);
1504 }
1505}
1506
1507
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001508// generic code with resampling
John Grossman4ff14ba2012-02-08 16:37:41 -08001509void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001510{
Andy Hung296b7412014-06-17 15:25:47 -07001511 ALOGVV("process__genericResampling\n");
Glenn Kasten54c3b662012-01-06 07:46:30 -08001512 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -07001513 int32_t* const outTemp = state->outputTemp;
1514 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001515
1516 size_t numFrames = state->frameCount;
1517
1518 uint32_t e0 = state->enabledTracks;
1519 while (e0) {
1520 // process by group of tracks with same output buffer
1521 // to optimize cache use
1522 uint32_t e1 = e0, e2 = e0;
1523 int j = 31 - __builtin_clz(e1);
1524 track_t& t1 = state->tracks[j];
1525 e2 &= ~(1<<j);
1526 while (e2) {
1527 j = 31 - __builtin_clz(e2);
1528 e2 &= ~(1<<j);
1529 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -08001530 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001531 e1 &= ~(1<<j);
1532 }
1533 }
1534 e0 &= ~(e1);
1535 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +01001536 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001537 while (e1) {
1538 const int i = 31 - __builtin_clz(e1);
1539 e1 &= ~(1<<i);
1540 track_t& t = state->tracks[i];
1541 int32_t *aux = NULL;
Glenn Kastend6fadf02013-10-30 14:37:29 -07001542 if (CC_UNLIKELY(t.needs & NEEDS_AUX)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001543 aux = t.auxBuffer;
1544 }
1545
1546 // this is a little goofy, on the resampling case we don't
1547 // acquire/release the buffers because it's done by
1548 // the resampler.
Glenn Kastend6fadf02013-10-30 14:37:29 -07001549 if (t.needs & NEEDS_RESAMPLE) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001550 t.resampler->setPTS(pts);
Glenn Kastena1117922012-01-26 10:53:32 -08001551 t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001552 } else {
1553
1554 size_t outFrames = 0;
1555
1556 while (outFrames < numFrames) {
1557 t.buffer.frameCount = numFrames - outFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001558 int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
1559 t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001560 t.in = t.buffer.raw;
1561 // t.in == NULL can happen if the track was flushed just after having
1562 // been enabled for mixing.
1563 if (t.in == NULL) break;
1564
Glenn Kastenf6b16782011-12-15 09:51:17 -08001565 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001566 aux += outFrames;
1567 }
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001568 t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount,
1569 state->resampleTemp, aux);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001570 outFrames += t.buffer.frameCount;
1571 t.bufferProvider->releaseBuffer(&t.buffer);
1572 }
1573 }
1574 }
Andy Hung296b7412014-06-17 15:25:47 -07001575 convertMixerFormat(out, t1.mMixerFormat, outTemp, t1.mMixerInFormat, numFrames * FCC_2);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001576 }
1577}
1578
1579// one track, 16 bits stereo without resampling is the most common case
John Grossman4ff14ba2012-02-08 16:37:41 -08001580void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
1581 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001582{
Andy Hung296b7412014-06-17 15:25:47 -07001583 ALOGVV("process__OneTrack16BitsStereoNoResampling\n");
Glenn Kasten99e53b82012-01-19 08:59:58 -08001584 // This method is only called when state->enabledTracks has exactly
1585 // one bit set. The asserts below would verify this, but are commented out
1586 // since the whole point of this method is to optimize performance.
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001587 //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001588 const int i = 31 - __builtin_clz(state->enabledTracks);
Glenn Kasten5798d4e2012-03-08 12:18:35 -08001589 //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
Mathias Agopian65ab4712010-07-14 17:59:35 -07001590 const track_t& t = state->tracks[i];
1591
1592 AudioBufferProvider::Buffer& b(t.buffer);
1593
1594 int32_t* out = t.mainBuffer;
Andy Hungf8a106a2014-05-29 18:52:38 -07001595 float *fout = reinterpret_cast<float*>(out);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001596 size_t numFrames = state->frameCount;
1597
1598 const int16_t vl = t.volume[0];
1599 const int16_t vr = t.volume[1];
1600 const uint32_t vrl = t.volumeRL;
1601 while (numFrames) {
1602 b.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001603 int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
1604 t.bufferProvider->getNextBuffer(&b, outputPTS);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001605 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001606
1607 // in == NULL can happen if the track was flushed just after having
1608 // been enabled for mixing.
Andy Hungf8a106a2014-05-29 18:52:38 -07001609 if (in == NULL || (((uintptr_t)in) & 3)) {
1610 memset(out, 0, numFrames
1611 * MAX_NUM_CHANNELS * audio_bytes_per_sample(t.mMixerFormat));
1612 ALOGE_IF((((uintptr_t)in) & 3), "process stereo track: input buffer alignment pb: "
Glenn Kasten85ab62c2012-11-01 11:11:38 -07001613 "buffer %p track %d, channels %d, needs %08x",
Mathias Agopian65ab4712010-07-14 17:59:35 -07001614 in, i, t.channelCount, t.needs);
1615 return;
1616 }
1617 size_t outFrames = b.frameCount;
1618
Andy Hung78820702014-02-28 16:23:02 -08001619 switch (t.mMixerFormat) {
Andy Hungf8a106a2014-05-29 18:52:38 -07001620 case AUDIO_FORMAT_PCM_FLOAT:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001621 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001622 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001623 in += 2;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001624 int32_t l = mulRL(1, rl, vrl);
1625 int32_t r = mulRL(0, rl, vrl);
Andy Hung84a0c6e2014-04-02 11:24:53 -07001626 *fout++ = float_from_q4_27(l);
1627 *fout++ = float_from_q4_27(r);
Andy Hung3375bde2014-02-28 15:51:47 -08001628 // Note: In case of later int16_t sink output,
1629 // conversion and clamping is done by memcpy_to_i16_from_float().
Mathias Agopian65ab4712010-07-14 17:59:35 -07001630 } while (--outFrames);
Andy Hungf8a106a2014-05-29 18:52:38 -07001631 break;
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001632 case AUDIO_FORMAT_PCM_16_BIT:
Andy Hung97ae8242014-05-30 10:35:47 -07001633 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
Andy Hunga1ab7cc2014-02-24 19:26:52 -08001634 // volume is boosted, so we might need to clamp even though
1635 // we process only one track.
1636 do {
1637 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1638 in += 2;
1639 int32_t l = mulRL(1, rl, vrl) >> 12;
1640 int32_t r = mulRL(0, rl, vrl) >> 12;
1641 // clamping...
1642 l = clamp16(l);
1643 r = clamp16(r);
1644 *out++ = (r<<16) | (l & 0xFFFF);
1645 } while (--outFrames);
1646 } else {
1647 do {
1648 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1649 in += 2;
1650 int32_t l = mulRL(1, rl, vrl) >> 12;
1651 int32_t r = mulRL(0, rl, vrl) >> 12;
1652 *out++ = (r<<16) | (l & 0xFFFF);
1653 } while (--outFrames);
1654 }
1655 break;
1656 default:
Andy Hung78820702014-02-28 16:23:02 -08001657 LOG_ALWAYS_FATAL("bad mixer format: %d", t.mMixerFormat);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001658 }
1659 numFrames -= b.frameCount;
1660 t.bufferProvider->releaseBuffer(&b);
1661 }
1662}
1663
Glenn Kasten81a028f2011-12-15 09:53:12 -08001664#if 0
Mathias Agopian65ab4712010-07-14 17:59:35 -07001665// 2 tracks is also a common case
1666// NEVER used in current implementation of process__validate()
1667// only use if the 2 tracks have the same output buffer
John Grossman4ff14ba2012-02-08 16:37:41 -08001668void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state,
1669 int64_t pts)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001670{
1671 int i;
1672 uint32_t en = state->enabledTracks;
1673
1674 i = 31 - __builtin_clz(en);
1675 const track_t& t0 = state->tracks[i];
1676 AudioBufferProvider::Buffer& b0(t0.buffer);
1677
1678 en &= ~(1<<i);
1679 i = 31 - __builtin_clz(en);
1680 const track_t& t1 = state->tracks[i];
1681 AudioBufferProvider::Buffer& b1(t1.buffer);
1682
Glenn Kasten54c3b662012-01-06 07:46:30 -08001683 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001684 const int16_t vl0 = t0.volume[0];
1685 const int16_t vr0 = t0.volume[1];
1686 size_t frameCount0 = 0;
1687
Glenn Kasten54c3b662012-01-06 07:46:30 -08001688 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001689 const int16_t vl1 = t1.volume[0];
1690 const int16_t vr1 = t1.volume[1];
1691 size_t frameCount1 = 0;
1692
1693 //FIXME: only works if two tracks use same buffer
1694 int32_t* out = t0.mainBuffer;
1695 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001696 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001697
1698
1699 while (numFrames) {
1700
1701 if (frameCount0 == 0) {
1702 b0.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001703 int64_t outputPTS = calculateOutputPTS(t0, pts,
1704 out - t0.mainBuffer);
1705 t0.bufferProvider->getNextBuffer(&b0, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001706 if (b0.i16 == NULL) {
1707 if (buff == NULL) {
1708 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1709 }
1710 in0 = buff;
1711 b0.frameCount = numFrames;
1712 } else {
1713 in0 = b0.i16;
1714 }
1715 frameCount0 = b0.frameCount;
1716 }
1717 if (frameCount1 == 0) {
1718 b1.frameCount = numFrames;
John Grossman4ff14ba2012-02-08 16:37:41 -08001719 int64_t outputPTS = calculateOutputPTS(t1, pts,
1720 out - t0.mainBuffer);
1721 t1.bufferProvider->getNextBuffer(&b1, outputPTS);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001722 if (b1.i16 == NULL) {
1723 if (buff == NULL) {
1724 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1725 }
1726 in1 = buff;
1727 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001728 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001729 in1 = b1.i16;
1730 }
1731 frameCount1 = b1.frameCount;
1732 }
1733
1734 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1735
1736 numFrames -= outFrames;
1737 frameCount0 -= outFrames;
1738 frameCount1 -= outFrames;
1739
1740 do {
1741 int32_t l0 = *in0++;
1742 int32_t r0 = *in0++;
1743 l0 = mul(l0, vl0);
1744 r0 = mul(r0, vr0);
1745 int32_t l = *in1++;
1746 int32_t r = *in1++;
1747 l = mulAdd(l, vl1, l0) >> 12;
1748 r = mulAdd(r, vr1, r0) >> 12;
1749 // clamping...
1750 l = clamp16(l);
1751 r = clamp16(r);
1752 *out++ = (r<<16) | (l & 0xFFFF);
1753 } while (--outFrames);
1754
1755 if (frameCount0 == 0) {
1756 t0.bufferProvider->releaseBuffer(&b0);
1757 }
1758 if (frameCount1 == 0) {
1759 t1.bufferProvider->releaseBuffer(&b1);
1760 }
1761 }
1762
Glenn Kastene9dd0172012-01-27 18:08:45 -08001763 delete [] buff;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001764}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001765#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001766
John Grossman4ff14ba2012-02-08 16:37:41 -08001767int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1768 int outputFrameIndex)
1769{
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001770 if (AudioBufferProvider::kInvalidPTS == basePTS) {
John Grossman4ff14ba2012-02-08 16:37:41 -08001771 return AudioBufferProvider::kInvalidPTS;
Glenn Kasten6e2ebe92013-08-13 09:14:51 -07001772 }
John Grossman4ff14ba2012-02-08 16:37:41 -08001773
Glenn Kasten52008f82012-03-18 09:34:41 -07001774 return basePTS + ((outputFrameIndex * sLocalTimeFreq) / t.sampleRate);
1775}
1776
1777/*static*/ uint64_t AudioMixer::sLocalTimeFreq;
1778/*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
1779
1780/*static*/ void AudioMixer::sInitRoutine()
1781{
1782 LocalClock lc;
1783 sLocalTimeFreq = lc.getLocalFreq();
Glenn Kasten49c34ac2013-10-30 14:37:01 -07001784
1785 // find multichannel downmix effect if we have to play multichannel content
1786 uint32_t numEffects = 0;
1787 int ret = EffectQueryNumberEffects(&numEffects);
1788 if (ret != 0) {
1789 ALOGE("AudioMixer() error %d querying number of effects", ret);
1790 return;
1791 }
1792 ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects);
1793
1794 for (uint32_t i = 0 ; i < numEffects ; i++) {
1795 if (EffectQueryEffect(i, &sDwnmFxDesc) == 0) {
1796 ALOGV("effect %d is called %s", i, sDwnmFxDesc.name);
1797 if (memcmp(&sDwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) {
1798 ALOGI("found effect \"%s\" from %s",
1799 sDwnmFxDesc.name, sDwnmFxDesc.implementor);
1800 sIsMultichannelCapable = true;
1801 break;
1802 }
1803 }
1804 }
1805 ALOGW_IF(!sIsMultichannelCapable, "unable to find downmix effect");
John Grossman4ff14ba2012-02-08 16:37:41 -08001806}
1807
Andy Hung5e58b0a2014-06-23 19:07:29 -07001808template <int MIXTYPE, int NCHAN, bool USEFLOATVOL, bool ADJUSTVOL,
1809 typename TO, typename TI, typename TA>
1810void AudioMixer::volumeMix(TO *out, size_t outFrames,
1811 const TI *in, TA *aux, bool ramp, AudioMixer::track_t *t)
1812{
1813 if (USEFLOATVOL) {
1814 if (ramp) {
1815 volumeRampMulti<MIXTYPE, NCHAN>(out, outFrames, in, aux,
1816 t->mPrevVolume, t->mVolumeInc, &t->prevAuxLevel, t->auxInc);
1817 if (ADJUSTVOL) {
1818 t->adjustVolumeRamp(aux != NULL, true);
1819 }
1820 } else {
1821 volumeMulti<MIXTYPE, NCHAN>(out, outFrames, in, aux,
1822 t->mVolume, t->auxLevel);
1823 }
1824 } else {
1825 if (ramp) {
1826 volumeRampMulti<MIXTYPE, NCHAN>(out, outFrames, in, aux,
1827 t->prevVolume, t->volumeInc, &t->prevAuxLevel, t->auxInc);
1828 if (ADJUSTVOL) {
1829 t->adjustVolumeRamp(aux != NULL);
1830 }
1831 } else {
1832 volumeMulti<MIXTYPE, NCHAN>(out, outFrames, in, aux,
1833 t->volume, t->auxLevel);
1834 }
1835 }
1836}
1837
Andy Hung296b7412014-06-17 15:25:47 -07001838/* This process hook is called when there is a single track without
1839 * aux buffer, volume ramp, or resampling.
1840 * TODO: Update the hook selection: this can properly handle aux and ramp.
1841 */
1842template <int MIXTYPE, int NCHAN, typename TO, typename TI, typename TA>
1843void AudioMixer::process_NoResampleOneTrack(state_t* state, int64_t pts)
1844{
1845 ALOGVV("process_NoResampleOneTrack\n");
1846 // CLZ is faster than CTZ on ARM, though really not sure if true after 31 - clz.
1847 const int i = 31 - __builtin_clz(state->enabledTracks);
1848 ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
1849 track_t *t = &state->tracks[i];
1850 TO* out = reinterpret_cast<TO*>(t->mainBuffer);
1851 TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
1852 const bool ramp = t->needsRamp();
1853
1854 for (size_t numFrames = state->frameCount; numFrames; ) {
1855 AudioBufferProvider::Buffer& b(t->buffer);
1856 // get input buffer
1857 b.frameCount = numFrames;
1858 const int64_t outputPTS = calculateOutputPTS(*t, pts, state->frameCount - numFrames);
1859 t->bufferProvider->getNextBuffer(&b, outputPTS);
1860 const TI *in = reinterpret_cast<TI*>(b.raw);
1861
1862 // in == NULL can happen if the track was flushed just after having
1863 // been enabled for mixing.
1864 if (in == NULL || (((uintptr_t)in) & 3)) {
1865 memset(out, 0, numFrames
1866 * NCHAN * audio_bytes_per_sample(t->mMixerFormat));
1867 ALOGE_IF((((uintptr_t)in) & 3), "process_NoResampleOneTrack: bus error: "
1868 "buffer %p track %p, channels %d, needs %#x",
1869 in, t, t->channelCount, t->needs);
1870 return;
1871 }
1872
1873 const size_t outFrames = b.frameCount;
Andy Hung5e58b0a2014-06-23 19:07:29 -07001874 volumeMix<MIXTYPE, NCHAN, is_same<TI, float>::value, false> (out,
1875 outFrames, in, aux, ramp, t);
1876
Andy Hung296b7412014-06-17 15:25:47 -07001877 out += outFrames * NCHAN;
1878 if (aux != NULL) {
1879 aux += NCHAN;
1880 }
1881 numFrames -= b.frameCount;
1882
1883 // release buffer
1884 t->bufferProvider->releaseBuffer(&b);
1885 }
1886 if (ramp) {
Andy Hung5e58b0a2014-06-23 19:07:29 -07001887 t->adjustVolumeRamp(aux != NULL, is_same<TI, float>::value);
Andy Hung296b7412014-06-17 15:25:47 -07001888 }
1889}
1890
1891/* This track hook is called to do resampling then mixing,
1892 * pulling from the track's upstream AudioBufferProvider.
1893 */
1894template <int MIXTYPE, int NCHAN, typename TO, typename TI, typename TA>
1895void AudioMixer::track__Resample(track_t* t, TO* out, size_t outFrameCount, TO* temp, TA* aux)
1896{
1897 ALOGVV("track__Resample\n");
1898 t->resampler->setSampleRate(t->sampleRate);
1899
1900 const bool ramp = t->needsRamp();
1901 if (ramp || aux != NULL) {
1902 // if ramp: resample with unity gain to temp buffer and scale/mix in 2nd step.
1903 // if aux != NULL: resample with unity gain to temp buffer then apply send level.
1904
Andy Hung5e58b0a2014-06-23 19:07:29 -07001905 t->resampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
Andy Hung296b7412014-06-17 15:25:47 -07001906 memset(temp, 0, outFrameCount * NCHAN * sizeof(TO));
1907 t->resampler->resample((int32_t*)temp, outFrameCount, t->bufferProvider);
Andy Hung5e58b0a2014-06-23 19:07:29 -07001908
1909 volumeMix<MIXTYPE, NCHAN, is_same<TI, float>::value, true>(out, outFrameCount,
1910 temp, aux, ramp, t);
1911
Andy Hung296b7412014-06-17 15:25:47 -07001912 } else { // constant volume gain
Andy Hung5e58b0a2014-06-23 19:07:29 -07001913 t->resampler->setVolume(t->mVolume[0], t->mVolume[1]);
Andy Hung296b7412014-06-17 15:25:47 -07001914 t->resampler->resample((int32_t*)out, outFrameCount, t->bufferProvider);
1915 }
1916}
1917
1918/* This track hook is called to mix a track, when no resampling is required.
1919 * The input buffer should be present in t->in.
1920 */
1921template <int MIXTYPE, int NCHAN, typename TO, typename TI, typename TA>
1922void AudioMixer::track__NoResample(track_t* t, TO* out, size_t frameCount,
1923 TO* temp __unused, TA* aux)
1924{
1925 ALOGVV("track__NoResample\n");
1926 const TI *in = static_cast<const TI *>(t->in);
1927
Andy Hung5e58b0a2014-06-23 19:07:29 -07001928 volumeMix<MIXTYPE, NCHAN, is_same<TI, float>::value, true>(out, frameCount,
1929 in, aux, t->needsRamp(), t);
1930
Andy Hung296b7412014-06-17 15:25:47 -07001931 // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
1932 // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
1933 in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * NCHAN;
1934 t->in = in;
1935}
1936
1937/* The Mixer engine generates either int32_t (Q4_27) or float data.
1938 * We use this function to convert the engine buffers
1939 * to the desired mixer output format, either int16_t (Q.15) or float.
1940 */
1941void AudioMixer::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
1942 void *in, audio_format_t mixerInFormat, size_t sampleCount)
1943{
1944 switch (mixerInFormat) {
1945 case AUDIO_FORMAT_PCM_FLOAT:
1946 switch (mixerOutFormat) {
1947 case AUDIO_FORMAT_PCM_FLOAT:
1948 memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
1949 break;
1950 case AUDIO_FORMAT_PCM_16_BIT:
1951 memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
1952 break;
1953 default:
1954 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1955 break;
1956 }
1957 break;
1958 case AUDIO_FORMAT_PCM_16_BIT:
1959 switch (mixerOutFormat) {
1960 case AUDIO_FORMAT_PCM_FLOAT:
1961 memcpy_to_float_from_q4_27((float*)out, (int32_t*)in, sampleCount);
1962 break;
1963 case AUDIO_FORMAT_PCM_16_BIT:
1964 // two int16_t are produced per iteration
1965 ditherAndClamp((int32_t*)out, (int32_t*)in, sampleCount >> 1);
1966 break;
1967 default:
1968 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
1969 break;
1970 }
1971 break;
1972 default:
1973 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
1974 break;
1975 }
1976}
1977
1978/* Returns the proper track hook to use for mixing the track into the output buffer.
1979 */
1980AudioMixer::hook_t AudioMixer::getTrackHook(int trackType, int channels,
1981 audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
1982{
1983 if (!kUseNewMixer && channels == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
1984 switch (trackType) {
1985 case TRACKTYPE_NOP:
1986 return track__nop;
1987 case TRACKTYPE_RESAMPLE:
1988 return track__genericResample;
1989 case TRACKTYPE_NORESAMPLEMONO:
1990 return track__16BitsMono;
1991 case TRACKTYPE_NORESAMPLE:
1992 return track__16BitsStereo;
1993 default:
1994 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
1995 break;
1996 }
1997 }
1998 LOG_ALWAYS_FATAL_IF(channels != FCC_2); // TODO: must be stereo right now
1999 switch (trackType) {
2000 case TRACKTYPE_NOP:
2001 return track__nop;
2002 case TRACKTYPE_RESAMPLE:
2003 switch (mixerInFormat) {
2004 case AUDIO_FORMAT_PCM_FLOAT:
2005 return (AudioMixer::hook_t)
2006 track__Resample<MIXTYPE_MULTI, 2, float, float, int32_t>;
2007 case AUDIO_FORMAT_PCM_16_BIT:
2008 return (AudioMixer::hook_t)\
2009 track__Resample<MIXTYPE_MULTI, 2, int32_t, int16_t, int32_t>;
2010 default:
2011 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2012 break;
2013 }
2014 break;
2015 case TRACKTYPE_NORESAMPLEMONO:
2016 switch (mixerInFormat) {
2017 case AUDIO_FORMAT_PCM_FLOAT:
2018 return (AudioMixer::hook_t)
2019 track__NoResample<MIXTYPE_MONOEXPAND, 2, float, float, int32_t>;
2020 case AUDIO_FORMAT_PCM_16_BIT:
2021 return (AudioMixer::hook_t)
2022 track__NoResample<MIXTYPE_MONOEXPAND, 2, int32_t, int16_t, int32_t>;
2023 default:
2024 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2025 break;
2026 }
2027 break;
2028 case TRACKTYPE_NORESAMPLE:
2029 switch (mixerInFormat) {
2030 case AUDIO_FORMAT_PCM_FLOAT:
2031 return (AudioMixer::hook_t)
2032 track__NoResample<MIXTYPE_MULTI, 2, float, float, int32_t>;
2033 case AUDIO_FORMAT_PCM_16_BIT:
2034 return (AudioMixer::hook_t)
2035 track__NoResample<MIXTYPE_MULTI, 2, int32_t, int16_t, int32_t>;
2036 default:
2037 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2038 break;
2039 }
2040 break;
2041 default:
2042 LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
2043 break;
2044 }
2045 return NULL;
2046}
2047
2048/* Returns the proper process hook for mixing tracks. Currently works only for
2049 * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
2050 */
2051AudioMixer::process_hook_t AudioMixer::getProcessHook(int processType, int channels,
2052 audio_format_t mixerInFormat, audio_format_t mixerOutFormat)
2053{
2054 if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
2055 LOG_ALWAYS_FATAL("bad processType: %d", processType);
2056 return NULL;
2057 }
2058 if (!kUseNewMixer && channels == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
2059 return process__OneTrack16BitsStereoNoResampling;
2060 }
2061 LOG_ALWAYS_FATAL_IF(channels != FCC_2); // TODO: must be stereo right now
2062 switch (mixerInFormat) {
2063 case AUDIO_FORMAT_PCM_FLOAT:
2064 switch (mixerOutFormat) {
2065 case AUDIO_FORMAT_PCM_FLOAT:
2066 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY, 2,
2067 float, float, int32_t>;
2068 case AUDIO_FORMAT_PCM_16_BIT:
2069 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY, 2,
2070 int16_t, float, int32_t>;
2071 default:
2072 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2073 break;
2074 }
2075 break;
2076 case AUDIO_FORMAT_PCM_16_BIT:
2077 switch (mixerOutFormat) {
2078 case AUDIO_FORMAT_PCM_FLOAT:
2079 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY, 2,
2080 float, int16_t, int32_t>;
2081 case AUDIO_FORMAT_PCM_16_BIT:
2082 return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY, 2,
2083 int16_t, int16_t, int32_t>;
2084 default:
2085 LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
2086 break;
2087 }
2088 break;
2089 default:
2090 LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
2091 break;
2092 }
2093 return NULL;
2094}
2095
Mathias Agopian65ab4712010-07-14 17:59:35 -07002096// ----------------------------------------------------------------------------
2097}; // namespace android