1/*
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#include <cutils/compiler.h>
31#include <utils/Debug.h>
32
33#include <system/audio.h>
34
35#include <audio_utils/primitives.h>
36#include <common_time/local_clock.h>
37#include <common_time/cc_helper.h>
38
39#include <media/EffectsFactoryApi.h>
40
41#include "AudioMixer.h"
42
43namespace android {
44
45// ----------------------------------------------------------------------------
46AudioMixer::DownmixerBufferProvider::DownmixerBufferProvider() : AudioBufferProvider(),
47        mTrackBufferProvider(NULL), mDownmixHandle(NULL)
48{
49}
50
51AudioMixer::DownmixerBufferProvider::~DownmixerBufferProvider()
52{
53    ALOGV("AudioMixer deleting DownmixerBufferProvider (%p)", this);
54    EffectRelease(mDownmixHandle);
55}
56
57status_t AudioMixer::DownmixerBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer,
58        int64_t pts) {
59    //ALOGV("DownmixerBufferProvider::getNextBuffer()");
60    if (this->mTrackBufferProvider != NULL) {
61        status_t res = mTrackBufferProvider->getNextBuffer(pBuffer, pts);
62        if (res == OK) {
63            mDownmixConfig.inputCfg.buffer.frameCount = pBuffer->frameCount;
64            mDownmixConfig.inputCfg.buffer.raw = pBuffer->raw;
65            mDownmixConfig.outputCfg.buffer.frameCount = pBuffer->frameCount;
66            mDownmixConfig.outputCfg.buffer.raw = mDownmixConfig.inputCfg.buffer.raw;
67            // in-place so overwrite the buffer contents, has been set in prepareTrackForDownmix()
68            //mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
69
70            res = (*mDownmixHandle)->process(mDownmixHandle,
71                    &mDownmixConfig.inputCfg.buffer, &mDownmixConfig.outputCfg.buffer);
72            //ALOGV("getNextBuffer is downmixing");
73        }
74        return res;
75    } else {
76        ALOGE("DownmixerBufferProvider::getNextBuffer() error: NULL track buffer provider");
77        return NO_INIT;
78    }
79}
80
81void AudioMixer::DownmixerBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
82    //ALOGV("DownmixerBufferProvider::releaseBuffer()");
83    if (this->mTrackBufferProvider != NULL) {
84        mTrackBufferProvider->releaseBuffer(pBuffer);
85    } else {
86        ALOGE("DownmixerBufferProvider::releaseBuffer() error: NULL track buffer provider");
87    }
88}
89
90
91// ----------------------------------------------------------------------------
92bool AudioMixer::isMultichannelCapable = false;
93
94effect_descriptor_t AudioMixer::dwnmFxDesc;
95
96// Ensure mConfiguredNames bitmask is initialized properly on all architectures.
97// The value of 1 << x is undefined in C when x >= 32.
98
99AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks)
100    :   mTrackNames(0), mConfiguredNames((maxNumTracks >= 32 ? 0 : 1 << maxNumTracks) - 1),
101        mSampleRate(sampleRate)
102{
103    // AudioMixer is not yet capable of multi-channel beyond stereo
104    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(2 == MAX_NUM_CHANNELS);
105
106    ALOG_ASSERT(maxNumTracks <= MAX_NUM_TRACKS, "maxNumTracks %u > MAX_NUM_TRACKS %u",
107            maxNumTracks, MAX_NUM_TRACKS);
108
109    LocalClock lc;
110
111    mState.enabledTracks= 0;
112    mState.needsChanged = 0;
113    mState.frameCount   = frameCount;
114    mState.hook         = process__nop;
115    mState.outputTemp   = NULL;
116    mState.resampleTemp = NULL;
117    // mState.reserved
118
119    // FIXME Most of the following initialization is probably redundant since
120    // tracks[i] should only be referenced if (mTrackNames & (1 << i)) != 0
121    // and mTrackNames is initially 0.  However, leave it here until that's verified.
122    track_t* t = mState.tracks;
123    for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
124        // FIXME redundant per track
125        t->localTimeFreq = lc.getLocalFreq();
126        t->resampler = NULL;
127        t->downmixerBufferProvider = NULL;
128        t++;
129    }
130
131    // find multichannel downmix effect if we have to play multichannel content
132    uint32_t numEffects = 0;
133    int ret = EffectQueryNumberEffects(&numEffects);
134    if (ret != 0) {
135        ALOGE("AudioMixer() error %d querying number of effects", ret);
136        return;
137    }
138    ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects);
139
140    for (uint32_t i = 0 ; i < numEffects ; i++) {
141        if (EffectQueryEffect(i, &dwnmFxDesc) == 0) {
142            ALOGV("effect %d is called %s", i, dwnmFxDesc.name);
143            if (memcmp(&dwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) {
144                ALOGI("found effect \"%s\" from %s",
145                        dwnmFxDesc.name, dwnmFxDesc.implementor);
146                isMultichannelCapable = true;
147                break;
148            }
149        }
150    }
151    ALOGE_IF(!isMultichannelCapable, "unable to find downmix effect");
152}
153
154AudioMixer::~AudioMixer()
155{
156    track_t* t = mState.tracks;
157    for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
158        delete t->resampler;
159        delete t->downmixerBufferProvider;
160        t++;
161    }
162    delete [] mState.outputTemp;
163    delete [] mState.resampleTemp;
164}
165
166int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId)
167{
168    uint32_t names = (~mTrackNames) & mConfiguredNames;
169    if (names != 0) {
170        int n = __builtin_ctz(names);
171        ALOGV("add track (%d)", n);
172        mTrackNames |= 1 << n;
173        // assume default parameters for the track, except where noted below
174        track_t* t = &mState.tracks[n];
175        t->needs = 0;
176        t->volume[0] = UNITY_GAIN;
177        t->volume[1] = UNITY_GAIN;
178        // no initialization needed
179        // t->prevVolume[0]
180        // t->prevVolume[1]
181        t->volumeInc[0] = 0;
182        t->volumeInc[1] = 0;
183        t->auxLevel = 0;
184        t->auxInc = 0;
185        // no initialization needed
186        // t->prevAuxLevel
187        // t->frameCount
188        t->channelCount = 2;
189        t->enabled = false;
190        t->format = 16;
191        t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
192        t->sessionId = sessionId;
193        // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
194        t->bufferProvider = NULL;
195        t->downmixerBufferProvider = NULL;
196        t->buffer.raw = NULL;
197        // no initialization needed
198        // t->buffer.frameCount
199        t->hook = NULL;
200        t->in = NULL;
201        t->resampler = NULL;
202        t->sampleRate = mSampleRate;
203        // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
204        t->mainBuffer = NULL;
205        t->auxBuffer = NULL;
206        // see t->localTimeFreq in constructor above
207
208        status_t status = initTrackDownmix(&mState.tracks[n], n, channelMask);
209        if (status == OK) {
210            return TRACK0 + n;
211        }
212        ALOGE("AudioMixer::getTrackName(0x%x) failed, error preparing track for downmix",
213                channelMask);
214    }
215    return -1;
216}
217
218void AudioMixer::invalidateState(uint32_t mask)
219{
220    if (mask) {
221        mState.needsChanged |= mask;
222        mState.hook = process__validate;
223    }
224 }
225
226status_t AudioMixer::initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask)
227{
228    uint32_t channelCount = popcount(mask);
229    ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
230    status_t status = OK;
231    if (channelCount > MAX_NUM_CHANNELS) {
232        pTrack->channelMask = mask;
233        pTrack->channelCount = channelCount;
234        ALOGV("initTrackDownmix(track=%d, mask=0x%x) calls prepareTrackForDownmix()",
235                trackNum, mask);
236        status = prepareTrackForDownmix(pTrack, trackNum);
237    } else {
238        unprepareTrackForDownmix(pTrack, trackNum);
239    }
240    return status;
241}
242
243void AudioMixer::unprepareTrackForDownmix(track_t* pTrack, int trackName) {
244    ALOGV("AudioMixer::unprepareTrackForDownmix(%d)", trackName);
245
246    if (pTrack->downmixerBufferProvider != NULL) {
247        // this track had previously been configured with a downmixer, delete it
248        ALOGV(" deleting old downmixer");
249        pTrack->bufferProvider = pTrack->downmixerBufferProvider->mTrackBufferProvider;
250        delete pTrack->downmixerBufferProvider;
251        pTrack->downmixerBufferProvider = NULL;
252    } else {
253        ALOGV(" nothing to do, no downmixer to delete");
254    }
255}
256
257status_t AudioMixer::prepareTrackForDownmix(track_t* pTrack, int trackName)
258{
259    ALOGV("AudioMixer::prepareTrackForDownmix(%d) with mask 0x%x", trackName, pTrack->channelMask);
260
261    // discard the previous downmixer if there was one
262    unprepareTrackForDownmix(pTrack, trackName);
263
264    DownmixerBufferProvider* pDbp = new DownmixerBufferProvider();
265    int32_t status;
266
267    if (!isMultichannelCapable) {
268        ALOGE("prepareTrackForDownmix(%d) fails: mixer doesn't support multichannel content",
269                trackName);
270        goto noDownmixForActiveTrack;
271    }
272
273    if (EffectCreate(&dwnmFxDesc.uuid,
274            pTrack->sessionId /*sessionId*/, -2 /*ioId not relevant here, using random value*/,
275            &pDbp->mDownmixHandle/*pHandle*/) != 0) {
276        ALOGE("prepareTrackForDownmix(%d) fails: error creating downmixer effect", trackName);
277        goto noDownmixForActiveTrack;
278    }
279
280    // channel input configuration will be overridden per-track
281    pDbp->mDownmixConfig.inputCfg.channels = pTrack->channelMask;
282    pDbp->mDownmixConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
283    pDbp->mDownmixConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
284    pDbp->mDownmixConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
285    pDbp->mDownmixConfig.inputCfg.samplingRate = pTrack->sampleRate;
286    pDbp->mDownmixConfig.outputCfg.samplingRate = pTrack->sampleRate;
287    pDbp->mDownmixConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
288    pDbp->mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
289    // input and output buffer provider, and frame count will not be used as the downmix effect
290    // process() function is called directly (see DownmixerBufferProvider::getNextBuffer())
291    pDbp->mDownmixConfig.inputCfg.mask = EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS |
292            EFFECT_CONFIG_FORMAT | EFFECT_CONFIG_ACC_MODE;
293    pDbp->mDownmixConfig.outputCfg.mask = pDbp->mDownmixConfig.inputCfg.mask;
294
295    {// scope for local variables that are not used in goto label "noDownmixForActiveTrack"
296        int cmdStatus;
297        uint32_t replySize = sizeof(int);
298
299        // Configure and enable downmixer
300        status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
301                EFFECT_CMD_SET_CONFIG /*cmdCode*/, sizeof(effect_config_t) /*cmdSize*/,
302                &pDbp->mDownmixConfig /*pCmdData*/,
303                &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
304        if ((status != 0) || (cmdStatus != 0)) {
305            ALOGE("error %d while configuring downmixer for track %d", status, trackName);
306            goto noDownmixForActiveTrack;
307        }
308        replySize = sizeof(int);
309        status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
310                EFFECT_CMD_ENABLE /*cmdCode*/, 0 /*cmdSize*/, NULL /*pCmdData*/,
311                &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
312        if ((status != 0) || (cmdStatus != 0)) {
313            ALOGE("error %d while enabling downmixer for track %d", status, trackName);
314            goto noDownmixForActiveTrack;
315        }
316
317        // Set downmix type
318        // parameter size rounded for padding on 32bit boundary
319        const int psizePadded = ((sizeof(downmix_params_t) - 1)/sizeof(int) + 1) * sizeof(int);
320        const int downmixParamSize =
321                sizeof(effect_param_t) + psizePadded + sizeof(downmix_type_t);
322        effect_param_t * const param = (effect_param_t *) malloc(downmixParamSize);
323        param->psize = sizeof(downmix_params_t);
324        const downmix_params_t downmixParam = DOWNMIX_PARAM_TYPE;
325        memcpy(param->data, &downmixParam, param->psize);
326        const downmix_type_t downmixType = DOWNMIX_TYPE_FOLD;
327        param->vsize = sizeof(downmix_type_t);
328        memcpy(param->data + psizePadded, &downmixType, param->vsize);
329
330        status = (*pDbp->mDownmixHandle)->command(pDbp->mDownmixHandle,
331                EFFECT_CMD_SET_PARAM /* cmdCode */, downmixParamSize/* cmdSize */,
332                param /*pCmndData*/, &replySize /*replySize*/, &cmdStatus /*pReplyData*/);
333
334        free(param);
335
336        if ((status != 0) || (cmdStatus != 0)) {
337            ALOGE("error %d while setting downmix type for track %d", status, trackName);
338            goto noDownmixForActiveTrack;
339        } else {
340            ALOGV("downmix type set to %d for track %d", (int) downmixType, trackName);
341        }
342    }// end of scope for local variables that are not used in goto label "noDownmixForActiveTrack"
343
344    // initialization successful:
345    // - keep track of the real buffer provider in case it was set before
346    pDbp->mTrackBufferProvider = pTrack->bufferProvider;
347    // - we'll use the downmix effect integrated inside this
348    //    track's buffer provider, and we'll use it as the track's buffer provider
349    pTrack->downmixerBufferProvider = pDbp;
350    pTrack->bufferProvider = pDbp;
351
352    return NO_ERROR;
353
354noDownmixForActiveTrack:
355    delete pDbp;
356    pTrack->downmixerBufferProvider = NULL;
357    return NO_INIT;
358}
359
360void AudioMixer::deleteTrackName(int name)
361{
362    ALOGV("AudioMixer::deleteTrackName(%d)", name);
363    name -= TRACK0;
364    ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
365    ALOGV("deleteTrackName(%d)", name);
366    track_t& track(mState.tracks[ name ]);
367    if (track.enabled) {
368        track.enabled = false;
369        invalidateState(1<<name);
370    }
371    // delete the resampler
372    delete track.resampler;
373    track.resampler = NULL;
374    // delete the downmixer
375    unprepareTrackForDownmix(&mState.tracks[name], name);
376
377    mTrackNames &= ~(1<<name);
378}
379
380void AudioMixer::enable(int name)
381{
382    name -= TRACK0;
383    ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
384    track_t& track = mState.tracks[name];
385
386    if (!track.enabled) {
387        track.enabled = true;
388        ALOGV("enable(%d)", name);
389        invalidateState(1 << name);
390    }
391}
392
393void AudioMixer::disable(int name)
394{
395    name -= TRACK0;
396    ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
397    track_t& track = mState.tracks[name];
398
399    if (track.enabled) {
400        track.enabled = false;
401        ALOGV("disable(%d)", name);
402        invalidateState(1 << name);
403    }
404}
405
406void AudioMixer::setParameter(int name, int target, int param, void *value)
407{
408    name -= TRACK0;
409    ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
410    track_t& track = mState.tracks[name];
411
412    int valueInt = (int)value;
413    int32_t *valueBuf = (int32_t *)value;
414
415    switch (target) {
416
417    case TRACK:
418        switch (param) {
419        case CHANNEL_MASK: {
420            audio_channel_mask_t mask = (audio_channel_mask_t) value;
421            if (track.channelMask != mask) {
422                uint32_t channelCount = popcount(mask);
423                ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
424                track.channelMask = mask;
425                track.channelCount = channelCount;
426                // the mask has changed, does this track need a downmixer?
427                initTrackDownmix(&mState.tracks[name], name, mask);
428                ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
429                invalidateState(1 << name);
430            }
431            } break;
432        case MAIN_BUFFER:
433            if (track.mainBuffer != valueBuf) {
434                track.mainBuffer = valueBuf;
435                ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
436                invalidateState(1 << name);
437            }
438            break;
439        case AUX_BUFFER:
440            if (track.auxBuffer != valueBuf) {
441                track.auxBuffer = valueBuf;
442                ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
443                invalidateState(1 << name);
444            }
445            break;
446        case FORMAT:
447            ALOG_ASSERT(valueInt == AUDIO_FORMAT_PCM_16_BIT);
448            break;
449        // FIXME do we want to support setting the downmix type from AudioFlinger?
450        //         for a specific track? or per mixer?
451        /* case DOWNMIX_TYPE:
452            break          */
453        default:
454            LOG_FATAL("bad param");
455        }
456        break;
457
458    case RESAMPLE:
459        switch (param) {
460        case SAMPLE_RATE:
461            ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
462            if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
463                ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
464                        uint32_t(valueInt));
465                invalidateState(1 << name);
466            }
467            break;
468        case RESET:
469            track.resetResampler();
470            invalidateState(1 << name);
471            break;
472        case REMOVE:
473            delete track.resampler;
474            track.resampler = NULL;
475            track.sampleRate = mSampleRate;
476            invalidateState(1 << name);
477            break;
478        default:
479            LOG_FATAL("bad param");
480        }
481        break;
482
483    case RAMP_VOLUME:
484    case VOLUME:
485        switch (param) {
486        case VOLUME0:
487        case VOLUME1:
488            if (track.volume[param-VOLUME0] != valueInt) {
489                ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
490                track.prevVolume[param-VOLUME0] = track.volume[param-VOLUME0] << 16;
491                track.volume[param-VOLUME0] = valueInt;
492                if (target == VOLUME) {
493                    track.prevVolume[param-VOLUME0] = valueInt << 16;
494                    track.volumeInc[param-VOLUME0] = 0;
495                } else {
496                    int32_t d = (valueInt<<16) - track.prevVolume[param-VOLUME0];
497                    int32_t volInc = d / int32_t(mState.frameCount);
498                    track.volumeInc[param-VOLUME0] = volInc;
499                    if (volInc == 0) {
500                        track.prevVolume[param-VOLUME0] = valueInt << 16;
501                    }
502                }
503                invalidateState(1 << name);
504            }
505            break;
506        case AUXLEVEL:
507            //ALOG_ASSERT(0 <= valueInt && valueInt <= MAX_GAIN_INT, "bad aux level %d", valueInt);
508            if (track.auxLevel != valueInt) {
509                ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
510                track.prevAuxLevel = track.auxLevel << 16;
511                track.auxLevel = valueInt;
512                if (target == VOLUME) {
513                    track.prevAuxLevel = valueInt << 16;
514                    track.auxInc = 0;
515                } else {
516                    int32_t d = (valueInt<<16) - track.prevAuxLevel;
517                    int32_t volInc = d / int32_t(mState.frameCount);
518                    track.auxInc = volInc;
519                    if (volInc == 0) {
520                        track.prevAuxLevel = valueInt << 16;
521                    }
522                }
523                invalidateState(1 << name);
524            }
525            break;
526        default:
527            LOG_FATAL("bad param");
528        }
529        break;
530
531    default:
532        LOG_FATAL("bad target");
533    }
534}
535
536bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
537{
538    if (value != devSampleRate || resampler != NULL) {
539        if (sampleRate != value) {
540            sampleRate = value;
541            if (resampler == NULL) {
542                ALOGV("creating resampler from track %d Hz to device %d Hz", value, devSampleRate);
543                AudioResampler::src_quality quality;
544                // force lowest quality level resampler if use case isn't music or video
545                // FIXME this is flawed for dynamic sample rates, as we choose the resampler
546                // quality level based on the initial ratio, but that could change later.
547                // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
548                if (!((value == 44100 && devSampleRate == 48000) ||
549                      (value == 48000 && devSampleRate == 44100))) {
550                    quality = AudioResampler::LOW_QUALITY;
551                } else {
552                    quality = AudioResampler::DEFAULT_QUALITY;
553                }
554                resampler = AudioResampler::create(
555                        format,
556                        // the resampler sees the number of channels after the downmixer, if any
557                        downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount,
558                        devSampleRate, quality);
559                resampler->setLocalTimeFreq(localTimeFreq);
560            }
561            return true;
562        }
563    }
564    return false;
565}
566
567inline
568void AudioMixer::track_t::adjustVolumeRamp(bool aux)
569{
570    for (uint32_t i=0 ; i<MAX_NUM_CHANNELS ; i++) {
571        if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
572            ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
573            volumeInc[i] = 0;
574            prevVolume[i] = volume[i]<<16;
575        }
576    }
577    if (aux) {
578        if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
579            ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
580            auxInc = 0;
581            prevAuxLevel = auxLevel<<16;
582        }
583    }
584}
585
586size_t AudioMixer::getUnreleasedFrames(int name) const
587{
588    name -= TRACK0;
589    if (uint32_t(name) < MAX_NUM_TRACKS) {
590        return mState.tracks[name].getUnreleasedFrames();
591    }
592    return 0;
593}
594
595void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
596{
597    name -= TRACK0;
598    ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
599
600    if (mState.tracks[name].downmixerBufferProvider != NULL) {
601        // update required?
602        if (mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider != bufferProvider) {
603            ALOGV("AudioMixer::setBufferProvider(%p) for downmix", bufferProvider);
604            // setting the buffer provider for a track that gets downmixed consists in:
605            //  1/ setting the buffer provider to the "downmix / buffer provider" wrapper
606            //     so it's the one that gets called when the buffer provider is needed,
607            mState.tracks[name].bufferProvider = mState.tracks[name].downmixerBufferProvider;
608            //  2/ saving the buffer provider for the track so the wrapper can use it
609            //     when it downmixes.
610            mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider = bufferProvider;
611        }
612    } else {
613        mState.tracks[name].bufferProvider = bufferProvider;
614    }
615}
616
617
618
619void AudioMixer::process(int64_t pts)
620{
621    mState.hook(&mState, pts);
622}
623
624
625void AudioMixer::process__validate(state_t* state, int64_t pts)
626{
627    ALOGW_IF(!state->needsChanged,
628        "in process__validate() but nothing's invalid");
629
630    uint32_t changed = state->needsChanged;
631    state->needsChanged = 0; // clear the validation flag
632
633    // recompute which tracks are enabled / disabled
634    uint32_t enabled = 0;
635    uint32_t disabled = 0;
636    while (changed) {
637        const int i = 31 - __builtin_clz(changed);
638        const uint32_t mask = 1<<i;
639        changed &= ~mask;
640        track_t& t = state->tracks[i];
641        (t.enabled ? enabled : disabled) |= mask;
642    }
643    state->enabledTracks &= ~disabled;
644    state->enabledTracks |=  enabled;
645
646    // compute everything we need...
647    int countActiveTracks = 0;
648    bool all16BitsStereoNoResample = true;
649    bool resampling = false;
650    bool volumeRamp = false;
651    uint32_t en = state->enabledTracks;
652    while (en) {
653        const int i = 31 - __builtin_clz(en);
654        en &= ~(1<<i);
655
656        countActiveTracks++;
657        track_t& t = state->tracks[i];
658        uint32_t n = 0;
659        n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
660        n |= NEEDS_FORMAT_16;
661        n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
662        if (t.auxLevel != 0 && t.auxBuffer != NULL) {
663            n |= NEEDS_AUX_ENABLED;
664        }
665
666        if (t.volumeInc[0]|t.volumeInc[1]) {
667            volumeRamp = true;
668        } else if (!t.doesResample() && t.volumeRL == 0) {
669            n |= NEEDS_MUTE_ENABLED;
670        }
671        t.needs = n;
672
673        if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
674            t.hook = track__nop;
675        } else {
676            if ((n & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
677                all16BitsStereoNoResample = false;
678            }
679            if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
680                all16BitsStereoNoResample = false;
681                resampling = true;
682                t.hook = track__genericResample;
683                ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
684                        "Track %d needs downmix + resample", i);
685            } else {
686                if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
687                    t.hook = track__16BitsMono;
688                    all16BitsStereoNoResample = false;
689                }
690                if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
691                    t.hook = track__16BitsStereo;
692                    ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
693                            "Track %d needs downmix", i);
694                }
695            }
696        }
697    }
698
699    // select the processing hooks
700    state->hook = process__nop;
701    if (countActiveTracks) {
702        if (resampling) {
703            if (!state->outputTemp) {
704                state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
705            }
706            if (!state->resampleTemp) {
707                state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
708            }
709            state->hook = process__genericResampling;
710        } else {
711            if (state->outputTemp) {
712                delete [] state->outputTemp;
713                state->outputTemp = NULL;
714            }
715            if (state->resampleTemp) {
716                delete [] state->resampleTemp;
717                state->resampleTemp = NULL;
718            }
719            state->hook = process__genericNoResampling;
720            if (all16BitsStereoNoResample && !volumeRamp) {
721                if (countActiveTracks == 1) {
722                    state->hook = process__OneTrack16BitsStereoNoResampling;
723                }
724            }
725        }
726    }
727
728    ALOGV("mixer configuration change: %d activeTracks (%08x) "
729        "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
730        countActiveTracks, state->enabledTracks,
731        all16BitsStereoNoResample, resampling, volumeRamp);
732
733   state->hook(state, pts);
734
735    // Now that the volume ramp has been done, set optimal state and
736    // track hooks for subsequent mixer process
737    if (countActiveTracks) {
738        bool allMuted = true;
739        uint32_t en = state->enabledTracks;
740        while (en) {
741            const int i = 31 - __builtin_clz(en);
742            en &= ~(1<<i);
743            track_t& t = state->tracks[i];
744            if (!t.doesResample() && t.volumeRL == 0)
745            {
746                t.needs |= NEEDS_MUTE_ENABLED;
747                t.hook = track__nop;
748            } else {
749                allMuted = false;
750            }
751        }
752        if (allMuted) {
753            state->hook = process__nop;
754        } else if (all16BitsStereoNoResample) {
755            if (countActiveTracks == 1) {
756                state->hook = process__OneTrack16BitsStereoNoResampling;
757            }
758        }
759    }
760}
761
762
763void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
764{
765    t->resampler->setSampleRate(t->sampleRate);
766
767    // ramp gain - resample to temp buffer and scale/mix in 2nd step
768    if (aux != NULL) {
769        // always resample with unity gain when sending to auxiliary buffer to be able
770        // to apply send level after resampling
771        // TODO: modify each resampler to support aux channel?
772        t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
773        memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
774        t->resampler->resample(temp, outFrameCount, t->bufferProvider);
775        if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
776            volumeRampStereo(t, out, outFrameCount, temp, aux);
777        } else {
778            volumeStereo(t, out, outFrameCount, temp, aux);
779        }
780    } else {
781        if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
782            t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
783            memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
784            t->resampler->resample(temp, outFrameCount, t->bufferProvider);
785            volumeRampStereo(t, out, outFrameCount, temp, aux);
786        }
787
788        // constant gain
789        else {
790            t->resampler->setVolume(t->volume[0], t->volume[1]);
791            t->resampler->resample(out, outFrameCount, t->bufferProvider);
792        }
793    }
794}
795
796void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
797{
798}
799
800void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
801{
802    int32_t vl = t->prevVolume[0];
803    int32_t vr = t->prevVolume[1];
804    const int32_t vlInc = t->volumeInc[0];
805    const int32_t vrInc = t->volumeInc[1];
806
807    //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
808    //        t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
809    //       (vl + vlInc*frameCount)/65536.0f, frameCount);
810
811    // ramp volume
812    if (CC_UNLIKELY(aux != NULL)) {
813        int32_t va = t->prevAuxLevel;
814        const int32_t vaInc = t->auxInc;
815        int32_t l;
816        int32_t r;
817
818        do {
819            l = (*temp++ >> 12);
820            r = (*temp++ >> 12);
821            *out++ += (vl >> 16) * l;
822            *out++ += (vr >> 16) * r;
823            *aux++ += (va >> 17) * (l + r);
824            vl += vlInc;
825            vr += vrInc;
826            va += vaInc;
827        } while (--frameCount);
828        t->prevAuxLevel = va;
829    } else {
830        do {
831            *out++ += (vl >> 16) * (*temp++ >> 12);
832            *out++ += (vr >> 16) * (*temp++ >> 12);
833            vl += vlInc;
834            vr += vrInc;
835        } while (--frameCount);
836    }
837    t->prevVolume[0] = vl;
838    t->prevVolume[1] = vr;
839    t->adjustVolumeRamp(aux != NULL);
840}
841
842void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
843{
844    const int16_t vl = t->volume[0];
845    const int16_t vr = t->volume[1];
846
847    if (CC_UNLIKELY(aux != NULL)) {
848        const int16_t va = t->auxLevel;
849        do {
850            int16_t l = (int16_t)(*temp++ >> 12);
851            int16_t r = (int16_t)(*temp++ >> 12);
852            out[0] = mulAdd(l, vl, out[0]);
853            int16_t a = (int16_t)(((int32_t)l + r) >> 1);
854            out[1] = mulAdd(r, vr, out[1]);
855            out += 2;
856            aux[0] = mulAdd(a, va, aux[0]);
857            aux++;
858        } while (--frameCount);
859    } else {
860        do {
861            int16_t l = (int16_t)(*temp++ >> 12);
862            int16_t r = (int16_t)(*temp++ >> 12);
863            out[0] = mulAdd(l, vl, out[0]);
864            out[1] = mulAdd(r, vr, out[1]);
865            out += 2;
866        } while (--frameCount);
867    }
868}
869
870void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
871{
872    const int16_t *in = static_cast<const int16_t *>(t->in);
873
874    if (CC_UNLIKELY(aux != NULL)) {
875        int32_t l;
876        int32_t r;
877        // ramp gain
878        if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
879            int32_t vl = t->prevVolume[0];
880            int32_t vr = t->prevVolume[1];
881            int32_t va = t->prevAuxLevel;
882            const int32_t vlInc = t->volumeInc[0];
883            const int32_t vrInc = t->volumeInc[1];
884            const int32_t vaInc = t->auxInc;
885            // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
886            //        t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
887            //        (vl + vlInc*frameCount)/65536.0f, frameCount);
888
889            do {
890                l = (int32_t)*in++;
891                r = (int32_t)*in++;
892                *out++ += (vl >> 16) * l;
893                *out++ += (vr >> 16) * r;
894                *aux++ += (va >> 17) * (l + r);
895                vl += vlInc;
896                vr += vrInc;
897                va += vaInc;
898            } while (--frameCount);
899
900            t->prevVolume[0] = vl;
901            t->prevVolume[1] = vr;
902            t->prevAuxLevel = va;
903            t->adjustVolumeRamp(true);
904        }
905
906        // constant gain
907        else {
908            const uint32_t vrl = t->volumeRL;
909            const int16_t va = (int16_t)t->auxLevel;
910            do {
911                uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
912                int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
913                in += 2;
914                out[0] = mulAddRL(1, rl, vrl, out[0]);
915                out[1] = mulAddRL(0, rl, vrl, out[1]);
916                out += 2;
917                aux[0] = mulAdd(a, va, aux[0]);
918                aux++;
919            } while (--frameCount);
920        }
921    } else {
922        // ramp gain
923        if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
924            int32_t vl = t->prevVolume[0];
925            int32_t vr = t->prevVolume[1];
926            const int32_t vlInc = t->volumeInc[0];
927            const int32_t vrInc = t->volumeInc[1];
928
929            // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
930            //        t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
931            //        (vl + vlInc*frameCount)/65536.0f, frameCount);
932
933            do {
934                *out++ += (vl >> 16) * (int32_t) *in++;
935                *out++ += (vr >> 16) * (int32_t) *in++;
936                vl += vlInc;
937                vr += vrInc;
938            } while (--frameCount);
939
940            t->prevVolume[0] = vl;
941            t->prevVolume[1] = vr;
942            t->adjustVolumeRamp(false);
943        }
944
945        // constant gain
946        else {
947            const uint32_t vrl = t->volumeRL;
948            do {
949                uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
950                in += 2;
951                out[0] = mulAddRL(1, rl, vrl, out[0]);
952                out[1] = mulAddRL(0, rl, vrl, out[1]);
953                out += 2;
954            } while (--frameCount);
955        }
956    }
957    t->in = in;
958}
959
960void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
961{
962    const int16_t *in = static_cast<int16_t const *>(t->in);
963
964    if (CC_UNLIKELY(aux != NULL)) {
965        // ramp gain
966        if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
967            int32_t vl = t->prevVolume[0];
968            int32_t vr = t->prevVolume[1];
969            int32_t va = t->prevAuxLevel;
970            const int32_t vlInc = t->volumeInc[0];
971            const int32_t vrInc = t->volumeInc[1];
972            const int32_t vaInc = t->auxInc;
973
974            // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
975            //         t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
976            //         (vl + vlInc*frameCount)/65536.0f, frameCount);
977
978            do {
979                int32_t l = *in++;
980                *out++ += (vl >> 16) * l;
981                *out++ += (vr >> 16) * l;
982                *aux++ += (va >> 16) * l;
983                vl += vlInc;
984                vr += vrInc;
985                va += vaInc;
986            } while (--frameCount);
987
988            t->prevVolume[0] = vl;
989            t->prevVolume[1] = vr;
990            t->prevAuxLevel = va;
991            t->adjustVolumeRamp(true);
992        }
993        // constant gain
994        else {
995            const int16_t vl = t->volume[0];
996            const int16_t vr = t->volume[1];
997            const int16_t va = (int16_t)t->auxLevel;
998            do {
999                int16_t l = *in++;
1000                out[0] = mulAdd(l, vl, out[0]);
1001                out[1] = mulAdd(l, vr, out[1]);
1002                out += 2;
1003                aux[0] = mulAdd(l, va, aux[0]);
1004                aux++;
1005            } while (--frameCount);
1006        }
1007    } else {
1008        // ramp gain
1009        if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
1010            int32_t vl = t->prevVolume[0];
1011            int32_t vr = t->prevVolume[1];
1012            const int32_t vlInc = t->volumeInc[0];
1013            const int32_t vrInc = t->volumeInc[1];
1014
1015            // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
1016            //         t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
1017            //         (vl + vlInc*frameCount)/65536.0f, frameCount);
1018
1019            do {
1020                int32_t l = *in++;
1021                *out++ += (vl >> 16) * l;
1022                *out++ += (vr >> 16) * l;
1023                vl += vlInc;
1024                vr += vrInc;
1025            } while (--frameCount);
1026
1027            t->prevVolume[0] = vl;
1028            t->prevVolume[1] = vr;
1029            t->adjustVolumeRamp(false);
1030        }
1031        // constant gain
1032        else {
1033            const int16_t vl = t->volume[0];
1034            const int16_t vr = t->volume[1];
1035            do {
1036                int16_t l = *in++;
1037                out[0] = mulAdd(l, vl, out[0]);
1038                out[1] = mulAdd(l, vr, out[1]);
1039                out += 2;
1040            } while (--frameCount);
1041        }
1042    }
1043    t->in = in;
1044}
1045
1046// no-op case
1047void AudioMixer::process__nop(state_t* state, int64_t pts)
1048{
1049    uint32_t e0 = state->enabledTracks;
1050    size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS;
1051    while (e0) {
1052        // process by group of tracks with same output buffer to
1053        // avoid multiple memset() on same buffer
1054        uint32_t e1 = e0, e2 = e0;
1055        int i = 31 - __builtin_clz(e1);
1056        track_t& t1 = state->tracks[i];
1057        e2 &= ~(1<<i);
1058        while (e2) {
1059            i = 31 - __builtin_clz(e2);
1060            e2 &= ~(1<<i);
1061            track_t& t2 = state->tracks[i];
1062            if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1063                e1 &= ~(1<<i);
1064            }
1065        }
1066        e0 &= ~(e1);
1067
1068        memset(t1.mainBuffer, 0, bufSize);
1069
1070        while (e1) {
1071            i = 31 - __builtin_clz(e1);
1072            e1 &= ~(1<<i);
1073            t1 = state->tracks[i];
1074            size_t outFrames = state->frameCount;
1075            while (outFrames) {
1076                t1.buffer.frameCount = outFrames;
1077                int64_t outputPTS = calculateOutputPTS(
1078                    t1, pts, state->frameCount - outFrames);
1079                t1.bufferProvider->getNextBuffer(&t1.buffer, outputPTS);
1080                if (t1.buffer.raw == NULL) break;
1081                outFrames -= t1.buffer.frameCount;
1082                t1.bufferProvider->releaseBuffer(&t1.buffer);
1083            }
1084        }
1085    }
1086}
1087
1088// generic code without resampling
1089void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
1090{
1091    int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
1092
1093    // acquire each track's buffer
1094    uint32_t enabledTracks = state->enabledTracks;
1095    uint32_t e0 = enabledTracks;
1096    while (e0) {
1097        const int i = 31 - __builtin_clz(e0);
1098        e0 &= ~(1<<i);
1099        track_t& t = state->tracks[i];
1100        t.buffer.frameCount = state->frameCount;
1101        t.bufferProvider->getNextBuffer(&t.buffer, pts);
1102        t.frameCount = t.buffer.frameCount;
1103        t.in = t.buffer.raw;
1104        // t.in == NULL can happen if the track was flushed just after having
1105        // been enabled for mixing.
1106        if (t.in == NULL)
1107            enabledTracks &= ~(1<<i);
1108    }
1109
1110    e0 = enabledTracks;
1111    while (e0) {
1112        // process by group of tracks with same output buffer to
1113        // optimize cache use
1114        uint32_t e1 = e0, e2 = e0;
1115        int j = 31 - __builtin_clz(e1);
1116        track_t& t1 = state->tracks[j];
1117        e2 &= ~(1<<j);
1118        while (e2) {
1119            j = 31 - __builtin_clz(e2);
1120            e2 &= ~(1<<j);
1121            track_t& t2 = state->tracks[j];
1122            if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1123                e1 &= ~(1<<j);
1124            }
1125        }
1126        e0 &= ~(e1);
1127        // this assumes output 16 bits stereo, no resampling
1128        int32_t *out = t1.mainBuffer;
1129        size_t numFrames = 0;
1130        do {
1131            memset(outTemp, 0, sizeof(outTemp));
1132            e2 = e1;
1133            while (e2) {
1134                const int i = 31 - __builtin_clz(e2);
1135                e2 &= ~(1<<i);
1136                track_t& t = state->tracks[i];
1137                size_t outFrames = BLOCKSIZE;
1138                int32_t *aux = NULL;
1139                if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
1140                    aux = t.auxBuffer + numFrames;
1141                }
1142                while (outFrames) {
1143                    size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
1144                    if (inFrames) {
1145                        t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux);
1146                        t.frameCount -= inFrames;
1147                        outFrames -= inFrames;
1148                        if (CC_UNLIKELY(aux != NULL)) {
1149                            aux += inFrames;
1150                        }
1151                    }
1152                    if (t.frameCount == 0 && outFrames) {
1153                        t.bufferProvider->releaseBuffer(&t.buffer);
1154                        t.buffer.frameCount = (state->frameCount - numFrames) - (BLOCKSIZE - outFrames);
1155                        int64_t outputPTS = calculateOutputPTS(
1156                            t, pts, numFrames + (BLOCKSIZE - outFrames));
1157                        t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
1158                        t.in = t.buffer.raw;
1159                        if (t.in == NULL) {
1160                            enabledTracks &= ~(1<<i);
1161                            e1 &= ~(1<<i);
1162                            break;
1163                        }
1164                        t.frameCount = t.buffer.frameCount;
1165                    }
1166                }
1167            }
1168            ditherAndClamp(out, outTemp, BLOCKSIZE);
1169            out += BLOCKSIZE;
1170            numFrames += BLOCKSIZE;
1171        } while (numFrames < state->frameCount);
1172    }
1173
1174    // release each track's buffer
1175    e0 = enabledTracks;
1176    while (e0) {
1177        const int i = 31 - __builtin_clz(e0);
1178        e0 &= ~(1<<i);
1179        track_t& t = state->tracks[i];
1180        t.bufferProvider->releaseBuffer(&t.buffer);
1181    }
1182}
1183
1184
1185// generic code with resampling
1186void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
1187{
1188    // this const just means that local variable outTemp doesn't change
1189    int32_t* const outTemp = state->outputTemp;
1190    const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
1191
1192    size_t numFrames = state->frameCount;
1193
1194    uint32_t e0 = state->enabledTracks;
1195    while (e0) {
1196        // process by group of tracks with same output buffer
1197        // to optimize cache use
1198        uint32_t e1 = e0, e2 = e0;
1199        int j = 31 - __builtin_clz(e1);
1200        track_t& t1 = state->tracks[j];
1201        e2 &= ~(1<<j);
1202        while (e2) {
1203            j = 31 - __builtin_clz(e2);
1204            e2 &= ~(1<<j);
1205            track_t& t2 = state->tracks[j];
1206            if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
1207                e1 &= ~(1<<j);
1208            }
1209        }
1210        e0 &= ~(e1);
1211        int32_t *out = t1.mainBuffer;
1212        memset(outTemp, 0, size);
1213        while (e1) {
1214            const int i = 31 - __builtin_clz(e1);
1215            e1 &= ~(1<<i);
1216            track_t& t = state->tracks[i];
1217            int32_t *aux = NULL;
1218            if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
1219                aux = t.auxBuffer;
1220            }
1221
1222            // this is a little goofy, on the resampling case we don't
1223            // acquire/release the buffers because it's done by
1224            // the resampler.
1225            if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
1226                t.resampler->setPTS(pts);
1227                t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
1228            } else {
1229
1230                size_t outFrames = 0;
1231
1232                while (outFrames < numFrames) {
1233                    t.buffer.frameCount = numFrames - outFrames;
1234                    int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
1235                    t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
1236                    t.in = t.buffer.raw;
1237                    // t.in == NULL can happen if the track was flushed just after having
1238                    // been enabled for mixing.
1239                    if (t.in == NULL) break;
1240
1241                    if (CC_UNLIKELY(aux != NULL)) {
1242                        aux += outFrames;
1243                    }
1244                    t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
1245                    outFrames += t.buffer.frameCount;
1246                    t.bufferProvider->releaseBuffer(&t.buffer);
1247                }
1248            }
1249        }
1250        ditherAndClamp(out, outTemp, numFrames);
1251    }
1252}
1253
1254// one track, 16 bits stereo without resampling is the most common case
1255void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
1256                                                           int64_t pts)
1257{
1258    // This method is only called when state->enabledTracks has exactly
1259    // one bit set.  The asserts below would verify this, but are commented out
1260    // since the whole point of this method is to optimize performance.
1261    //ALOG_ASSERT(0 != state->enabledTracks, "no tracks enabled");
1262    const int i = 31 - __builtin_clz(state->enabledTracks);
1263    //ALOG_ASSERT((1 << i) == state->enabledTracks, "more than 1 track enabled");
1264    const track_t& t = state->tracks[i];
1265
1266    AudioBufferProvider::Buffer& b(t.buffer);
1267
1268    int32_t* out = t.mainBuffer;
1269    size_t numFrames = state->frameCount;
1270
1271    const int16_t vl = t.volume[0];
1272    const int16_t vr = t.volume[1];
1273    const uint32_t vrl = t.volumeRL;
1274    while (numFrames) {
1275        b.frameCount = numFrames;
1276        int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
1277        t.bufferProvider->getNextBuffer(&b, outputPTS);
1278        const int16_t *in = b.i16;
1279
1280        // in == NULL can happen if the track was flushed just after having
1281        // been enabled for mixing.
1282        if (in == NULL || ((unsigned long)in & 3)) {
1283            memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
1284            ALOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: buffer %p track %d, channels %d, needs %08x",
1285                    in, i, t.channelCount, t.needs);
1286            return;
1287        }
1288        size_t outFrames = b.frameCount;
1289
1290        if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
1291            // volume is boosted, so we might need to clamp even though
1292            // we process only one track.
1293            do {
1294                uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1295                in += 2;
1296                int32_t l = mulRL(1, rl, vrl) >> 12;
1297                int32_t r = mulRL(0, rl, vrl) >> 12;
1298                // clamping...
1299                l = clamp16(l);
1300                r = clamp16(r);
1301                *out++ = (r<<16) | (l & 0xFFFF);
1302            } while (--outFrames);
1303        } else {
1304            do {
1305                uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
1306                in += 2;
1307                int32_t l = mulRL(1, rl, vrl) >> 12;
1308                int32_t r = mulRL(0, rl, vrl) >> 12;
1309                *out++ = (r<<16) | (l & 0xFFFF);
1310            } while (--outFrames);
1311        }
1312        numFrames -= b.frameCount;
1313        t.bufferProvider->releaseBuffer(&b);
1314    }
1315}
1316
1317#if 0
1318// 2 tracks is also a common case
1319// NEVER used in current implementation of process__validate()
1320// only use if the 2 tracks have the same output buffer
1321void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state,
1322                                                            int64_t pts)
1323{
1324    int i;
1325    uint32_t en = state->enabledTracks;
1326
1327    i = 31 - __builtin_clz(en);
1328    const track_t& t0 = state->tracks[i];
1329    AudioBufferProvider::Buffer& b0(t0.buffer);
1330
1331    en &= ~(1<<i);
1332    i = 31 - __builtin_clz(en);
1333    const track_t& t1 = state->tracks[i];
1334    AudioBufferProvider::Buffer& b1(t1.buffer);
1335
1336    const int16_t *in0;
1337    const int16_t vl0 = t0.volume[0];
1338    const int16_t vr0 = t0.volume[1];
1339    size_t frameCount0 = 0;
1340
1341    const int16_t *in1;
1342    const int16_t vl1 = t1.volume[0];
1343    const int16_t vr1 = t1.volume[1];
1344    size_t frameCount1 = 0;
1345
1346    //FIXME: only works if two tracks use same buffer
1347    int32_t* out = t0.mainBuffer;
1348    size_t numFrames = state->frameCount;
1349    const int16_t *buff = NULL;
1350
1351
1352    while (numFrames) {
1353
1354        if (frameCount0 == 0) {
1355            b0.frameCount = numFrames;
1356            int64_t outputPTS = calculateOutputPTS(t0, pts,
1357                                                   out - t0.mainBuffer);
1358            t0.bufferProvider->getNextBuffer(&b0, outputPTS);
1359            if (b0.i16 == NULL) {
1360                if (buff == NULL) {
1361                    buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1362                }
1363                in0 = buff;
1364                b0.frameCount = numFrames;
1365            } else {
1366                in0 = b0.i16;
1367            }
1368            frameCount0 = b0.frameCount;
1369        }
1370        if (frameCount1 == 0) {
1371            b1.frameCount = numFrames;
1372            int64_t outputPTS = calculateOutputPTS(t1, pts,
1373                                                   out - t0.mainBuffer);
1374            t1.bufferProvider->getNextBuffer(&b1, outputPTS);
1375            if (b1.i16 == NULL) {
1376                if (buff == NULL) {
1377                    buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
1378                }
1379                in1 = buff;
1380                b1.frameCount = numFrames;
1381            } else {
1382                in1 = b1.i16;
1383            }
1384            frameCount1 = b1.frameCount;
1385        }
1386
1387        size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
1388
1389        numFrames -= outFrames;
1390        frameCount0 -= outFrames;
1391        frameCount1 -= outFrames;
1392
1393        do {
1394            int32_t l0 = *in0++;
1395            int32_t r0 = *in0++;
1396            l0 = mul(l0, vl0);
1397            r0 = mul(r0, vr0);
1398            int32_t l = *in1++;
1399            int32_t r = *in1++;
1400            l = mulAdd(l, vl1, l0) >> 12;
1401            r = mulAdd(r, vr1, r0) >> 12;
1402            // clamping...
1403            l = clamp16(l);
1404            r = clamp16(r);
1405            *out++ = (r<<16) | (l & 0xFFFF);
1406        } while (--outFrames);
1407
1408        if (frameCount0 == 0) {
1409            t0.bufferProvider->releaseBuffer(&b0);
1410        }
1411        if (frameCount1 == 0) {
1412            t1.bufferProvider->releaseBuffer(&b1);
1413        }
1414    }
1415
1416    delete [] buff;
1417}
1418#endif
1419
1420int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
1421                                       int outputFrameIndex)
1422{
1423    if (AudioBufferProvider::kInvalidPTS == basePTS)
1424        return AudioBufferProvider::kInvalidPTS;
1425
1426    return basePTS + ((outputFrameIndex * t.localTimeFreq) / t.sampleRate);
1427}
1428
1429// ----------------------------------------------------------------------------
1430}; // namespace android
1431