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