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