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