blob: 74db59e6f6adc6d5e7025945deecf56cfb0f58be [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>
31
32#include <system/audio.h>
33
Mathias Agopian65ab4712010-07-14 17:59:35 -070034#include "AudioMixer.h"
35
36namespace android {
37// ----------------------------------------------------------------------------
38
39static inline int16_t clamp16(int32_t sample)
40{
41 if ((sample>>15) ^ (sample>>31))
42 sample = 0x7FFF ^ (sample>>31);
43 return sample;
44}
45
46// ----------------------------------------------------------------------------
47
48AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate)
49 : mActiveTrack(0), mTrackNames(0), mSampleRate(sampleRate)
50{
51 mState.enabledTracks= 0;
52 mState.needsChanged = 0;
53 mState.frameCount = frameCount;
54 mState.outputTemp = 0;
55 mState.resampleTemp = 0;
56 mState.hook = process__nop;
57 track_t* t = mState.tracks;
58 for (int i=0 ; i<32 ; i++) {
59 t->needs = 0;
60 t->volume[0] = UNITY_GAIN;
61 t->volume[1] = UNITY_GAIN;
62 t->volumeInc[0] = 0;
63 t->volumeInc[1] = 0;
64 t->auxLevel = 0;
65 t->auxInc = 0;
66 t->channelCount = 2;
67 t->enabled = 0;
68 t->format = 16;
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -070069 t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
Mathias Agopian65ab4712010-07-14 17:59:35 -070070 t->buffer.raw = 0;
71 t->bufferProvider = 0;
72 t->hook = 0;
73 t->resampler = 0;
74 t->sampleRate = mSampleRate;
75 t->in = 0;
76 t->mainBuffer = NULL;
77 t->auxBuffer = NULL;
78 t++;
79 }
80}
81
82 AudioMixer::~AudioMixer()
83 {
84 track_t* t = mState.tracks;
85 for (int i=0 ; i<32 ; i++) {
86 delete t->resampler;
87 t++;
88 }
89 delete [] mState.outputTemp;
90 delete [] mState.resampleTemp;
91 }
92
93 int AudioMixer::getTrackName()
94 {
95 uint32_t names = mTrackNames;
96 uint32_t mask = 1;
97 int n = 0;
98 while (names & mask) {
99 mask <<= 1;
100 n++;
101 }
102 if (mask) {
Steve Block3856b092011-10-20 11:56:00 +0100103 ALOGV("add track (%d)", n);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700104 mTrackNames |= mask;
105 return TRACK0 + n;
106 }
107 return -1;
108 }
109
110 void AudioMixer::invalidateState(uint32_t mask)
111 {
112 if (mask) {
113 mState.needsChanged |= mask;
114 mState.hook = process__validate;
115 }
116 }
117
118 void AudioMixer::deleteTrackName(int name)
119 {
120 name -= TRACK0;
121 if (uint32_t(name) < MAX_NUM_TRACKS) {
Steve Block3856b092011-10-20 11:56:00 +0100122 ALOGV("deleteTrackName(%d)", name);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700123 track_t& track(mState.tracks[ name ]);
124 if (track.enabled != 0) {
125 track.enabled = 0;
126 invalidateState(1<<name);
127 }
128 if (track.resampler) {
129 // delete the resampler
130 delete track.resampler;
131 track.resampler = 0;
132 track.sampleRate = mSampleRate;
133 invalidateState(1<<name);
134 }
135 track.volumeInc[0] = 0;
136 track.volumeInc[1] = 0;
137 mTrackNames &= ~(1<<name);
138 }
139 }
140
141status_t AudioMixer::enable(int name)
142{
143 switch (name) {
144 case MIXING: {
145 if (mState.tracks[ mActiveTrack ].enabled != 1) {
146 mState.tracks[ mActiveTrack ].enabled = 1;
Steve Block3856b092011-10-20 11:56:00 +0100147 ALOGV("enable(%d)", mActiveTrack);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700148 invalidateState(1<<mActiveTrack);
149 }
150 } break;
151 default:
152 return NAME_NOT_FOUND;
153 }
154 return NO_ERROR;
155}
156
157status_t AudioMixer::disable(int name)
158{
159 switch (name) {
160 case MIXING: {
161 if (mState.tracks[ mActiveTrack ].enabled != 0) {
162 mState.tracks[ mActiveTrack ].enabled = 0;
Steve Block3856b092011-10-20 11:56:00 +0100163 ALOGV("disable(%d)", mActiveTrack);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700164 invalidateState(1<<mActiveTrack);
165 }
166 } break;
167 default:
168 return NAME_NOT_FOUND;
169 }
170 return NO_ERROR;
171}
172
Glenn Kastenfba380a2011-12-15 15:46:46 -0800173void AudioMixer::setActiveTrack(int track)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700174{
Glenn Kastenfba380a2011-12-15 15:46:46 -0800175 // this also catches track < TRACK0
176 track -= TRACK0;
177 assert(uint32_t(track) < MAX_NUM_TRACKS);
178 mActiveTrack = track;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700179}
180
181status_t AudioMixer::setParameter(int target, int name, void *value)
182{
183 int valueInt = (int)value;
184 int32_t *valueBuf = (int32_t *)value;
185
186 switch (target) {
187 case TRACK:
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -0700188 if (name == CHANNEL_MASK) {
189 uint32_t mask = (uint32_t)value;
190 if (mState.tracks[ mActiveTrack ].channelMask != mask) {
191 uint8_t channelCount = popcount(mask);
192 if ((channelCount <= MAX_NUM_CHANNELS) && (channelCount)) {
193 mState.tracks[ mActiveTrack ].channelMask = mask;
194 mState.tracks[ mActiveTrack ].channelCount = channelCount;
Steve Block3856b092011-10-20 11:56:00 +0100195 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700196 invalidateState(1<<mActiveTrack);
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -0700197 return NO_ERROR;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700198 }
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -0700199 } else {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700200 return NO_ERROR;
201 }
202 }
203 if (name == MAIN_BUFFER) {
204 if (mState.tracks[ mActiveTrack ].mainBuffer != valueBuf) {
205 mState.tracks[ mActiveTrack ].mainBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100206 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700207 invalidateState(1<<mActiveTrack);
208 }
209 return NO_ERROR;
210 }
211 if (name == AUX_BUFFER) {
212 if (mState.tracks[ mActiveTrack ].auxBuffer != valueBuf) {
213 mState.tracks[ mActiveTrack ].auxBuffer = valueBuf;
Steve Block3856b092011-10-20 11:56:00 +0100214 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700215 invalidateState(1<<mActiveTrack);
216 }
217 return NO_ERROR;
218 }
219
220 break;
221 case RESAMPLE:
222 if (name == SAMPLE_RATE) {
223 if (valueInt > 0) {
224 track_t& track = mState.tracks[ mActiveTrack ];
225 if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
Steve Block3856b092011-10-20 11:56:00 +0100226 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700227 uint32_t(valueInt));
228 invalidateState(1<<mActiveTrack);
229 }
230 return NO_ERROR;
231 }
232 }
Eric Laurent243f5f92011-02-28 16:52:51 -0800233 if (name == RESET) {
234 track_t& track = mState.tracks[ mActiveTrack ];
235 track.resetResampler();
236 invalidateState(1<<mActiveTrack);
237 return NO_ERROR;
238 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700239 break;
240 case RAMP_VOLUME:
241 case VOLUME:
242 if ((uint32_t(name-VOLUME0) < MAX_NUM_CHANNELS)) {
243 track_t& track = mState.tracks[ mActiveTrack ];
244 if (track.volume[name-VOLUME0] != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100245 ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700246 track.prevVolume[name-VOLUME0] = track.volume[name-VOLUME0] << 16;
247 track.volume[name-VOLUME0] = valueInt;
248 if (target == VOLUME) {
249 track.prevVolume[name-VOLUME0] = valueInt << 16;
250 track.volumeInc[name-VOLUME0] = 0;
251 } else {
252 int32_t d = (valueInt<<16) - track.prevVolume[name-VOLUME0];
253 int32_t volInc = d / int32_t(mState.frameCount);
254 track.volumeInc[name-VOLUME0] = volInc;
255 if (volInc == 0) {
256 track.prevVolume[name-VOLUME0] = valueInt << 16;
257 }
258 }
259 invalidateState(1<<mActiveTrack);
260 }
261 return NO_ERROR;
262 } else if (name == AUXLEVEL) {
263 track_t& track = mState.tracks[ mActiveTrack ];
264 if (track.auxLevel != valueInt) {
Steve Block3856b092011-10-20 11:56:00 +0100265 ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700266 track.prevAuxLevel = track.auxLevel << 16;
267 track.auxLevel = valueInt;
268 if (target == VOLUME) {
269 track.prevAuxLevel = valueInt << 16;
270 track.auxInc = 0;
271 } else {
272 int32_t d = (valueInt<<16) - track.prevAuxLevel;
273 int32_t volInc = d / int32_t(mState.frameCount);
274 track.auxInc = volInc;
275 if (volInc == 0) {
276 track.prevAuxLevel = valueInt << 16;
277 }
278 }
279 invalidateState(1<<mActiveTrack);
280 }
281 return NO_ERROR;
282 }
283 break;
284 }
285 return BAD_VALUE;
286}
287
288bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
289{
290 if (value!=devSampleRate || resampler) {
291 if (sampleRate != value) {
292 sampleRate = value;
293 if (resampler == 0) {
294 resampler = AudioResampler::create(
295 format, channelCount, devSampleRate);
296 }
297 return true;
298 }
299 }
300 return false;
301}
302
303bool AudioMixer::track_t::doesResample() const
304{
305 return resampler != 0;
306}
307
Eric Laurent243f5f92011-02-28 16:52:51 -0800308void AudioMixer::track_t::resetResampler()
309{
310 if (resampler != 0) {
311 resampler->reset();
312 }
313}
314
Mathias Agopian65ab4712010-07-14 17:59:35 -0700315inline
316void AudioMixer::track_t::adjustVolumeRamp(bool aux)
317{
318 for (int i=0 ; i<2 ; i++) {
319 if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
320 ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
321 volumeInc[i] = 0;
322 prevVolume[i] = volume[i]<<16;
323 }
324 }
325 if (aux) {
326 if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
327 ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
328 auxInc = 0;
329 prevAuxLevel = auxLevel<<16;
330 }
331 }
332}
333
334
Glenn Kastenfba380a2011-12-15 15:46:46 -0800335void AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700336{
337 mState.tracks[ mActiveTrack ].bufferProvider = buffer;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700338}
339
340
341
342void AudioMixer::process()
343{
344 mState.hook(&mState);
345}
346
347
348void AudioMixer::process__validate(state_t* state)
349{
350 LOGW_IF(!state->needsChanged,
351 "in process__validate() but nothing's invalid");
352
353 uint32_t changed = state->needsChanged;
354 state->needsChanged = 0; // clear the validation flag
355
356 // recompute which tracks are enabled / disabled
357 uint32_t enabled = 0;
358 uint32_t disabled = 0;
359 while (changed) {
360 const int i = 31 - __builtin_clz(changed);
361 const uint32_t mask = 1<<i;
362 changed &= ~mask;
363 track_t& t = state->tracks[i];
364 (t.enabled ? enabled : disabled) |= mask;
365 }
366 state->enabledTracks &= ~disabled;
367 state->enabledTracks |= enabled;
368
369 // compute everything we need...
370 int countActiveTracks = 0;
371 int all16BitsStereoNoResample = 1;
372 int resampling = 0;
373 int volumeRamp = 0;
374 uint32_t en = state->enabledTracks;
375 while (en) {
376 const int i = 31 - __builtin_clz(en);
377 en &= ~(1<<i);
378
379 countActiveTracks++;
380 track_t& t = state->tracks[i];
381 uint32_t n = 0;
382 n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
383 n |= NEEDS_FORMAT_16;
384 n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
385 if (t.auxLevel != 0 && t.auxBuffer != NULL) {
386 n |= NEEDS_AUX_ENABLED;
387 }
388
389 if (t.volumeInc[0]|t.volumeInc[1]) {
390 volumeRamp = 1;
391 } else if (!t.doesResample() && t.volumeRL == 0) {
392 n |= NEEDS_MUTE_ENABLED;
393 }
394 t.needs = n;
395
396 if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
397 t.hook = track__nop;
398 } else {
399 if ((n & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
400 all16BitsStereoNoResample = 0;
401 }
402 if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
403 all16BitsStereoNoResample = 0;
404 resampling = 1;
405 t.hook = track__genericResample;
406 } else {
407 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
408 t.hook = track__16BitsMono;
409 all16BitsStereoNoResample = 0;
410 }
411 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
412 t.hook = track__16BitsStereo;
413 }
414 }
415 }
416 }
417
418 // select the processing hooks
419 state->hook = process__nop;
420 if (countActiveTracks) {
421 if (resampling) {
422 if (!state->outputTemp) {
423 state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
424 }
425 if (!state->resampleTemp) {
426 state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
427 }
428 state->hook = process__genericResampling;
429 } else {
430 if (state->outputTemp) {
431 delete [] state->outputTemp;
432 state->outputTemp = 0;
433 }
434 if (state->resampleTemp) {
435 delete [] state->resampleTemp;
436 state->resampleTemp = 0;
437 }
438 state->hook = process__genericNoResampling;
439 if (all16BitsStereoNoResample && !volumeRamp) {
440 if (countActiveTracks == 1) {
441 state->hook = process__OneTrack16BitsStereoNoResampling;
442 }
443 }
444 }
445 }
446
Steve Block3856b092011-10-20 11:56:00 +0100447 ALOGV("mixer configuration change: %d activeTracks (%08x) "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700448 "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
449 countActiveTracks, state->enabledTracks,
450 all16BitsStereoNoResample, resampling, volumeRamp);
451
452 state->hook(state);
453
454 // Now that the volume ramp has been done, set optimal state and
455 // track hooks for subsequent mixer process
456 if (countActiveTracks) {
457 int allMuted = 1;
458 uint32_t en = state->enabledTracks;
459 while (en) {
460 const int i = 31 - __builtin_clz(en);
461 en &= ~(1<<i);
462 track_t& t = state->tracks[i];
463 if (!t.doesResample() && t.volumeRL == 0)
464 {
465 t.needs |= NEEDS_MUTE_ENABLED;
466 t.hook = track__nop;
467 } else {
468 allMuted = 0;
469 }
470 }
471 if (allMuted) {
472 state->hook = process__nop;
473 } else if (all16BitsStereoNoResample) {
474 if (countActiveTracks == 1) {
475 state->hook = process__OneTrack16BitsStereoNoResampling;
476 }
477 }
478 }
479}
480
481static inline
482int32_t mulAdd(int16_t in, int16_t v, int32_t a)
483{
484#if defined(__arm__) && !defined(__thumb__)
485 int32_t out;
486 asm( "smlabb %[out], %[in], %[v], %[a] \n"
487 : [out]"=r"(out)
488 : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
489 : );
490 return out;
491#else
492 return a + in * int32_t(v);
493#endif
494}
495
496static inline
497int32_t mul(int16_t in, int16_t v)
498{
499#if defined(__arm__) && !defined(__thumb__)
500 int32_t out;
501 asm( "smulbb %[out], %[in], %[v] \n"
502 : [out]"=r"(out)
503 : [in]"%r"(in), [v]"r"(v)
504 : );
505 return out;
506#else
507 return in * int32_t(v);
508#endif
509}
510
511static inline
512int32_t mulAddRL(int left, uint32_t inRL, uint32_t vRL, int32_t a)
513{
514#if defined(__arm__) && !defined(__thumb__)
515 int32_t out;
516 if (left) {
517 asm( "smlabb %[out], %[inRL], %[vRL], %[a] \n"
518 : [out]"=r"(out)
519 : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a)
520 : );
521 } else {
522 asm( "smlatt %[out], %[inRL], %[vRL], %[a] \n"
523 : [out]"=r"(out)
524 : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a)
525 : );
526 }
527 return out;
528#else
529 if (left) {
530 return a + int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF);
531 } else {
532 return a + int16_t(inRL>>16) * int16_t(vRL>>16);
533 }
534#endif
535}
536
537static inline
538int32_t mulRL(int left, uint32_t inRL, uint32_t vRL)
539{
540#if defined(__arm__) && !defined(__thumb__)
541 int32_t out;
542 if (left) {
543 asm( "smulbb %[out], %[inRL], %[vRL] \n"
544 : [out]"=r"(out)
545 : [inRL]"%r"(inRL), [vRL]"r"(vRL)
546 : );
547 } else {
548 asm( "smultt %[out], %[inRL], %[vRL] \n"
549 : [out]"=r"(out)
550 : [inRL]"%r"(inRL), [vRL]"r"(vRL)
551 : );
552 }
553 return out;
554#else
555 if (left) {
556 return int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF);
557 } else {
558 return int16_t(inRL>>16) * int16_t(vRL>>16);
559 }
560#endif
561}
562
563
564void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
565{
566 t->resampler->setSampleRate(t->sampleRate);
567
568 // ramp gain - resample to temp buffer and scale/mix in 2nd step
569 if (aux != NULL) {
570 // always resample with unity gain when sending to auxiliary buffer to be able
571 // to apply send level after resampling
572 // TODO: modify each resampler to support aux channel?
573 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
574 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
575 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
576 if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc) {
577 volumeRampStereo(t, out, outFrameCount, temp, aux);
578 } else {
579 volumeStereo(t, out, outFrameCount, temp, aux);
580 }
581 } else {
582 if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
583 t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
584 memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
585 t->resampler->resample(temp, outFrameCount, t->bufferProvider);
586 volumeRampStereo(t, out, outFrameCount, temp, aux);
587 }
588
589 // constant gain
590 else {
591 t->resampler->setVolume(t->volume[0], t->volume[1]);
592 t->resampler->resample(out, outFrameCount, t->bufferProvider);
593 }
594 }
595}
596
597void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
598{
599}
600
601void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
602{
603 int32_t vl = t->prevVolume[0];
604 int32_t vr = t->prevVolume[1];
605 const int32_t vlInc = t->volumeInc[0];
606 const int32_t vrInc = t->volumeInc[1];
607
608 //LOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
609 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
610 // (vl + vlInc*frameCount)/65536.0f, frameCount);
611
612 // ramp volume
613 if UNLIKELY(aux != NULL) {
614 int32_t va = t->prevAuxLevel;
615 const int32_t vaInc = t->auxInc;
616 int32_t l;
617 int32_t r;
618
619 do {
620 l = (*temp++ >> 12);
621 r = (*temp++ >> 12);
622 *out++ += (vl >> 16) * l;
623 *out++ += (vr >> 16) * r;
624 *aux++ += (va >> 17) * (l + r);
625 vl += vlInc;
626 vr += vrInc;
627 va += vaInc;
628 } while (--frameCount);
629 t->prevAuxLevel = va;
630 } else {
631 do {
632 *out++ += (vl >> 16) * (*temp++ >> 12);
633 *out++ += (vr >> 16) * (*temp++ >> 12);
634 vl += vlInc;
635 vr += vrInc;
636 } while (--frameCount);
637 }
638 t->prevVolume[0] = vl;
639 t->prevVolume[1] = vr;
640 t->adjustVolumeRamp((aux != NULL));
641}
642
643void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
644{
645 const int16_t vl = t->volume[0];
646 const int16_t vr = t->volume[1];
647
648 if UNLIKELY(aux != NULL) {
649 const int16_t va = (int16_t)t->auxLevel;
650 do {
651 int16_t l = (int16_t)(*temp++ >> 12);
652 int16_t r = (int16_t)(*temp++ >> 12);
653 out[0] = mulAdd(l, vl, out[0]);
654 int16_t a = (int16_t)(((int32_t)l + r) >> 1);
655 out[1] = mulAdd(r, vr, out[1]);
656 out += 2;
657 aux[0] = mulAdd(a, va, aux[0]);
658 aux++;
659 } while (--frameCount);
660 } else {
661 do {
662 int16_t l = (int16_t)(*temp++ >> 12);
663 int16_t r = (int16_t)(*temp++ >> 12);
664 out[0] = mulAdd(l, vl, out[0]);
665 out[1] = mulAdd(r, vr, out[1]);
666 out += 2;
667 } while (--frameCount);
668 }
669}
670
671void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
672{
673 int16_t const *in = static_cast<int16_t const *>(t->in);
674
675 if UNLIKELY(aux != NULL) {
676 int32_t l;
677 int32_t r;
678 // ramp gain
679 if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc) {
680 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 // LOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
687 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
688 // (vl + vlInc*frameCount)/65536.0f, frameCount);
689
690 do {
691 l = (int32_t)*in++;
692 r = (int32_t)*in++;
693 *out++ += (vl >> 16) * l;
694 *out++ += (vr >> 16) * r;
695 *aux++ += (va >> 17) * (l + r);
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
707 // constant gain
708 else {
709 const uint32_t vrl = t->volumeRL;
710 const int16_t va = (int16_t)t->auxLevel;
711 do {
712 uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
713 int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
714 in += 2;
715 out[0] = mulAddRL(1, rl, vrl, out[0]);
716 out[1] = mulAddRL(0, rl, vrl, out[1]);
717 out += 2;
718 aux[0] = mulAdd(a, va, aux[0]);
719 aux++;
720 } while (--frameCount);
721 }
722 } else {
723 // ramp gain
724 if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
725 int32_t vl = t->prevVolume[0];
726 int32_t vr = t->prevVolume[1];
727 const int32_t vlInc = t->volumeInc[0];
728 const int32_t vrInc = t->volumeInc[1];
729
730 // LOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
731 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
732 // (vl + vlInc*frameCount)/65536.0f, frameCount);
733
734 do {
735 *out++ += (vl >> 16) * (int32_t) *in++;
736 *out++ += (vr >> 16) * (int32_t) *in++;
737 vl += vlInc;
738 vr += vrInc;
739 } while (--frameCount);
740
741 t->prevVolume[0] = vl;
742 t->prevVolume[1] = vr;
743 t->adjustVolumeRamp(false);
744 }
745
746 // constant gain
747 else {
748 const uint32_t vrl = t->volumeRL;
749 do {
750 uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
751 in += 2;
752 out[0] = mulAddRL(1, rl, vrl, out[0]);
753 out[1] = mulAddRL(0, rl, vrl, out[1]);
754 out += 2;
755 } while (--frameCount);
756 }
757 }
758 t->in = in;
759}
760
761void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
762{
763 int16_t const *in = static_cast<int16_t const *>(t->in);
764
765 if UNLIKELY(aux != NULL) {
766 // ramp gain
767 if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc) {
768 int32_t vl = t->prevVolume[0];
769 int32_t vr = t->prevVolume[1];
770 int32_t va = t->prevAuxLevel;
771 const int32_t vlInc = t->volumeInc[0];
772 const int32_t vrInc = t->volumeInc[1];
773 const int32_t vaInc = t->auxInc;
774
775 // LOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
776 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
777 // (vl + vlInc*frameCount)/65536.0f, frameCount);
778
779 do {
780 int32_t l = *in++;
781 *out++ += (vl >> 16) * l;
782 *out++ += (vr >> 16) * l;
783 *aux++ += (va >> 16) * l;
784 vl += vlInc;
785 vr += vrInc;
786 va += vaInc;
787 } while (--frameCount);
788
789 t->prevVolume[0] = vl;
790 t->prevVolume[1] = vr;
791 t->prevAuxLevel = va;
792 t->adjustVolumeRamp(true);
793 }
794 // constant gain
795 else {
796 const int16_t vl = t->volume[0];
797 const int16_t vr = t->volume[1];
798 const int16_t va = (int16_t)t->auxLevel;
799 do {
800 int16_t l = *in++;
801 out[0] = mulAdd(l, vl, out[0]);
802 out[1] = mulAdd(l, vr, out[1]);
803 out += 2;
804 aux[0] = mulAdd(l, va, aux[0]);
805 aux++;
806 } while (--frameCount);
807 }
808 } else {
809 // ramp gain
810 if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
811 int32_t vl = t->prevVolume[0];
812 int32_t vr = t->prevVolume[1];
813 const int32_t vlInc = t->volumeInc[0];
814 const int32_t vrInc = t->volumeInc[1];
815
816 // LOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
817 // t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
818 // (vl + vlInc*frameCount)/65536.0f, frameCount);
819
820 do {
821 int32_t l = *in++;
822 *out++ += (vl >> 16) * l;
823 *out++ += (vr >> 16) * l;
824 vl += vlInc;
825 vr += vrInc;
826 } while (--frameCount);
827
828 t->prevVolume[0] = vl;
829 t->prevVolume[1] = vr;
830 t->adjustVolumeRamp(false);
831 }
832 // constant gain
833 else {
834 const int16_t vl = t->volume[0];
835 const int16_t vr = t->volume[1];
836 do {
837 int16_t l = *in++;
838 out[0] = mulAdd(l, vl, out[0]);
839 out[1] = mulAdd(l, vr, out[1]);
840 out += 2;
841 } while (--frameCount);
842 }
843 }
844 t->in = in;
845}
846
847void AudioMixer::ditherAndClamp(int32_t* out, int32_t const *sums, size_t c)
848{
849 for (size_t i=0 ; i<c ; i++) {
850 int32_t l = *sums++;
851 int32_t r = *sums++;
852 int32_t nl = l >> 12;
853 int32_t nr = r >> 12;
854 l = clamp16(nl);
855 r = clamp16(nr);
856 *out++ = (r<<16) | (l & 0xFFFF);
857 }
858}
859
860// no-op case
861void AudioMixer::process__nop(state_t* state)
862{
863 uint32_t e0 = state->enabledTracks;
864 size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS;
865 while (e0) {
866 // process by group of tracks with same output buffer to
867 // avoid multiple memset() on same buffer
868 uint32_t e1 = e0, e2 = e0;
869 int i = 31 - __builtin_clz(e1);
870 track_t& t1 = state->tracks[i];
871 e2 &= ~(1<<i);
872 while (e2) {
873 i = 31 - __builtin_clz(e2);
874 e2 &= ~(1<<i);
875 track_t& t2 = state->tracks[i];
876 if UNLIKELY(t2.mainBuffer != t1.mainBuffer) {
877 e1 &= ~(1<<i);
878 }
879 }
880 e0 &= ~(e1);
881
882 memset(t1.mainBuffer, 0, bufSize);
883
884 while (e1) {
885 i = 31 - __builtin_clz(e1);
886 e1 &= ~(1<<i);
887 t1 = state->tracks[i];
888 size_t outFrames = state->frameCount;
889 while (outFrames) {
890 t1.buffer.frameCount = outFrames;
891 t1.bufferProvider->getNextBuffer(&t1.buffer);
892 if (!t1.buffer.raw) break;
893 outFrames -= t1.buffer.frameCount;
894 t1.bufferProvider->releaseBuffer(&t1.buffer);
895 }
896 }
897 }
898}
899
900// generic code without resampling
901void AudioMixer::process__genericNoResampling(state_t* state)
902{
903 int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
904
905 // acquire each track's buffer
906 uint32_t enabledTracks = state->enabledTracks;
907 uint32_t e0 = enabledTracks;
908 while (e0) {
909 const int i = 31 - __builtin_clz(e0);
910 e0 &= ~(1<<i);
911 track_t& t = state->tracks[i];
912 t.buffer.frameCount = state->frameCount;
913 t.bufferProvider->getNextBuffer(&t.buffer);
914 t.frameCount = t.buffer.frameCount;
915 t.in = t.buffer.raw;
916 // t.in == NULL can happen if the track was flushed just after having
917 // been enabled for mixing.
918 if (t.in == NULL)
919 enabledTracks &= ~(1<<i);
920 }
921
922 e0 = enabledTracks;
923 while (e0) {
924 // process by group of tracks with same output buffer to
925 // optimize cache use
926 uint32_t e1 = e0, e2 = e0;
927 int j = 31 - __builtin_clz(e1);
928 track_t& t1 = state->tracks[j];
929 e2 &= ~(1<<j);
930 while (e2) {
931 j = 31 - __builtin_clz(e2);
932 e2 &= ~(1<<j);
933 track_t& t2 = state->tracks[j];
934 if UNLIKELY(t2.mainBuffer != t1.mainBuffer) {
935 e1 &= ~(1<<j);
936 }
937 }
938 e0 &= ~(e1);
939 // this assumes output 16 bits stereo, no resampling
940 int32_t *out = t1.mainBuffer;
941 size_t numFrames = 0;
942 do {
943 memset(outTemp, 0, sizeof(outTemp));
944 e2 = e1;
945 while (e2) {
946 const int i = 31 - __builtin_clz(e2);
947 e2 &= ~(1<<i);
948 track_t& t = state->tracks[i];
949 size_t outFrames = BLOCKSIZE;
950 int32_t *aux = NULL;
951 if UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
952 aux = t.auxBuffer + numFrames;
953 }
954 while (outFrames) {
955 size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
956 if (inFrames) {
957 (t.hook)(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux);
958 t.frameCount -= inFrames;
959 outFrames -= inFrames;
960 if UNLIKELY(aux != NULL) {
961 aux += inFrames;
962 }
963 }
964 if (t.frameCount == 0 && outFrames) {
965 t.bufferProvider->releaseBuffer(&t.buffer);
966 t.buffer.frameCount = (state->frameCount - numFrames) - (BLOCKSIZE - outFrames);
967 t.bufferProvider->getNextBuffer(&t.buffer);
968 t.in = t.buffer.raw;
969 if (t.in == NULL) {
970 enabledTracks &= ~(1<<i);
971 e1 &= ~(1<<i);
972 break;
973 }
974 t.frameCount = t.buffer.frameCount;
975 }
976 }
977 }
978 ditherAndClamp(out, outTemp, BLOCKSIZE);
979 out += BLOCKSIZE;
980 numFrames += BLOCKSIZE;
981 } while (numFrames < state->frameCount);
982 }
983
984 // release each track's buffer
985 e0 = enabledTracks;
986 while (e0) {
987 const int i = 31 - __builtin_clz(e0);
988 e0 &= ~(1<<i);
989 track_t& t = state->tracks[i];
990 t.bufferProvider->releaseBuffer(&t.buffer);
991 }
992}
993
994
995 // generic code with resampling
996void AudioMixer::process__genericResampling(state_t* state)
997{
998 int32_t* const outTemp = state->outputTemp;
999 const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001000
1001 size_t numFrames = state->frameCount;
1002
1003 uint32_t e0 = state->enabledTracks;
1004 while (e0) {
1005 // process by group of tracks with same output buffer
1006 // to optimize cache use
1007 uint32_t e1 = e0, e2 = e0;
1008 int j = 31 - __builtin_clz(e1);
1009 track_t& t1 = state->tracks[j];
1010 e2 &= ~(1<<j);
1011 while (e2) {
1012 j = 31 - __builtin_clz(e2);
1013 e2 &= ~(1<<j);
1014 track_t& t2 = state->tracks[j];
1015 if UNLIKELY(t2.mainBuffer != t1.mainBuffer) {
1016 e1 &= ~(1<<j);
1017 }
1018 }
1019 e0 &= ~(e1);
1020 int32_t *out = t1.mainBuffer;
Yuuhi Yamaguchi2151d7b2011-02-04 15:24:34 +01001021 memset(outTemp, 0, size);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001022 while (e1) {
1023 const int i = 31 - __builtin_clz(e1);
1024 e1 &= ~(1<<i);
1025 track_t& t = state->tracks[i];
1026 int32_t *aux = NULL;
1027 if UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
1028 aux = t.auxBuffer;
1029 }
1030
1031 // this is a little goofy, on the resampling case we don't
1032 // acquire/release the buffers because it's done by
1033 // the resampler.
1034 if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
1035 (t.hook)(&t, outTemp, numFrames, state->resampleTemp, aux);
1036 } else {
1037
1038 size_t outFrames = 0;
1039
1040 while (outFrames < numFrames) {
1041 t.buffer.frameCount = numFrames - outFrames;
1042 t.bufferProvider->getNextBuffer(&t.buffer);
1043 t.in = t.buffer.raw;
1044 // t.in == NULL can happen if the track was flushed just after having
1045 // been enabled for mixing.
1046 if (t.in == NULL) break;
1047
1048 if UNLIKELY(aux != NULL) {
1049 aux += outFrames;
1050 }
1051 (t.hook)(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
1052 outFrames += t.buffer.frameCount;
1053 t.bufferProvider->releaseBuffer(&t.buffer);
1054 }
1055 }
1056 }
1057 ditherAndClamp(out, outTemp, numFrames);
1058 }
1059}
1060
1061// one track, 16 bits stereo without resampling is the most common case
1062void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state)
1063{
1064 const int i = 31 - __builtin_clz(state->enabledTracks);
1065 const track_t& t = state->tracks[i];
1066
1067 AudioBufferProvider::Buffer& b(t.buffer);
1068
1069 int32_t* out = t.mainBuffer;
1070 size_t numFrames = state->frameCount;
1071
1072 const int16_t vl = t.volume[0];
1073 const int16_t vr = t.volume[1];
1074 const uint32_t vrl = t.volumeRL;
1075 while (numFrames) {
1076 b.frameCount = numFrames;
1077 t.bufferProvider->getNextBuffer(&b);
1078 int16_t const *in = b.i16;
1079
1080 // in == NULL can happen if the track was flushed just after having
1081 // been enabled for mixing.
1082 if (in == NULL || ((unsigned long)in & 3)) {
1083 memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
1084 LOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: buffer %p track %d, channels %d, needs %08x",
1085 in, i, t.channelCount, t.needs);
1086 return;
1087 }
1088 size_t outFrames = b.frameCount;
1089
1090 if (UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
1091 // volume is boosted, so we might need to clamp even though
1092 // we process only one track.
1093 do {
1094 uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
1095 in += 2;
1096 int32_t l = mulRL(1, rl, vrl) >> 12;
1097 int32_t r = mulRL(0, rl, vrl) >> 12;
1098 // clamping...
1099 l = clamp16(l);
1100 r = clamp16(r);
1101 *out++ = (r<<16) | (l & 0xFFFF);
1102 } while (--outFrames);
1103 } else {
1104 do {
1105 uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
1106 in += 2;
1107 int32_t l = mulRL(1, rl, vrl) >> 12;
1108 int32_t r = mulRL(0, rl, vrl) >> 12;
1109 *out++ = (r<<16) | (l & 0xFFFF);
1110 } while (--outFrames);
1111 }
1112 numFrames -= b.frameCount;
1113 t.bufferProvider->releaseBuffer(&b);
1114 }
1115}
1116
1117// 2 tracks is also a common case
1118// NEVER used in current implementation of process__validate()
1119// only use if the 2 tracks have the same output buffer
1120void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state)
1121{
1122 int i;
1123 uint32_t en = state->enabledTracks;
1124
1125 i = 31 - __builtin_clz(en);
1126 const track_t& t0 = state->tracks[i];
1127 AudioBufferProvider::Buffer& b0(t0.buffer);
1128
1129 en &= ~(1<<i);
1130 i = 31 - __builtin_clz(en);
1131 const track_t& t1 = state->tracks[i];
1132 AudioBufferProvider::Buffer& b1(t1.buffer);
1133
1134 int16_t const *in0;
1135 const int16_t vl0 = t0.volume[0];
1136 const int16_t vr0 = t0.volume[1];
1137 size_t frameCount0 = 0;
1138
1139 int16_t const *in1;
1140 const int16_t vl1 = t1.volume[0];
1141 const int16_t vr1 = t1.volume[1];
1142 size_t frameCount1 = 0;
1143
1144 //FIXME: only works if two tracks use same buffer
1145 int32_t* out = t0.mainBuffer;
1146 size_t numFrames = state->frameCount;
1147 int16_t const *buff = NULL;
1148
1149
1150 while (numFrames) {
1151
1152 if (frameCount0 == 0) {
1153 b0.frameCount = numFrames;
1154 t0.bufferProvider->getNextBuffer(&b0);
1155 if (b0.i16 == NULL) {
1156 if (buff == NULL) {
1157 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1158 }
1159 in0 = buff;
1160 b0.frameCount = numFrames;
1161 } else {
1162 in0 = b0.i16;
1163 }
1164 frameCount0 = b0.frameCount;
1165 }
1166 if (frameCount1 == 0) {
1167 b1.frameCount = numFrames;
1168 t1.bufferProvider->getNextBuffer(&b1);
1169 if (b1.i16 == NULL) {
1170 if (buff == NULL) {
1171 buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1172 }
1173 in1 = buff;
1174 b1.frameCount = numFrames;
1175 } else {
1176 in1 = b1.i16;
1177 }
1178 frameCount1 = b1.frameCount;
1179 }
1180
1181 size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1182
1183 numFrames -= outFrames;
1184 frameCount0 -= outFrames;
1185 frameCount1 -= outFrames;
1186
1187 do {
1188 int32_t l0 = *in0++;
1189 int32_t r0 = *in0++;
1190 l0 = mul(l0, vl0);
1191 r0 = mul(r0, vr0);
1192 int32_t l = *in1++;
1193 int32_t r = *in1++;
1194 l = mulAdd(l, vl1, l0) >> 12;
1195 r = mulAdd(r, vr1, r0) >> 12;
1196 // clamping...
1197 l = clamp16(l);
1198 r = clamp16(r);
1199 *out++ = (r<<16) | (l & 0xFFFF);
1200 } while (--outFrames);
1201
1202 if (frameCount0 == 0) {
1203 t0.bufferProvider->releaseBuffer(&b0);
1204 }
1205 if (frameCount1 == 0) {
1206 t1.bufferProvider->releaseBuffer(&b1);
1207 }
1208 }
1209
1210 if (buff != NULL) {
1211 delete [] buff;
1212 }
1213}
1214
1215// ----------------------------------------------------------------------------
1216}; // namespace android
1217