blob: 977726f197a076d3ec081a0369501bdb05ef053b [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)
44 : mActiveTrack(0), mTrackNames(0), mSampleRate(sampleRate)
45{
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 Kastene0feee32011-12-13 11:53:26 -080051 mState.outputTemp = NULL;
52 mState.resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -070053 mState.hook = process__nop;
54 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -080055 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -070056 t->needs = 0;
57 t->volume[0] = UNITY_GAIN;
58 t->volume[1] = UNITY_GAIN;
Glenn Kasten0cfd8232011-12-13 11:58:23 -080059 // no initialization needed
60 // t->prevVolume[0]
61 // t->prevVolume[1]
Mathias Agopian65ab4712010-07-14 17:59:35 -070062 t->volumeInc[0] = 0;
63 t->volumeInc[1] = 0;
64 t->auxLevel = 0;
65 t->auxInc = 0;
Glenn Kasten0cfd8232011-12-13 11:58:23 -080066 // no initialization needed
67 // t->prevAuxLevel
68 // t->frameCount
Mathias Agopian65ab4712010-07-14 17:59:35 -070069 t->channelCount = 2;
70 t->enabled = 0;
71 t->format = 16;
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070072 t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
Mathias Agopian65ab4712010-07-14 17:59:35 -070073 t->buffer.raw = 0;
Glenn Kastene0feee32011-12-13 11:53:26 -080074 t->bufferProvider = NULL;
75 t->hook = NULL;
76 t->resampler = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -070077 t->sampleRate = mSampleRate;
Glenn Kastene0feee32011-12-13 11:53:26 -080078 t->in = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -070079 t->mainBuffer = NULL;
80 t->auxBuffer = NULL;
81 t++;
82 }
83}
84
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080085AudioMixer::~AudioMixer()
86{
87 track_t* t = mState.tracks;
Glenn Kastenbf71f1e2011-12-13 11:52:35 -080088 for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080089 delete t->resampler;
90 t++;
91 }
92 delete [] mState.outputTemp;
93 delete [] mState.resampleTemp;
94}
Mathias Agopian65ab4712010-07-14 17:59:35 -070095
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -080096int AudioMixer::getTrackName()
97{
Mathias Agopian65ab4712010-07-14 17:59:35 -070098 uint32_t names = mTrackNames;
99 uint32_t mask = 1;
100 int n = 0;
101 while (names & mask) {
102 mask <<= 1;
103 n++;
104 }
105 if (mask) {
Steve Block3856b092011-10-20 11:56:00 +0100106 ALOGV("add track (%d)", n);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700107 mTrackNames |= mask;
108 return TRACK0 + n;
109 }
110 return -1;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800111}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700112
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800113void AudioMixer::invalidateState(uint32_t mask)
114{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700115 if (mask) {
116 mState.needsChanged |= mask;
117 mState.hook = process__validate;
118 }
119 }
120
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800121void AudioMixer::deleteTrackName(int name)
122{
Mathias Agopian65ab4712010-07-14 17:59:35 -0700123 name -= TRACK0;
Glenn Kasten237a6242011-12-15 15:32:27 -0800124 assert(uint32_t(name) < MAX_NUM_TRACKS);
125 ALOGV("deleteTrackName(%d)", name);
126 track_t& track(mState.tracks[ name ]);
127 if (track.enabled != 0) {
128 track.enabled = 0;
129 invalidateState(1<<name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700130 }
Glenn Kasten237a6242011-12-15 15:32:27 -0800131 if (track.resampler) {
132 // delete the resampler
133 delete track.resampler;
134 track.resampler = NULL;
135 track.sampleRate = mSampleRate;
136 invalidateState(1<<name);
137 }
138 track.volumeInc[0] = 0;
139 track.volumeInc[1] = 0;
140 mTrackNames &= ~(1<<name);
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800141}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700142
Glenn Kasten1c48c3c2011-12-15 14:54:01 -0800143void AudioMixer::enable()
Mathias Agopian65ab4712010-07-14 17:59:35 -0700144{
Glenn Kasten1c48c3c2011-12-15 14:54:01 -0800145 if (mState.tracks[ mActiveTrack ].enabled != 1) {
146 mState.tracks[ mActiveTrack ].enabled = 1;
147 ALOGV("enable(%d)", mActiveTrack);
148 invalidateState(1<<mActiveTrack);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700149 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700150}
151
Glenn Kasten1c48c3c2011-12-15 14:54:01 -0800152void AudioMixer::disable()
Mathias Agopian65ab4712010-07-14 17:59:35 -0700153{
Glenn Kasten1c48c3c2011-12-15 14:54:01 -0800154 if (mState.tracks[ mActiveTrack ].enabled != 0) {
155 mState.tracks[ mActiveTrack ].enabled = 0;
156 ALOGV("disable(%d)", mActiveTrack);
157 invalidateState(1<<mActiveTrack);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700158 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700159}
160
Glenn Kastenfba380a2011-12-15 15:46:46 -0800161void AudioMixer::setActiveTrack(int track)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700162{
Glenn Kastenfba380a2011-12-15 15:46:46 -0800163 // this also catches track < TRACK0
164 track -= TRACK0;
165 assert(uint32_t(track) < MAX_NUM_TRACKS);
166 mActiveTrack = track;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700167}
168
Glenn Kasten788040c2011-05-05 08:19:00 -0700169void AudioMixer::setParameter(int target, int name, void *value)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700170{
171 int valueInt = (int)value;
172 int32_t *valueBuf = (int32_t *)value;
173
174 switch (target) {
Glenn Kasten788040c2011-05-05 08:19:00 -0700175
Mathias Agopian65ab4712010-07-14 17:59:35 -0700176 case TRACK:
Glenn Kasten788040c2011-05-05 08:19:00 -0700177 switch (name) {
178 case CHANNEL_MASK: {
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -0700179 uint32_t mask = (uint32_t)value;
180 if (mState.tracks[ mActiveTrack ].channelMask != mask) {
181 uint8_t channelCount = popcount(mask);
Glenn Kasten788040c2011-05-05 08:19:00 -0700182 assert((channelCount <= MAX_NUM_CHANNELS) && (channelCount));
183 mState.tracks[ mActiveTrack ].channelMask = mask;
184 mState.tracks[ mActiveTrack ].channelCount = channelCount;
185 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
186 invalidateState(1<<mActiveTrack);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700187 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700188 } break;
189 case MAIN_BUFFER:
Mathias Agopian65ab4712010-07-14 17:59:35 -0700190 if (mState.tracks[ mActiveTrack ].mainBuffer != valueBuf) {
191 mState.tracks[ mActiveTrack ].mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100192 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700193 invalidateState(1<<mActiveTrack);
194 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700195 break;
196 case AUX_BUFFER:
Mathias Agopian65ab4712010-07-14 17:59:35 -0700197 if (mState.tracks[ mActiveTrack ].auxBuffer != valueBuf) {
198 mState.tracks[ mActiveTrack ].auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100199 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700200 invalidateState(1<<mActiveTrack);
201 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700202 break;
203 default:
204 // bad name
205 assert(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700206 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700207 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700208
Mathias Agopian65ab4712010-07-14 17:59:35 -0700209 case RESAMPLE:
Glenn Kasten788040c2011-05-05 08:19:00 -0700210 switch (name) {
211 case SAMPLE_RATE: {
212 assert(valueInt > 0);
213 track_t& track = mState.tracks[ mActiveTrack ];
214 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
215 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
216 uint32_t(valueInt));
217 invalidateState(1<<mActiveTrack);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700218 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700219 } break;
220 case RESET: {
Eric Laurent243f5f92011-02-28 16:52:51 -0800221 track_t& track = mState.tracks[ mActiveTrack ];
222 track.resetResampler();
223 invalidateState(1<<mActiveTrack);
Glenn Kasten788040c2011-05-05 08:19:00 -0700224 } break;
225 default:
226 // bad name
227 assert(false);
Eric Laurent243f5f92011-02-28 16:52:51 -0800228 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700229 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700230
Mathias Agopian65ab4712010-07-14 17:59:35 -0700231 case RAMP_VOLUME:
232 case VOLUME:
Glenn Kasten788040c2011-05-05 08:19:00 -0700233 switch (name) {
234 case VOLUME0:
235 case VOLUME1: {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700236 track_t& track = mState.tracks[ mActiveTrack ];
237 if (track.volume[name-VOLUME0] != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100238 ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700239 track.prevVolume[name-VOLUME0] = track.volume[name-VOLUME0] << 16;
240 track.volume[name-VOLUME0] = valueInt;
241 if (target == VOLUME) {
242 track.prevVolume[name-VOLUME0] = valueInt << 16;
243 track.volumeInc[name-VOLUME0] = 0;
244 } else {
245 int32_t d = (valueInt<<16) - track.prevVolume[name-VOLUME0];
246 int32_t volInc = d / int32_t(mState.frameCount);
247 track.volumeInc[name-VOLUME0] = volInc;
248 if (volInc == 0) {
249 track.prevVolume[name-VOLUME0] = valueInt << 16;
250 }
251 }
252 invalidateState(1<<mActiveTrack);
253 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700254 } break;
255 case AUXLEVEL: {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700256 track_t& track = mState.tracks[ mActiveTrack ];
257 if (track.auxLevel != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100258 ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700259 track.prevAuxLevel = track.auxLevel << 16;
260 track.auxLevel = valueInt;
261 if (target == VOLUME) {
262 track.prevAuxLevel = valueInt << 16;
263 track.auxInc = 0;
264 } else {
265 int32_t d = (valueInt<<16) - track.prevAuxLevel;
266 int32_t volInc = d / int32_t(mState.frameCount);
267 track.auxInc = volInc;
268 if (volInc == 0) {
269 track.prevAuxLevel = valueInt << 16;
270 }
271 }
272 invalidateState(1<<mActiveTrack);
273 }
Glenn Kasten788040c2011-05-05 08:19:00 -0700274 } break;
275 default:
276 // bad name
277 assert(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700278 }
279 break;
Glenn Kasten788040c2011-05-05 08:19:00 -0700280
281 default:
282 // bad target
283 assert(false);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700284 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700285}
286
287bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
288{
289 if (value!=devSampleRate || resampler) {
290 if (sampleRate != value) {
291 sampleRate = value;
Glenn Kastene0feee32011-12-13 11:53:26 -0800292 if (resampler == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700293 resampler = AudioResampler::create(
294 format, channelCount, devSampleRate);
295 }
296 return true;
297 }
298 }
299 return false;
300}
301
302bool AudioMixer::track_t::doesResample() const
303{
Glenn Kastene0feee32011-12-13 11:53:26 -0800304 return resampler != NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700305}
306
Eric Laurent243f5f92011-02-28 16:52:51 -0800307void AudioMixer::track_t::resetResampler()
308{
Glenn Kastene0feee32011-12-13 11:53:26 -0800309 if (resampler != NULL) {
Eric Laurent243f5f92011-02-28 16:52:51 -0800310 resampler->reset();
311 }
312}
313
Mathias Agopian65ab4712010-07-14 17:59:35 -0700314inline
315void AudioMixer::track_t::adjustVolumeRamp(bool aux)
316{
Glenn Kastenbf71f1e2011-12-13 11:52:35 -0800317 for (int i=0 ; i<MAX_NUM_CHANNELS ; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700318 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
319 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
320 volumeInc[i] = 0;
321 prevVolume[i] = volume[i]<<16;
322 }
323 }
324 if (aux) {
325 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
326 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
327 auxInc = 0;
328 prevAuxLevel = auxLevel<<16;
329 }
330 }
331}
332
Eric Laurent071ccd52011-12-22 16:08:41 -0800333size_t AudioMixer::track_t::getUnreleasedFrames()
334{
335 if (resampler != NULL) {
336 return resampler->getUnreleasedFrames();
337 }
338 return 0;
339}
340
341size_t AudioMixer::getUnreleasedFrames(int name)
342{
343 name -= TRACK0;
344 if (uint32_t(name) < MAX_NUM_TRACKS) {
345 track_t& track(mState.tracks[name]);
346 return track.getUnreleasedFrames();
347 }
348 return 0;
349}
Mathias Agopian65ab4712010-07-14 17:59:35 -0700350
Glenn Kastenfba380a2011-12-15 15:46:46 -0800351void AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700352{
353 mState.tracks[ mActiveTrack ].bufferProvider = buffer;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700354}
355
356
357
358void AudioMixer::process()
359{
360 mState.hook(&mState);
361}
362
363
364void AudioMixer::process__validate(state_t* state)
365{
366 LOGW_IF(!state->needsChanged,
367 "in process__validate() but nothing's invalid");
368
369 uint32_t changed = state->needsChanged;
370 state->needsChanged = 0; // clear the validation flag
371
372 // recompute which tracks are enabled / disabled
373 uint32_t enabled = 0;
374 uint32_t disabled = 0;
375 while (changed) {
376 const int i = 31 - __builtin_clz(changed);
377 const uint32_t mask = 1<<i;
378 changed &= ~mask;
379 track_t& t = state->tracks[i];
380 (t.enabled ? enabled : disabled) |= mask;
381 }
382 state->enabledTracks &= ~disabled;
383 state->enabledTracks |= enabled;
384
385 // compute everything we need...
386 int countActiveTracks = 0;
387 int all16BitsStereoNoResample = 1;
388 int resampling = 0;
389 int volumeRamp = 0;
390 uint32_t en = state->enabledTracks;
391 while (en) {
392 const int i = 31 - __builtin_clz(en);
393 en &= ~(1<<i);
394
395 countActiveTracks++;
396 track_t& t = state->tracks[i];
397 uint32_t n = 0;
398 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
399 n |= NEEDS_FORMAT_16;
400 n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
401 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
402 n |= NEEDS_AUX_ENABLED;
403 }
404
405 if (t.volumeInc[0]|t.volumeInc[1]) {
406 volumeRamp = 1;
407 } else if (!t.doesResample() && t.volumeRL == 0) {
408 n |= NEEDS_MUTE_ENABLED;
409 }
410 t.needs = n;
411
412 if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
413 t.hook = track__nop;
414 } else {
415 if ((n & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
416 all16BitsStereoNoResample = 0;
417 }
418 if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
419 all16BitsStereoNoResample = 0;
420 resampling = 1;
421 t.hook = track__genericResample;
422 } else {
423 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
424 t.hook = track__16BitsMono;
425 all16BitsStereoNoResample = 0;
426 }
427 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
428 t.hook = track__16BitsStereo;
429 }
430 }
431 }
432 }
433
434 // select the processing hooks
435 state->hook = process__nop;
436 if (countActiveTracks) {
437 if (resampling) {
438 if (!state->outputTemp) {
439 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
440 }
441 if (!state->resampleTemp) {
442 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
443 }
444 state->hook = process__genericResampling;
445 } else {
446 if (state->outputTemp) {
447 delete [] state->outputTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800448 state->outputTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700449 }
450 if (state->resampleTemp) {
451 delete [] state->resampleTemp;
Glenn Kastene0feee32011-12-13 11:53:26 -0800452 state->resampleTemp = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700453 }
454 state->hook = process__genericNoResampling;
455 if (all16BitsStereoNoResample && !volumeRamp) {
456 if (countActiveTracks == 1) {
457 state->hook = process__OneTrack16BitsStereoNoResampling;
458 }
459 }
460 }
461 }
462
Steve Block3856b092011-10-20 11:56:00 +0100463 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700464 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
465 countActiveTracks, state->enabledTracks,
466 all16BitsStereoNoResample, resampling, volumeRamp);
467
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800468 state->hook(state);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700469
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800470 // Now that the volume ramp has been done, set optimal state and
471 // track hooks for subsequent mixer process
472 if (countActiveTracks) {
473 int allMuted = 1;
474 uint32_t en = state->enabledTracks;
475 while (en) {
476 const int i = 31 - __builtin_clz(en);
477 en &= ~(1<<i);
478 track_t& t = state->tracks[i];
479 if (!t.doesResample() && t.volumeRL == 0)
480 {
481 t.needs |= NEEDS_MUTE_ENABLED;
482 t.hook = track__nop;
483 } else {
484 allMuted = 0;
485 }
486 }
487 if (allMuted) {
488 state->hook = process__nop;
489 } else if (all16BitsStereoNoResample) {
490 if (countActiveTracks == 1) {
491 state->hook = process__OneTrack16BitsStereoNoResampling;
492 }
493 }
494 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700495}
496
Mathias Agopian65ab4712010-07-14 17:59:35 -0700497
498void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
499{
500 t->resampler->setSampleRate(t->sampleRate);
501
502 // ramp gain - resample to temp buffer and scale/mix in 2nd step
503 if (aux != NULL) {
504 // always resample with unity gain when sending to auxiliary buffer to be able
505 // to apply send level after resampling
506 // TODO: modify each resampler to support aux channel?
507 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
508 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
509 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
Glenn Kastenf6b16782011-12-15 09:51:17 -0800510 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700511 volumeRampStereo(t, out, outFrameCount, temp, aux);
512 } else {
513 volumeStereo(t, out, outFrameCount, temp, aux);
514 }
515 } else {
Glenn Kastenf6b16782011-12-15 09:51:17 -0800516 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700517 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
518 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
519 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
520 volumeRampStereo(t, out, outFrameCount, temp, aux);
521 }
522
523 // constant gain
524 else {
525 t->resampler->setVolume(t->volume[0], t->volume[1]);
526 t->resampler->resample(out, outFrameCount, t->bufferProvider);
527 }
528 }
529}
530
531void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
532{
533}
534
535void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
536{
537 int32_t vl = t->prevVolume[0];
538 int32_t vr = t->prevVolume[1];
539 const int32_t vlInc = t->volumeInc[0];
540 const int32_t vrInc = t->volumeInc[1];
541
Steve Blockb8a80522011-12-20 16:23:08 +0000542 //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700543 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
544 // (vl + vlInc*frameCount)/65536.0f, frameCount);
545
546 // ramp volume
Glenn Kastenf6b16782011-12-15 09:51:17 -0800547 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700548 int32_t va = t->prevAuxLevel;
549 const int32_t vaInc = t->auxInc;
550 int32_t l;
551 int32_t r;
552
553 do {
554 l = (*temp++ >> 12);
555 r = (*temp++ >> 12);
556 *out++ += (vl >> 16) * l;
557 *out++ += (vr >> 16) * r;
558 *aux++ += (va >> 17) * (l + r);
559 vl += vlInc;
560 vr += vrInc;
561 va += vaInc;
562 } while (--frameCount);
563 t->prevAuxLevel = va;
564 } else {
565 do {
566 *out++ += (vl >> 16) * (*temp++ >> 12);
567 *out++ += (vr >> 16) * (*temp++ >> 12);
568 vl += vlInc;
569 vr += vrInc;
570 } while (--frameCount);
571 }
572 t->prevVolume[0] = vl;
573 t->prevVolume[1] = vr;
574 t->adjustVolumeRamp((aux != NULL));
575}
576
577void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
578{
579 const int16_t vl = t->volume[0];
580 const int16_t vr = t->volume[1];
581
Glenn Kastenf6b16782011-12-15 09:51:17 -0800582 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700583 const int16_t va = (int16_t)t->auxLevel;
584 do {
585 int16_t l = (int16_t)(*temp++ >> 12);
586 int16_t r = (int16_t)(*temp++ >> 12);
587 out[0] = mulAdd(l, vl, out[0]);
588 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
589 out[1] = mulAdd(r, vr, out[1]);
590 out += 2;
591 aux[0] = mulAdd(a, va, aux[0]);
592 aux++;
593 } while (--frameCount);
594 } else {
595 do {
596 int16_t l = (int16_t)(*temp++ >> 12);
597 int16_t r = (int16_t)(*temp++ >> 12);
598 out[0] = mulAdd(l, vl, out[0]);
599 out[1] = mulAdd(r, vr, out[1]);
600 out += 2;
601 } while (--frameCount);
602 }
603}
604
605void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
606{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800607 const int16_t *in = static_cast<const int16_t *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700608
Glenn Kastenf6b16782011-12-15 09:51:17 -0800609 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700610 int32_t l;
611 int32_t r;
612 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800613 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700614 int32_t vl = t->prevVolume[0];
615 int32_t vr = t->prevVolume[1];
616 int32_t va = t->prevAuxLevel;
617 const int32_t vlInc = t->volumeInc[0];
618 const int32_t vrInc = t->volumeInc[1];
619 const int32_t vaInc = t->auxInc;
Steve Blockb8a80522011-12-20 16:23:08 +0000620 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700621 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
622 // (vl + vlInc*frameCount)/65536.0f, frameCount);
623
624 do {
625 l = (int32_t)*in++;
626 r = (int32_t)*in++;
627 *out++ += (vl >> 16) * l;
628 *out++ += (vr >> 16) * r;
629 *aux++ += (va >> 17) * (l + r);
630 vl += vlInc;
631 vr += vrInc;
632 va += vaInc;
633 } while (--frameCount);
634
635 t->prevVolume[0] = vl;
636 t->prevVolume[1] = vr;
637 t->prevAuxLevel = va;
638 t->adjustVolumeRamp(true);
639 }
640
641 // constant gain
642 else {
643 const uint32_t vrl = t->volumeRL;
644 const int16_t va = (int16_t)t->auxLevel;
645 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800646 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700647 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
648 in += 2;
649 out[0] = mulAddRL(1, rl, vrl, out[0]);
650 out[1] = mulAddRL(0, rl, vrl, out[1]);
651 out += 2;
652 aux[0] = mulAdd(a, va, aux[0]);
653 aux++;
654 } while (--frameCount);
655 }
656 } else {
657 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800658 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700659 int32_t vl = t->prevVolume[0];
660 int32_t vr = t->prevVolume[1];
661 const int32_t vlInc = t->volumeInc[0];
662 const int32_t vrInc = t->volumeInc[1];
663
Steve Blockb8a80522011-12-20 16:23:08 +0000664 // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700665 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
666 // (vl + vlInc*frameCount)/65536.0f, frameCount);
667
668 do {
669 *out++ += (vl >> 16) * (int32_t) *in++;
670 *out++ += (vr >> 16) * (int32_t) *in++;
671 vl += vlInc;
672 vr += vrInc;
673 } while (--frameCount);
674
675 t->prevVolume[0] = vl;
676 t->prevVolume[1] = vr;
677 t->adjustVolumeRamp(false);
678 }
679
680 // constant gain
681 else {
682 const uint32_t vrl = t->volumeRL;
683 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -0800684 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700685 in += 2;
686 out[0] = mulAddRL(1, rl, vrl, out[0]);
687 out[1] = mulAddRL(0, rl, vrl, out[1]);
688 out += 2;
689 } while (--frameCount);
690 }
691 }
692 t->in = in;
693}
694
695void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
696{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800697 const int16_t *in = static_cast<int16_t const *>(t->in);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700698
Glenn Kastenf6b16782011-12-15 09:51:17 -0800699 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700700 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800701 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700702 int32_t vl = t->prevVolume[0];
703 int32_t vr = t->prevVolume[1];
704 int32_t va = t->prevAuxLevel;
705 const int32_t vlInc = t->volumeInc[0];
706 const int32_t vrInc = t->volumeInc[1];
707 const int32_t vaInc = t->auxInc;
708
Steve Blockb8a80522011-12-20 16:23:08 +0000709 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700710 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
711 // (vl + vlInc*frameCount)/65536.0f, frameCount);
712
713 do {
714 int32_t l = *in++;
715 *out++ += (vl >> 16) * l;
716 *out++ += (vr >> 16) * l;
717 *aux++ += (va >> 16) * l;
718 vl += vlInc;
719 vr += vrInc;
720 va += vaInc;
721 } while (--frameCount);
722
723 t->prevVolume[0] = vl;
724 t->prevVolume[1] = vr;
725 t->prevAuxLevel = va;
726 t->adjustVolumeRamp(true);
727 }
728 // constant gain
729 else {
730 const int16_t vl = t->volume[0];
731 const int16_t vr = t->volume[1];
732 const int16_t va = (int16_t)t->auxLevel;
733 do {
734 int16_t l = *in++;
735 out[0] = mulAdd(l, vl, out[0]);
736 out[1] = mulAdd(l, vr, out[1]);
737 out += 2;
738 aux[0] = mulAdd(l, va, aux[0]);
739 aux++;
740 } while (--frameCount);
741 }
742 } else {
743 // ramp gain
Glenn Kastenf6b16782011-12-15 09:51:17 -0800744 if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700745 int32_t vl = t->prevVolume[0];
746 int32_t vr = t->prevVolume[1];
747 const int32_t vlInc = t->volumeInc[0];
748 const int32_t vrInc = t->volumeInc[1];
749
Steve Blockb8a80522011-12-20 16:23:08 +0000750 // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700751 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
752 // (vl + vlInc*frameCount)/65536.0f, frameCount);
753
754 do {
755 int32_t l = *in++;
756 *out++ += (vl >> 16) * l;
757 *out++ += (vr >> 16) * l;
758 vl += vlInc;
759 vr += vrInc;
760 } while (--frameCount);
761
762 t->prevVolume[0] = vl;
763 t->prevVolume[1] = vr;
764 t->adjustVolumeRamp(false);
765 }
766 // constant gain
767 else {
768 const int16_t vl = t->volume[0];
769 const int16_t vr = t->volume[1];
770 do {
771 int16_t l = *in++;
772 out[0] = mulAdd(l, vl, out[0]);
773 out[1] = mulAdd(l, vr, out[1]);
774 out += 2;
775 } while (--frameCount);
776 }
777 }
778 t->in = in;
779}
780
Mathias Agopian65ab4712010-07-14 17:59:35 -0700781// no-op case
782void AudioMixer::process__nop(state_t* state)
783{
784 uint32_t e0 = state->enabledTracks;
785 size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS;
786 while (e0) {
787 // process by group of tracks with same output buffer to
788 // avoid multiple memset() on same buffer
789 uint32_t e1 = e0, e2 = e0;
790 int i = 31 - __builtin_clz(e1);
791 track_t& t1 = state->tracks[i];
792 e2 &= ~(1<<i);
793 while (e2) {
794 i = 31 - __builtin_clz(e2);
795 e2 &= ~(1<<i);
796 track_t& t2 = state->tracks[i];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800797 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700798 e1 &= ~(1<<i);
799 }
800 }
801 e0 &= ~(e1);
802
803 memset(t1.mainBuffer, 0, bufSize);
804
805 while (e1) {
806 i = 31 - __builtin_clz(e1);
807 e1 &= ~(1<<i);
808 t1 = state->tracks[i];
809 size_t outFrames = state->frameCount;
810 while (outFrames) {
811 t1.buffer.frameCount = outFrames;
812 t1.bufferProvider->getNextBuffer(&t1.buffer);
813 if (!t1.buffer.raw) break;
814 outFrames -= t1.buffer.frameCount;
815 t1.bufferProvider->releaseBuffer(&t1.buffer);
816 }
817 }
818 }
819}
820
821// generic code without resampling
822void AudioMixer::process__genericNoResampling(state_t* state)
823{
824 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
825
826 // acquire each track's buffer
827 uint32_t enabledTracks = state->enabledTracks;
828 uint32_t e0 = enabledTracks;
829 while (e0) {
830 const int i = 31 - __builtin_clz(e0);
831 e0 &= ~(1<<i);
832 track_t& t = state->tracks[i];
833 t.buffer.frameCount = state->frameCount;
834 t.bufferProvider->getNextBuffer(&t.buffer);
835 t.frameCount = t.buffer.frameCount;
836 t.in = t.buffer.raw;
837 // t.in == NULL can happen if the track was flushed just after having
838 // been enabled for mixing.
839 if (t.in == NULL)
840 enabledTracks &= ~(1<<i);
841 }
842
843 e0 = enabledTracks;
844 while (e0) {
845 // process by group of tracks with same output buffer to
846 // optimize cache use
847 uint32_t e1 = e0, e2 = e0;
848 int j = 31 - __builtin_clz(e1);
849 track_t& t1 = state->tracks[j];
850 e2 &= ~(1<<j);
851 while (e2) {
852 j = 31 - __builtin_clz(e2);
853 e2 &= ~(1<<j);
854 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800855 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700856 e1 &= ~(1<<j);
857 }
858 }
859 e0 &= ~(e1);
860 // this assumes output 16 bits stereo, no resampling
861 int32_t *out = t1.mainBuffer;
862 size_t numFrames = 0;
863 do {
864 memset(outTemp, 0, sizeof(outTemp));
865 e2 = e1;
866 while (e2) {
867 const int i = 31 - __builtin_clz(e2);
868 e2 &= ~(1<<i);
869 track_t& t = state->tracks[i];
870 size_t outFrames = BLOCKSIZE;
871 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800872 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700873 aux = t.auxBuffer + numFrames;
874 }
875 while (outFrames) {
876 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
877 if (inFrames) {
878 (t.hook)(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux);
879 t.frameCount -= inFrames;
880 outFrames -= inFrames;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800881 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700882 aux += inFrames;
883 }
884 }
885 if (t.frameCount == 0 && outFrames) {
886 t.bufferProvider->releaseBuffer(&t.buffer);
887 t.buffer.frameCount = (state->frameCount - numFrames) - (BLOCKSIZE - outFrames);
888 t.bufferProvider->getNextBuffer(&t.buffer);
889 t.in = t.buffer.raw;
890 if (t.in == NULL) {
891 enabledTracks &= ~(1<<i);
892 e1 &= ~(1<<i);
893 break;
894 }
895 t.frameCount = t.buffer.frameCount;
896 }
897 }
898 }
899 ditherAndClamp(out, outTemp, BLOCKSIZE);
900 out += BLOCKSIZE;
901 numFrames += BLOCKSIZE;
902 } while (numFrames < state->frameCount);
903 }
904
905 // release each track's buffer
906 e0 = enabledTracks;
907 while (e0) {
908 const int i = 31 - __builtin_clz(e0);
909 e0 &= ~(1<<i);
910 track_t& t = state->tracks[i];
911 t.bufferProvider->releaseBuffer(&t.buffer);
912 }
913}
914
915
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -0800916// generic code with resampling
Mathias Agopian65ab4712010-07-14 17:59:35 -0700917void AudioMixer::process__genericResampling(state_t* state)
918{
Glenn Kasten54c3b662012-01-06 07:46:30 -0800919 // this const just means that local variable outTemp doesn't change
Mathias Agopian65ab4712010-07-14 17:59:35 -0700920 int32_t* const outTemp = state->outputTemp;
921 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700922
923 size_t numFrames = state->frameCount;
924
925 uint32_t e0 = state->enabledTracks;
926 while (e0) {
927 // process by group of tracks with same output buffer
928 // to optimize cache use
929 uint32_t e1 = e0, e2 = e0;
930 int j = 31 - __builtin_clz(e1);
931 track_t& t1 = state->tracks[j];
932 e2 &= ~(1<<j);
933 while (e2) {
934 j = 31 - __builtin_clz(e2);
935 e2 &= ~(1<<j);
936 track_t& t2 = state->tracks[j];
Glenn Kastenf6b16782011-12-15 09:51:17 -0800937 if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700938 e1 &= ~(1<<j);
939 }
940 }
941 e0 &= ~(e1);
942 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +0100943 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700944 while (e1) {
945 const int i = 31 - __builtin_clz(e1);
946 e1 &= ~(1<<i);
947 track_t& t = state->tracks[i];
948 int32_t *aux = NULL;
Glenn Kastenf6b16782011-12-15 09:51:17 -0800949 if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700950 aux = t.auxBuffer;
951 }
952
953 // this is a little goofy, on the resampling case we don't
954 // acquire/release the buffers because it's done by
955 // the resampler.
956 if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
957 (t.hook)(&t, outTemp, numFrames, state->resampleTemp, aux);
958 } else {
959
960 size_t outFrames = 0;
961
962 while (outFrames < numFrames) {
963 t.buffer.frameCount = numFrames - outFrames;
964 t.bufferProvider->getNextBuffer(&t.buffer);
965 t.in = t.buffer.raw;
966 // t.in == NULL can happen if the track was flushed just after having
967 // been enabled for mixing.
968 if (t.in == NULL) break;
969
Glenn Kastenf6b16782011-12-15 09:51:17 -0800970 if (CC_UNLIKELY(aux != NULL)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700971 aux += outFrames;
972 }
973 (t.hook)(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
974 outFrames += t.buffer.frameCount;
975 t.bufferProvider->releaseBuffer(&t.buffer);
976 }
977 }
978 }
979 ditherAndClamp(out, outTemp, numFrames);
980 }
981}
982
983// one track, 16 bits stereo without resampling is the most common case
984void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state)
985{
986 const int i = 31 - __builtin_clz(state->enabledTracks);
987 const track_t& t = state->tracks[i];
988
989 AudioBufferProvider::Buffer& b(t.buffer);
990
991 int32_t* out = t.mainBuffer;
992 size_t numFrames = state->frameCount;
993
994 const int16_t vl = t.volume[0];
995 const int16_t vr = t.volume[1];
996 const uint32_t vrl = t.volumeRL;
997 while (numFrames) {
998 b.frameCount = numFrames;
999 t.bufferProvider->getNextBuffer(&b);
Glenn Kasten54c3b662012-01-06 07:46:30 -08001000 const int16_t *in = b.i16;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001001
1002 // in == NULL can happen if the track was flushed just after having
1003 // been enabled for mixing.
1004 if (in == NULL || ((unsigned long)in & 3)) {
1005 memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
1006 LOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: buffer %p track %d, channels %d, needs %08x",
1007 in, i, t.channelCount, t.needs);
1008 return;
1009 }
1010 size_t outFrames = b.frameCount;
1011
Glenn Kastenf6b16782011-12-15 09:51:17 -08001012 if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001013 // volume is boosted, so we might need to clamp even though
1014 // we process only one track.
1015 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001016 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001017 in += 2;
1018 int32_t l = mulRL(1, rl, vrl) >> 12;
1019 int32_t r = mulRL(0, rl, vrl) >> 12;
1020 // clamping...
1021 l = clamp16(l);
1022 r = clamp16(r);
1023 *out++ = (r<<16) | (l & 0xFFFF);
1024 } while (--outFrames);
1025 } else {
1026 do {
Glenn Kasten54c3b662012-01-06 07:46:30 -08001027 uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001028 in += 2;
1029 int32_t l = mulRL(1, rl, vrl) >> 12;
1030 int32_t r = mulRL(0, rl, vrl) >> 12;
1031 *out++ = (r<<16) | (l & 0xFFFF);
1032 } while (--outFrames);
1033 }
1034 numFrames -= b.frameCount;
1035 t.bufferProvider->releaseBuffer(&b);
1036 }
1037}
1038
Glenn Kasten81a028f2011-12-15 09:53:12 -08001039#if 0
Mathias Agopian65ab4712010-07-14 17:59:35 -07001040// 2 tracks is also a common case
1041// NEVER used in current implementation of process__validate()
1042// only use if the 2 tracks have the same output buffer
1043void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state)
1044{
1045 int i;
1046 uint32_t en = state->enabledTracks;
1047
1048 i = 31 - __builtin_clz(en);
1049 const track_t& t0 = state->tracks[i];
1050 AudioBufferProvider::Buffer& b0(t0.buffer);
1051
1052 en &= ~(1<<i);
1053 i = 31 - __builtin_clz(en);
1054 const track_t& t1 = state->tracks[i];
1055 AudioBufferProvider::Buffer& b1(t1.buffer);
1056
Glenn Kasten54c3b662012-01-06 07:46:30 -08001057 const int16_t *in0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001058 const int16_t vl0 = t0.volume[0];
1059 const int16_t vr0 = t0.volume[1];
1060 size_t frameCount0 = 0;
1061
Glenn Kasten54c3b662012-01-06 07:46:30 -08001062 const int16_t *in1;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001063 const int16_t vl1 = t1.volume[0];
1064 const int16_t vr1 = t1.volume[1];
1065 size_t frameCount1 = 0;
1066
1067 //FIXME: only works if two tracks use same buffer
1068 int32_t* out = t0.mainBuffer;
1069 size_t numFrames = state->frameCount;
Glenn Kasten54c3b662012-01-06 07:46:30 -08001070 const int16_t *buff = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001071
1072
1073 while (numFrames) {
1074
1075 if (frameCount0 == 0) {
1076 b0.frameCount = numFrames;
1077 t0.bufferProvider->getNextBuffer(&b0);
1078 if (b0.i16 == NULL) {
1079 if (buff == NULL) {
1080 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1081 }
1082 in0 = buff;
1083 b0.frameCount = numFrames;
1084 } else {
1085 in0 = b0.i16;
1086 }
1087 frameCount0 = b0.frameCount;
1088 }
1089 if (frameCount1 == 0) {
1090 b1.frameCount = numFrames;
1091 t1.bufferProvider->getNextBuffer(&b1);
1092 if (b1.i16 == NULL) {
1093 if (buff == NULL) {
1094 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1095 }
1096 in1 = buff;
1097 b1.frameCount = numFrames;
Glenn Kastenc5ac4cb2011-12-12 09:05:55 -08001098 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001099 in1 = b1.i16;
1100 }
1101 frameCount1 = b1.frameCount;
1102 }
1103
1104 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1105
1106 numFrames -= outFrames;
1107 frameCount0 -= outFrames;
1108 frameCount1 -= outFrames;
1109
1110 do {
1111 int32_t l0 = *in0++;
1112 int32_t r0 = *in0++;
1113 l0 = mul(l0, vl0);
1114 r0 = mul(r0, vr0);
1115 int32_t l = *in1++;
1116 int32_t r = *in1++;
1117 l = mulAdd(l, vl1, l0) >> 12;
1118 r = mulAdd(r, vr1, r0) >> 12;
1119 // clamping...
1120 l = clamp16(l);
1121 r = clamp16(r);
1122 *out++ = (r<<16) | (l & 0xFFFF);
1123 } while (--outFrames);
1124
1125 if (frameCount0 == 0) {
1126 t0.bufferProvider->releaseBuffer(&b0);
1127 }
1128 if (frameCount1 == 0) {
1129 t1.bufferProvider->releaseBuffer(&b1);
1130 }
1131 }
1132
1133 if (buff != NULL) {
1134 delete [] buff;
1135 }
1136}
Glenn Kasten81a028f2011-12-15 09:53:12 -08001137#endif
Mathias Agopian65ab4712010-07-14 17:59:35 -07001138
1139// ----------------------------------------------------------------------------
1140}; // namespace android