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