blob: fe733d9615ecdadd7562ffb1e1346cda42d86934 [file] [log] [blame]
Mathias Agopian65ab4712010-07-14 17:59:35 -07001/* //device/include/server/AudioFlinger/AudioMixer.cpp
2**
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"
19//#define LOG_NDEBUG 0
20
Glenn Kastenfba380a2011-12-15 15:46:46 -080021#include <assert.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070022#include <stdint.h>
23#include <string.h>
24#include <stdlib.h>
25#include <sys/types.h>
26
27#include <utils/Errors.h>
28#include <utils/Log.h>
29
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070030#include <cutils/bitops.h>
Glenn Kastenf6b16782011-12-15 09:51:17 -080031#include <cutils/compiler.h>
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070032
33#include <system/audio.h>
34
Glenn Kasten3b21c502011-12-15 09:52:39 -080035#include <audio_utils/primitives.h>
36
Mathias Agopian65ab4712010-07-14 17:59:35 -070037#include "AudioMixer.h"
38
39namespace android {
Mathias Agopian65ab4712010-07-14 17:59:35 -070040
41// ----------------------------------------------------------------------------
42
43AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate)
Glenn Kasten9c56d4a2011-12-19 15:06:39 -080044 : mTrackNames(0), mSampleRate(sampleRate)
Mathias Agopian65ab4712010-07-14 17:59:35 -070045{
Glenn Kasten788040c2011-05-05 08:19:00 -070046 // AudioMixer is not yet capable of multi-channel beyond stereo
47 assert(2 == MAX_NUM_CHANNELS);
Mathias Agopian65ab4712010-07-14 17:59:35 -070048 mState.enabledTracks= 0;
49 mState.needsChanged = 0;
50 mState.frameCount = frameCount;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080051 mState.hook = process__nop;
Glenn Kastene0feee32011-12-13 11:53:26 -080052 mState.outputTemp = NULL;
53 mState.resampleTemp = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080054 // mState.reserved
Mathias Agopian65ab4712010-07-14 17:59:35 -070055 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -080056 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -070057 t->needs = 0;
58 t->volume[0] = UNITY_GAIN;
59 t->volume[1] = UNITY_GAIN;
Glenn Kasten0cfd8232011-12-13 11:58:23 -080060 // no initialization needed
61 // t->prevVolume[0]
62 // t->prevVolume[1]
Mathias Agopian65ab4712010-07-14 17:59:35 -070063 t->volumeInc[0] = 0;
64 t->volumeInc[1] = 0;
65 t->auxLevel = 0;
66 t->auxInc = 0;
Glenn Kasten0cfd8232011-12-13 11:58:23 -080067 // no initialization needed
68 // t->prevAuxLevel
69 // t->frameCount
Mathias Agopian65ab4712010-07-14 17:59:35 -070070 t->channelCount = 2;
71 t->enabled = 0;
72 t->format = 16;
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070073 t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
Glenn Kastene0feee32011-12-13 11:53:26 -080074 t->bufferProvider = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080075 t->buffer.raw = NULL;
76 // t->buffer.frameCount
Glenn Kastene0feee32011-12-13 11:53:26 -080077 t->hook = NULL;
Glenn Kasten84afa3b2012-01-25 15:28:08 -080078 t->in = NULL;
Glenn Kastene0feee32011-12-13 11:53:26 -080079 t->resampler = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -070080 t->sampleRate = mSampleRate;
Mathias Agopian65ab4712010-07-14 17:59:35 -070081 t->mainBuffer = NULL;
82 t->auxBuffer = NULL;
83 t++;
84 }
85}
86
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080087AudioMixer::~AudioMixer()
88{
89 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -080090 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080091 delete t->resampler;
92 t++;
93 }
94 delete [] mState.outputTemp;
95 delete [] mState.resampleTemp;
96}
Mathias Agopian65ab4712010-07-14 17:59:35 -070097
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080098int AudioMixer::getTrackName()
99{
Glenn Kasten98dd5422011-12-15 14:38:29 -0800100 uint32_t names = ~mTrackNames;
101 if (names != 0) {
102 int n = __builtin_ctz(names);
Steve Block3856b092011-10-20 11:56:00 +0100103 ALOGV("add track (%d)", n);
Glenn Kasten98dd5422011-12-15 14:38:29 -0800104 mTrackNames |= 1 << n;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700105 return TRACK0 + n;
106 }
107 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800108}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700109
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800110void AudioMixer::invalidateState(uint32_t mask)
111{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700112 if (mask) {
113 mState.needsChanged |= mask;
114 mState.hook = process__validate;
115 }
116 }
117
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800118void AudioMixer::deleteTrackName(int name)
119{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700120 name -= TRACK0;
Glenn Kasten237a6242011-12-15 15:32:27 -0800121 assert(uint32_t(name) < MAX_NUM_TRACKS);
122 ALOGV("deleteTrackName(%d)", name);
123 track_t& track(mState.tracks[ name ]);
124 if (track.enabled != 0) {
125 track.enabled = 0;
126 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700127 }
Glenn Kastena0d68332012-01-27 16:47:15 -0800128 if (track.resampler != NULL) {
Glenn Kasten237a6242011-12-15 15:32:27 -0800129 // delete the resampler
130 delete track.resampler;
131 track.resampler = NULL;
132 track.sampleRate = mSampleRate;
133 invalidateState(1<<name);
134 }
135 track.volumeInc[0] = 0;
136 track.volumeInc[1] = 0;
137 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800138}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700139
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800140void AudioMixer::enable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700141{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800142 name -= TRACK0;
143 assert(uint32_t(name) < MAX_NUM_TRACKS);
144 track_t& track = mState.tracks[name];
145
146 if (track.enabled != 1) {
147 track.enabled = 1;
148 ALOGV("enable(%d)", name);
149 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700150 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700151}
152
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800153void AudioMixer::disable(int name)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700154{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800155 name -= TRACK0;
156 assert(uint32_t(name) < MAX_NUM_TRACKS);
157 track_t& track = mState.tracks[name];
158
159 if (track.enabled != 0) {
160 track.enabled = 0;
161 ALOGV("disable(%d)", name);
162 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700163 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700164}
165
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800166void AudioMixer::setParameter(int name, int target, int param, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700167{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800168 name -= TRACK0;
169 assert(uint32_t(name) < MAX_NUM_TRACKS);
170 track_t& track = mState.tracks[name];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700171
Mathias Agopian65ab4712010-07-14 17:59:35 -0700172 int valueInt = (int)value;
173 int32_t *valueBuf = (int32_t *)value;
174
175 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700176
Mathias Agopian65ab4712010-07-14 17:59:35 -0700177 case TRACK:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800178 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700179 case CHANNEL_MASK: {
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -0700180 uint32_t mask = (uint32_t)value;
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800181 if (track.channelMask != mask) {
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -0700182 uint8_t channelCount = popcount(mask);
Glenn Kasten788040c2011-05-05 08:19:00 -0700183 assert((channelCount <= MAX_NUM_CHANNELS) && (channelCount));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800184 track.channelMask = mask;
185 track.channelCount = channelCount;
Glenn Kasten788040c2011-05-05 08:19:00 -0700186 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800187 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700188 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700189 } break;
190 case MAIN_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800191 if (track.mainBuffer != valueBuf) {
192 track.mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100193 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800194 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700195 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700196 break;
197 case AUX_BUFFER:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800198 if (track.auxBuffer != valueBuf) {
199 track.auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100200 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800201 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700202 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700203 break;
204 default:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800205 // bad param
Glenn Kasten788040c2011-05-05 08:19:00 -0700206 assert(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700207 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700208 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700209
Mathias Agopian65ab4712010-07-14 17:59:35 -0700210 case RESAMPLE:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800211 switch (param) {
212 case SAMPLE_RATE:
Glenn Kasten788040c2011-05-05 08:19:00 -0700213 assert(valueInt > 0);
Glenn Kasten788040c2011-05-05 08:19:00 -0700214 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
215 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
216 uint32_t(valueInt));
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800217 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700218 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800219 break;
220 case RESET:
Eric Laurent243f5f92011-02-28 16:52:51 -0800221 track.resetResampler();
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800222 invalidateState(1 << name);
223 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700224 default:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800225 // bad param
Glenn Kasten788040c2011-05-05 08:19:00 -0700226 assert(false);
Eric Laurent243f5f92011-02-28 16:52:51 -0800227 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700228 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700229
Mathias Agopian65ab4712010-07-14 17:59:35 -0700230 case RAMP_VOLUME:
231 case VOLUME:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800232 switch (param) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700233 case VOLUME0:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800234 case VOLUME1:
235 if (track.volume[param-VOLUME0] != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100236 ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800237 track.prevVolume[param-VOLUME0] = track.volume[param-VOLUME0] << 16;
238 track.volume[param-VOLUME0] = valueInt;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700239 if (target == VOLUME) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800240 track.prevVolume[param-VOLUME0] = valueInt << 16;
241 track.volumeInc[param-VOLUME0] = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700242 } else {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800243 int32_t d = (valueInt<<16) - track.prevVolume[param-VOLUME0];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700244 int32_t volInc = d / int32_t(mState.frameCount);
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800245 track.volumeInc[param-VOLUME0] = volInc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700246 if (volInc == 0) {
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800247 track.prevVolume[param-VOLUME0] = valueInt << 16;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700248 }
249 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800250 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700251 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800252 break;
253 case AUXLEVEL:
Mathias Agopian65ab4712010-07-14 17:59:35 -0700254 if (track.auxLevel != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100255 ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700256 track.prevAuxLevel = track.auxLevel << 16;
257 track.auxLevel = valueInt;
258 if (target == VOLUME) {
259 track.prevAuxLevel = valueInt << 16;
260 track.auxInc = 0;
261 } else {
262 int32_t d = (valueInt<<16) - track.prevAuxLevel;
263 int32_t volInc = d / int32_t(mState.frameCount);
264 track.auxInc = volInc;
265 if (volInc == 0) {
266 track.prevAuxLevel = valueInt << 16;
267 }
268 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800269 invalidateState(1 << name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700270 }
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800271 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700272 default:
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800273 // bad param
Glenn Kasten788040c2011-05-05 08:19:00 -0700274 assert(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700275 }
276 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700277
278 default:
279 // bad target
280 assert(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700281 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700282}
283
284bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
285{
286 if (value!=devSampleRate || resampler) {
287 if (sampleRate != value) {
288 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800289 if (resampler == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700290 resampler = AudioResampler::create(
291 format, channelCount, devSampleRate);
292 }
293 return true;
294 }
295 }
296 return false;
297}
298
Mathias Agopian65ab4712010-07-14 17:59:35 -0700299inline
300void AudioMixer::track_t::adjustVolumeRamp(bool aux)
301{
Glenn Kastenf9a27772012-01-06 07:47:26 -0800302 for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700303 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
304 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
305 volumeInc[i] = 0;
306 prevVolume[i] = volume[i]<<16;
307 }
308 }
309 if (aux) {
310 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
311 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
312 auxInc = 0;
313 prevAuxLevel = auxLevel<<16;
314 }
315 }
316}
317
Glenn Kastenc59c0042012-02-02 14:06:11 -0800318size_t AudioMixer::getUnreleasedFrames(int name) const
Eric Laurent071ccd52011-12-22 16:08:41 -0800319{
320 name -= TRACK0;
321 if (uint32_t(name) < MAX_NUM_TRACKS) {
Glenn Kastenc59c0042012-02-02 14:06:11 -0800322 return mState.tracks[name].getUnreleasedFrames();
Eric Laurent071ccd52011-12-22 16:08:41 -0800323 }
324 return 0;
325}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700326
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800327void AudioMixer::setBufferProvider(int name, AudioBufferProvider* buffer)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700328{
Glenn Kasten9c56d4a2011-12-19 15:06:39 -0800329 name -= TRACK0;
330 assert(uint32_t(name) < MAX_NUM_TRACKS);
331 mState.tracks[name].bufferProvider = buffer;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700332}
333
334
335
336void AudioMixer::process()
337{
338 mState.hook(&mState);
339}
340
341
342void AudioMixer::process__validate(state_t* state)
343{
Steve Block5ff1dd52012-01-05 23:22:43 +0000344 ALOGW_IF(!state->needsChanged,
Mathias Agopian65ab4712010-07-14 17:59:35 -0700345 "in process__validate() but nothing's invalid");
346
347 uint32_t changed = state->needsChanged;
348 state->needsChanged = 0; // clear the validation flag
349
350 // recompute which tracks are enabled / disabled
351 uint32_t enabled = 0;
352 uint32_t disabled = 0;
353 while (changed) {
354 const int i = 31 - __builtin_clz(changed);
355 const uint32_t mask = 1<<i;
356 changed &= ~mask;
357 track_t& t = state->tracks[i];
358 (t.enabled ? enabled : disabled) |= mask;
359 }
360 state->enabledTracks &= ~disabled;
361 state->enabledTracks |= enabled;
362
363 // compute everything we need...
364 int countActiveTracks = 0;
365 int all16BitsStereoNoResample = 1;
366 int resampling = 0;
367 int volumeRamp = 0;
368 uint32_t en = state->enabledTracks;
369 while (en) {
370 const int i = 31 - __builtin_clz(en);
371 en &= ~(1<<i);
372
373 countActiveTracks++;
374 track_t& t = state->tracks[i];
375 uint32_t n = 0;
376 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
377 n |= NEEDS_FORMAT_16;
378 n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
379 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
380 n |= NEEDS_AUX_ENABLED;
381 }
382
383 if (t.volumeInc[0]|t.volumeInc[1]) {
384 volumeRamp = 1;
385 } else if (!t.doesResample() && t.volumeRL == 0) {
386 n |= NEEDS_MUTE_ENABLED;
387 }
388 t.needs = n;
389
390 if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
391 t.hook = track__nop;
392 } else {
393 if ((n & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
394 all16BitsStereoNoResample = 0;
395 }
396 if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
397 all16BitsStereoNoResample = 0;
398 resampling = 1;
399 t.hook = track__genericResample;
400 } else {
401 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
402 t.hook = track__16BitsMono;
403 all16BitsStereoNoResample = 0;
404 }
405 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
406 t.hook = track__16BitsStereo;
407 }
408 }
409 }
410 }
411
412 // select the processing hooks
413 state->hook = process__nop;
414 if (countActiveTracks) {
415 if (resampling) {
416 if (!state->outputTemp) {
417 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
418 }
419 if (!state->resampleTemp) {
420 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
421 }
422 state->hook = process__genericResampling;
423 } else {
424 if (state->outputTemp) {
425 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800426 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700427 }
428 if (state->resampleTemp) {
429 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800430 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700431 }
432 state->hook = process__genericNoResampling;
433 if (all16BitsStereoNoResample && !volumeRamp) {
434 if (countActiveTracks == 1) {
435 state->hook = process__OneTrack16BitsStereoNoResampling;
436 }
437 }
438 }
439 }
440
Steve Block3856b092011-10-20 11:56:00 +0100441 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700442 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
443 countActiveTracks, state->enabledTracks,
444 all16BitsStereoNoResample, resampling, volumeRamp);
445
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800446 state->hook(state);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700447
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800448 // Now that the volume ramp has been done, set optimal state and
449 // track hooks for subsequent mixer process
450 if (countActiveTracks) {
451 int allMuted = 1;
452 uint32_t en = state->enabledTracks;
453 while (en) {
454 const int i = 31 - __builtin_clz(en);
455 en &= ~(1<<i);
456 track_t& t = state->tracks[i];
457 if (!t.doesResample() && t.volumeRL == 0)
458 {
459 t.needs |= NEEDS_MUTE_ENABLED;
460 t.hook = track__nop;
461 } else {
462 allMuted = 0;
463 }
464 }
465 if (allMuted) {
466 state->hook = process__nop;
467 } else if (all16BitsStereoNoResample) {
468 if (countActiveTracks == 1) {
469 state->hook = process__OneTrack16BitsStereoNoResampling;
470 }
471 }
472 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700473}
474
Mathias Agopian65ab4712010-07-14 17:59:35 -0700475
476void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
477{
478 t->resampler->setSampleRate(t->sampleRate);
479
480 // ramp gain - resample to temp buffer and scale/mix in 2nd step
481 if (aux != NULL) {
482 // always resample with unity gain when sending to auxiliary buffer to be able
483 // to apply send level after resampling
484 // TODO: modify each resampler to support aux channel?
485 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
486 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
487 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -0800488 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700489 volumeRampStereo(t, out, outFrameCount, temp, aux);
490 } else {
491 volumeStereo(t, out, outFrameCount, temp, aux);
492 }
493 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -0800494 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700495 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
496 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
497 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
498 volumeRampStereo(t, out, outFrameCount, temp, aux);
499 }
500
501 // constant gain
502 else {
503 t->resampler->setVolume(t->volume[0], t->volume[1]);
504 t->resampler->resample(out, outFrameCount, t->bufferProvider);
505 }
506 }
507}
508
509void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
510{
511}
512
513void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
514{
515 int32_t vl = t->prevVolume[0];
516 int32_t vr = t->prevVolume[1];
517 const int32_t vlInc = t->volumeInc[0];
518 const int32_t vrInc = t->volumeInc[1];
519
Steve Blockb8a80522011-12-20 16:23:08 +0000520 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700521 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
522 // (vl + vlInc*frameCount)/65536.0f, frameCount);
523
524 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -0800525 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700526 int32_t va = t->prevAuxLevel;
527 const int32_t vaInc = t->auxInc;
528 int32_t l;
529 int32_t r;
530
531 do {
532 l = (*temp++ >> 12);
533 r = (*temp++ >> 12);
534 *out++ += (vl >> 16) * l;
535 *out++ += (vr >> 16) * r;
536 *aux++ += (va >> 17) * (l + r);
537 vl += vlInc;
538 vr += vrInc;
539 va += vaInc;
540 } while (--frameCount);
541 t->prevAuxLevel = va;
542 } else {
543 do {
544 *out++ += (vl >> 16) * (*temp++ >> 12);
545 *out++ += (vr >> 16) * (*temp++ >> 12);
546 vl += vlInc;
547 vr += vrInc;
548 } while (--frameCount);
549 }
550 t->prevVolume[0] = vl;
551 t->prevVolume[1] = vr;
552 t->adjustVolumeRamp((aux != NULL));
553}
554
555void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
556{
557 const int16_t vl = t->volume[0];
558 const int16_t vr = t->volume[1];
559
Glenn Kastenf6b16782011-12-15 09:51:17 -0800560 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700561 const int16_t va = (int16_t)t->auxLevel;
562 do {
563 int16_t l = (int16_t)(*temp++ >> 12);
564 int16_t r = (int16_t)(*temp++ >> 12);
565 out[0] = mulAdd(l, vl, out[0]);
566 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
567 out[1] = mulAdd(r, vr, out[1]);
568 out += 2;
569 aux[0] = mulAdd(a, va, aux[0]);
570 aux++;
571 } while (--frameCount);
572 } else {
573 do {
574 int16_t l = (int16_t)(*temp++ >> 12);
575 int16_t r = (int16_t)(*temp++ >> 12);
576 out[0] = mulAdd(l, vl, out[0]);
577 out[1] = mulAdd(r, vr, out[1]);
578 out += 2;
579 } while (--frameCount);
580 }
581}
582
583void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
584{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800585 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700586
Glenn Kastenf6b16782011-12-15 09:51:17 -0800587 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700588 int32_t l;
589 int32_t r;
590 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800591 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700592 int32_t vl = t->prevVolume[0];
593 int32_t vr = t->prevVolume[1];
594 int32_t va = t->prevAuxLevel;
595 const int32_t vlInc = t->volumeInc[0];
596 const int32_t vrInc = t->volumeInc[1];
597 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +0000598 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700599 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
600 // (vl + vlInc*frameCount)/65536.0f, frameCount);
601
602 do {
603 l = (int32_t)*in++;
604 r = (int32_t)*in++;
605 *out++ += (vl >> 16) * l;
606 *out++ += (vr >> 16) * r;
607 *aux++ += (va >> 17) * (l + r);
608 vl += vlInc;
609 vr += vrInc;
610 va += vaInc;
611 } while (--frameCount);
612
613 t->prevVolume[0] = vl;
614 t->prevVolume[1] = vr;
615 t->prevAuxLevel = va;
616 t->adjustVolumeRamp(true);
617 }
618
619 // constant gain
620 else {
621 const uint32_t vrl = t->volumeRL;
622 const int16_t va = (int16_t)t->auxLevel;
623 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800624 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700625 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
626 in += 2;
627 out[0] = mulAddRL(1, rl, vrl, out[0]);
628 out[1] = mulAddRL(0, rl, vrl, out[1]);
629 out += 2;
630 aux[0] = mulAdd(a, va, aux[0]);
631 aux++;
632 } while (--frameCount);
633 }
634 } else {
635 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800636 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700637 int32_t vl = t->prevVolume[0];
638 int32_t vr = t->prevVolume[1];
639 const int32_t vlInc = t->volumeInc[0];
640 const int32_t vrInc = t->volumeInc[1];
641
Steve Blockb8a80522011-12-20 16:23:08 +0000642 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700643 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
644 // (vl + vlInc*frameCount)/65536.0f, frameCount);
645
646 do {
647 *out++ += (vl >> 16) * (int32_t) *in++;
648 *out++ += (vr >> 16) * (int32_t) *in++;
649 vl += vlInc;
650 vr += vrInc;
651 } while (--frameCount);
652
653 t->prevVolume[0] = vl;
654 t->prevVolume[1] = vr;
655 t->adjustVolumeRamp(false);
656 }
657
658 // constant gain
659 else {
660 const uint32_t vrl = t->volumeRL;
661 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800662 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700663 in += 2;
664 out[0] = mulAddRL(1, rl, vrl, out[0]);
665 out[1] = mulAddRL(0, rl, vrl, out[1]);
666 out += 2;
667 } while (--frameCount);
668 }
669 }
670 t->in = in;
671}
672
673void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
674{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800675 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700676
Glenn Kastenf6b16782011-12-15 09:51:17 -0800677 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700678 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800679 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700680 int32_t vl = t->prevVolume[0];
681 int32_t vr = t->prevVolume[1];
682 int32_t va = t->prevAuxLevel;
683 const int32_t vlInc = t->volumeInc[0];
684 const int32_t vrInc = t->volumeInc[1];
685 const int32_t vaInc = t->auxInc;
686
Steve Blockb8a80522011-12-20 16:23:08 +0000687 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700688 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
689 // (vl + vlInc*frameCount)/65536.0f, frameCount);
690
691 do {
692 int32_t l = *in++;
693 *out++ += (vl >> 16) * l;
694 *out++ += (vr >> 16) * l;
695 *aux++ += (va >> 16) * l;
696 vl += vlInc;
697 vr += vrInc;
698 va += vaInc;
699 } while (--frameCount);
700
701 t->prevVolume[0] = vl;
702 t->prevVolume[1] = vr;
703 t->prevAuxLevel = va;
704 t->adjustVolumeRamp(true);
705 }
706 // constant gain
707 else {
708 const int16_t vl = t->volume[0];
709 const int16_t vr = t->volume[1];
710 const int16_t va = (int16_t)t->auxLevel;
711 do {
712 int16_t l = *in++;
713 out[0] = mulAdd(l, vl, out[0]);
714 out[1] = mulAdd(l, vr, out[1]);
715 out += 2;
716 aux[0] = mulAdd(l, va, aux[0]);
717 aux++;
718 } while (--frameCount);
719 }
720 } else {
721 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800722 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700723 int32_t vl = t->prevVolume[0];
724 int32_t vr = t->prevVolume[1];
725 const int32_t vlInc = t->volumeInc[0];
726 const int32_t vrInc = t->volumeInc[1];
727
Steve Blockb8a80522011-12-20 16:23:08 +0000728 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700729 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
730 // (vl + vlInc*frameCount)/65536.0f, frameCount);
731
732 do {
733 int32_t l = *in++;
734 *out++ += (vl >> 16) * l;
735 *out++ += (vr >> 16) * l;
736 vl += vlInc;
737 vr += vrInc;
738 } while (--frameCount);
739
740 t->prevVolume[0] = vl;
741 t->prevVolume[1] = vr;
742 t->adjustVolumeRamp(false);
743 }
744 // constant gain
745 else {
746 const int16_t vl = t->volume[0];
747 const int16_t vr = t->volume[1];
748 do {
749 int16_t l = *in++;
750 out[0] = mulAdd(l, vl, out[0]);
751 out[1] = mulAdd(l, vr, out[1]);
752 out += 2;
753 } while (--frameCount);
754 }
755 }
756 t->in = in;
757}
758
Mathias Agopian65ab4712010-07-14 17:59:35 -0700759// no-op case
760void AudioMixer::process__nop(state_t* state)
761{
762 uint32_t e0 = state->enabledTracks;
763 size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS;
764 while (e0) {
765 // process by group of tracks with same output buffer to
766 // avoid multiple memset() on same buffer
767 uint32_t e1 = e0, e2 = e0;
768 int i = 31 - __builtin_clz(e1);
769 track_t& t1 = state->tracks[i];
770 e2 &= ~(1<<i);
771 while (e2) {
772 i = 31 - __builtin_clz(e2);
773 e2 &= ~(1<<i);
774 track_t& t2 = state->tracks[i];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800775 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700776 e1 &= ~(1<<i);
777 }
778 }
779 e0 &= ~(e1);
780
781 memset(t1.mainBuffer, 0, bufSize);
782
783 while (e1) {
784 i = 31 - __builtin_clz(e1);
785 e1 &= ~(1<<i);
786 t1 = state->tracks[i];
787 size_t outFrames = state->frameCount;
788 while (outFrames) {
789 t1.buffer.frameCount = outFrames;
790 t1.bufferProvider->getNextBuffer(&t1.buffer);
Glenn Kastena0d68332012-01-27 16:47:15 -0800791 if (t1.buffer.raw == NULL) break;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700792 outFrames -= t1.buffer.frameCount;
793 t1.bufferProvider->releaseBuffer(&t1.buffer);
794 }
795 }
796 }
797}
798
799// generic code without resampling
800void AudioMixer::process__genericNoResampling(state_t* state)
801{
802 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
803
804 // acquire each track's buffer
805 uint32_t enabledTracks = state->enabledTracks;
806 uint32_t e0 = enabledTracks;
807 while (e0) {
808 const int i = 31 - __builtin_clz(e0);
809 e0 &= ~(1<<i);
810 track_t& t = state->tracks[i];
811 t.buffer.frameCount = state->frameCount;
812 t.bufferProvider->getNextBuffer(&t.buffer);
813 t.frameCount = t.buffer.frameCount;
814 t.in = t.buffer.raw;
815 // t.in == NULL can happen if the track was flushed just after having
816 // been enabled for mixing.
817 if (t.in == NULL)
818 enabledTracks &= ~(1<<i);
819 }
820
821 e0 = enabledTracks;
822 while (e0) {
823 // process by group of tracks with same output buffer to
824 // optimize cache use
825 uint32_t e1 = e0, e2 = e0;
826 int j = 31 - __builtin_clz(e1);
827 track_t& t1 = state->tracks[j];
828 e2 &= ~(1<<j);
829 while (e2) {
830 j = 31 - __builtin_clz(e2);
831 e2 &= ~(1<<j);
832 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800833 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700834 e1 &= ~(1<<j);
835 }
836 }
837 e0 &= ~(e1);
838 // this assumes output 16 bits stereo, no resampling
839 int32_t *out = t1.mainBuffer;
840 size_t numFrames = 0;
841 do {
842 memset(outTemp, 0, sizeof(outTemp));
843 e2 = e1;
844 while (e2) {
845 const int i = 31 - __builtin_clz(e2);
846 e2 &= ~(1<<i);
847 track_t& t = state->tracks[i];
848 size_t outFrames = BLOCKSIZE;
849 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800850 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700851 aux = t.auxBuffer + numFrames;
852 }
853 while (outFrames) {
854 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
855 if (inFrames) {
856 (t.hook)(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux);
857 t.frameCount -= inFrames;
858 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800859 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700860 aux += inFrames;
861 }
862 }
863 if (t.frameCount == 0 && outFrames) {
864 t.bufferProvider->releaseBuffer(&t.buffer);
865 t.buffer.frameCount = (state->frameCount - numFrames) - (BLOCKSIZE - outFrames);
866 t.bufferProvider->getNextBuffer(&t.buffer);
867 t.in = t.buffer.raw;
868 if (t.in == NULL) {
869 enabledTracks &= ~(1<<i);
870 e1 &= ~(1<<i);
871 break;
872 }
873 t.frameCount = t.buffer.frameCount;
874 }
875 }
876 }
877 ditherAndClamp(out, outTemp, BLOCKSIZE);
878 out += BLOCKSIZE;
879 numFrames += BLOCKSIZE;
880 } while (numFrames < state->frameCount);
881 }
882
883 // release each track's buffer
884 e0 = enabledTracks;
885 while (e0) {
886 const int i = 31 - __builtin_clz(e0);
887 e0 &= ~(1<<i);
888 track_t& t = state->tracks[i];
889 t.bufferProvider->releaseBuffer(&t.buffer);
890 }
891}
892
893
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800894// generic code with resampling
Mathias Agopian65ab4712010-07-14 17:59:35 -0700895void AudioMixer::process__genericResampling(state_t* state)
896{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800897 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -0700898 int32_t* const outTemp = state->outputTemp;
899 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700900
901 size_t numFrames = state->frameCount;
902
903 uint32_t e0 = state->enabledTracks;
904 while (e0) {
905 // process by group of tracks with same output buffer
906 // to optimize cache use
907 uint32_t e1 = e0, e2 = e0;
908 int j = 31 - __builtin_clz(e1);
909 track_t& t1 = state->tracks[j];
910 e2 &= ~(1<<j);
911 while (e2) {
912 j = 31 - __builtin_clz(e2);
913 e2 &= ~(1<<j);
914 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800915 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700916 e1 &= ~(1<<j);
917 }
918 }
919 e0 &= ~(e1);
920 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +0100921 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700922 while (e1) {
923 const int i = 31 - __builtin_clz(e1);
924 e1 &= ~(1<<i);
925 track_t& t = state->tracks[i];
926 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800927 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700928 aux = t.auxBuffer;
929 }
930
931 // this is a little goofy, on the resampling case we don't
932 // acquire/release the buffers because it's done by
933 // the resampler.
934 if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
935 (t.hook)(&t, outTemp, numFrames, state->resampleTemp, aux);
936 } else {
937
938 size_t outFrames = 0;
939
940 while (outFrames < numFrames) {
941 t.buffer.frameCount = numFrames - outFrames;
942 t.bufferProvider->getNextBuffer(&t.buffer);
943 t.in = t.buffer.raw;
944 // t.in == NULL can happen if the track was flushed just after having
945 // been enabled for mixing.
946 if (t.in == NULL) break;
947
Glenn Kastenf6b16782011-12-15 09:51:17 -0800948 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700949 aux += outFrames;
950 }
951 (t.hook)(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
952 outFrames += t.buffer.frameCount;
953 t.bufferProvider->releaseBuffer(&t.buffer);
954 }
955 }
956 }
957 ditherAndClamp(out, outTemp, numFrames);
958 }
959}
960
961// one track, 16 bits stereo without resampling is the most common case
962void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state)
963{
964 const int i = 31 - __builtin_clz(state->enabledTracks);
965 const track_t& t = state->tracks[i];
966
967 AudioBufferProvider::Buffer& b(t.buffer);
968
969 int32_t* out = t.mainBuffer;
970 size_t numFrames = state->frameCount;
971
972 const int16_t vl = t.volume[0];
973 const int16_t vr = t.volume[1];
974 const uint32_t vrl = t.volumeRL;
975 while (numFrames) {
976 b.frameCount = numFrames;
977 t.bufferProvider->getNextBuffer(&b);
Glenn Kasten54c3b662012-01-06 07:46:30 -0800978 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700979
980 // in == NULL can happen if the track was flushed just after having
981 // been enabled for mixing.
982 if (in == NULL || ((unsigned long)in & 3)) {
983 memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
Steve Block29357bc2012-01-06 19:20:56 +0000984 ALOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: buffer %p track %d, channels %d, needs %08x",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700985 in, i, t.channelCount, t.needs);
986 return;
987 }
988 size_t outFrames = b.frameCount;
989
Glenn Kastenf6b16782011-12-15 09:51:17 -0800990 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700991 // volume is boosted, so we might need to clamp even though
992 // we process only one track.
993 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800994 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700995 in += 2;
996 int32_t l = mulRL(1, rl, vrl) >> 12;
997 int32_t r = mulRL(0, rl, vrl) >> 12;
998 // clamping...
999 l = clamp16(l);
1000 r = clamp16(r);
1001 *out++ = (r<<16) | (l & 0xFFFF);
1002 } while (--outFrames);
1003 } else {
1004 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001005 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001006 in += 2;
1007 int32_t l = mulRL(1, rl, vrl) >> 12;
1008 int32_t r = mulRL(0, rl, vrl) >> 12;
1009 *out++ = (r<<16) | (l & 0xFFFF);
1010 } while (--outFrames);
1011 }
1012 numFrames -= b.frameCount;
1013 t.bufferProvider->releaseBuffer(&b);
1014 }
1015}
1016
Glenn Kasten81a028f2011-12-15 09:53:12 -08001017#if 0
Mathias Agopian65ab4712010-07-14 17:59:35 -07001018// 2 tracks is also a common case
1019// NEVER used in current implementation of process__validate()
1020// only use if the 2 tracks have the same output buffer
1021void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state)
1022{
1023 int i;
1024 uint32_t en = state->enabledTracks;
1025
1026 i = 31 - __builtin_clz(en);
1027 const track_t& t0 = state->tracks[i];
1028 AudioBufferProvider::Buffer& b0(t0.buffer);
1029
1030 en &= ~(1<<i);
1031 i = 31 - __builtin_clz(en);
1032 const track_t& t1 = state->tracks[i];
1033 AudioBufferProvider::Buffer& b1(t1.buffer);
1034
Glenn Kasten54c3b662012-01-06 07:46:30 -08001035 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001036 const int16_t vl0 = t0.volume[0];
1037 const int16_t vr0 = t0.volume[1];
1038 size_t frameCount0 = 0;
1039
Glenn Kasten54c3b662012-01-06 07:46:30 -08001040 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001041 const int16_t vl1 = t1.volume[0];
1042 const int16_t vr1 = t1.volume[1];
1043 size_t frameCount1 = 0;
1044
1045 //FIXME: only works if two tracks use same buffer
1046 int32_t* out = t0.mainBuffer;
1047 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001048 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001049
1050
1051 while (numFrames) {
1052
1053 if (frameCount0 == 0) {
1054 b0.frameCount = numFrames;
1055 t0.bufferProvider->getNextBuffer(&b0);
1056 if (b0.i16 == NULL) {
1057 if (buff == NULL) {
1058 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1059 }
1060 in0 = buff;
1061 b0.frameCount = numFrames;
1062 } else {
1063 in0 = b0.i16;
1064 }
1065 frameCount0 = b0.frameCount;
1066 }
1067 if (frameCount1 == 0) {
1068 b1.frameCount = numFrames;
1069 t1.bufferProvider->getNextBuffer(&b1);
1070 if (b1.i16 == NULL) {
1071 if (buff == NULL) {
1072 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1073 }
1074 in1 = buff;
1075 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001076 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001077 in1 = b1.i16;
1078 }
1079 frameCount1 = b1.frameCount;
1080 }
1081
1082 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1083
1084 numFrames -= outFrames;
1085 frameCount0 -= outFrames;
1086 frameCount1 -= outFrames;
1087
1088 do {
1089 int32_t l0 = *in0++;
1090 int32_t r0 = *in0++;
1091 l0 = mul(l0, vl0);
1092 r0 = mul(r0, vr0);
1093 int32_t l = *in1++;
1094 int32_t r = *in1++;
1095 l = mulAdd(l, vl1, l0) >> 12;
1096 r = mulAdd(r, vr1, r0) >> 12;
1097 // clamping...
1098 l = clamp16(l);
1099 r = clamp16(r);
1100 *out++ = (r<<16) | (l & 0xFFFF);
1101 } while (--outFrames);
1102
1103 if (frameCount0 == 0) {
1104 t0.bufferProvider->releaseBuffer(&b0);
1105 }
1106 if (frameCount1 == 0) {
1107 t1.bufferProvider->releaseBuffer(&b1);
1108 }
1109 }
1110
Glenn Kastene9dd0172012-01-27 18:08:45 -08001111 delete [] buff;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001112}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001113#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001114
1115// ----------------------------------------------------------------------------
1116}; // namespace android