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