FastMixer.cpp revision e4a7ce250cb94a00aa2f76e5edca1c4479dc5401
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// <IMPORTANT_WARNING>
18// Design rules for threadLoop() are given in the comments at section "Fast mixer thread" of
19// StateQueue.h.  In particular, avoid library and system calls except at well-known points.
20// The design rules are only for threadLoop(), and don't apply to FastMixerDumpState methods.
21// </IMPORTANT_WARNING>
22
23#define LOG_TAG "FastMixer"
24//#define LOG_NDEBUG 0
25
26#define ATRACE_TAG ATRACE_TAG_AUDIO
27
28#include "Configuration.h"
29#include <time.h>
30#include <utils/Debug.h>
31#include <utils/Log.h>
32#include <utils/Trace.h>
33#include <system/audio.h>
34#ifdef FAST_THREAD_STATISTICS
35#include <cpustats/CentralTendencyStatistics.h>
36#ifdef CPU_FREQUENCY_STATISTICS
37#include <cpustats/ThreadCpuUsage.h>
38#endif
39#endif
40#include <audio_utils/format.h>
41#include "AudioMixer.h"
42#include "FastMixer.h"
43
44#define FCC_2                       2   // fixed channel count assumption
45
46namespace android {
47
48/*static*/ const FastMixerState FastMixer::sInitial;
49
50FastMixer::FastMixer() : FastThread(),
51    mSlopNs(0),
52    // mFastTrackNames
53    // mGenerations
54    mOutputSink(NULL),
55    mOutputSinkGen(0),
56    mMixer(NULL),
57    mSinkBuffer(NULL),
58    mSinkBufferSize(0),
59    mSinkChannelCount(FCC_2),
60    mMixerBuffer(NULL),
61    mMixerBufferSize(0),
62    mMixerBufferFormat(AUDIO_FORMAT_PCM_16_BIT),
63    mMixerBufferState(UNDEFINED),
64    mFormat(Format_Invalid),
65    mSampleRate(0),
66    mFastTracksGen(0),
67    mTotalNativeFramesWritten(0),
68    // timestamp
69    mNativeFramesWrittenButNotPresented(0)   // the = 0 is to silence the compiler
70{
71    // FIXME pass sInitial as parameter to base class constructor, and make it static local
72    mPrevious = &sInitial;
73    mCurrent = &sInitial;
74
75    mDummyDumpState = &mDummyFastMixerDumpState;
76    // TODO: Add channel mask to NBAIO_Format.
77    // We assume that the channel mask must be a valid positional channel mask.
78    mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount);
79
80    unsigned i;
81    for (i = 0; i < FastMixerState::kMaxFastTracks; ++i) {
82        mFastTrackNames[i] = -1;
83        mGenerations[i] = 0;
84    }
85#ifdef FAST_THREAD_STATISTICS
86    mOldLoad.tv_sec = 0;
87    mOldLoad.tv_nsec = 0;
88#endif
89}
90
91FastMixer::~FastMixer()
92{
93}
94
95FastMixerStateQueue* FastMixer::sq()
96{
97    return &mSQ;
98}
99
100const FastThreadState *FastMixer::poll()
101{
102    return mSQ.poll();
103}
104
105void FastMixer::setLog(NBLog::Writer *logWriter)
106{
107    if (mMixer != NULL) {
108        mMixer->setLog(logWriter);
109    }
110}
111
112void FastMixer::onIdle()
113{
114    mPreIdle = *(const FastMixerState *)mCurrent;
115    mCurrent = &mPreIdle;
116}
117
118void FastMixer::onExit()
119{
120    delete mMixer;
121    free(mMixerBuffer);
122    free(mSinkBuffer);
123}
124
125bool FastMixer::isSubClassCommand(FastThreadState::Command command)
126{
127    switch ((FastMixerState::Command) command) {
128    case FastMixerState::MIX:
129    case FastMixerState::WRITE:
130    case FastMixerState::MIX_WRITE:
131        return true;
132    default:
133        return false;
134    }
135}
136
137void FastMixer::onStateChange()
138{
139    const FastMixerState * const current = (const FastMixerState *) this->mCurrent;
140    const FastMixerState * const previous = (const FastMixerState *) this->mPrevious;
141    FastMixerDumpState * const dumpState = (FastMixerDumpState *) this->mDumpState;
142    const size_t frameCount = current->mFrameCount;
143
144    // handle state change here, but since we want to diff the state,
145    // we're prepared for previous == &sInitial the first time through
146    unsigned previousTrackMask;
147
148    // check for change in output HAL configuration
149    NBAIO_Format previousFormat = mFormat;
150    if (current->mOutputSinkGen != mOutputSinkGen) {
151        mOutputSink = current->mOutputSink;
152        mOutputSinkGen = current->mOutputSinkGen;
153        if (mOutputSink == NULL) {
154            mFormat = Format_Invalid;
155            mSampleRate = 0;
156            mSinkChannelCount = 0;
157            mSinkChannelMask = AUDIO_CHANNEL_NONE;
158        } else {
159            mFormat = mOutputSink->format();
160            mSampleRate = Format_sampleRate(mFormat);
161            mSinkChannelCount = Format_channelCount(mFormat);
162            LOG_ALWAYS_FATAL_IF(mSinkChannelCount > AudioMixer::MAX_NUM_CHANNELS);
163
164            // TODO: Add channel mask to NBAIO_Format
165            // We assume that the channel mask must be a valid positional channel mask.
166            mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount);
167        }
168        dumpState->mSampleRate = mSampleRate;
169    }
170
171    if ((!Format_isEqual(mFormat, previousFormat)) || (frameCount != previous->mFrameCount)) {
172        // FIXME to avoid priority inversion, don't delete here
173        delete mMixer;
174        mMixer = NULL;
175        free(mMixerBuffer);
176        mMixerBuffer = NULL;
177        free(mSinkBuffer);
178        mSinkBuffer = NULL;
179        if (frameCount > 0 && mSampleRate > 0) {
180            // FIXME new may block for unbounded time at internal mutex of the heap
181            //       implementation; it would be better to have normal mixer allocate for us
182            //       to avoid blocking here and to prevent possible priority inversion
183            mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::kMaxFastTracks);
184            const size_t mixerFrameSize = mSinkChannelCount
185                    * audio_bytes_per_sample(mMixerBufferFormat);
186            mMixerBufferSize = mixerFrameSize * frameCount;
187            (void)posix_memalign(&mMixerBuffer, 32, mMixerBufferSize);
188            const size_t sinkFrameSize = mSinkChannelCount
189                    * audio_bytes_per_sample(mFormat.mFormat);
190            if (sinkFrameSize > mixerFrameSize) { // need a sink buffer
191                mSinkBufferSize = sinkFrameSize * frameCount;
192                (void)posix_memalign(&mSinkBuffer, 32, mSinkBufferSize);
193            }
194            mPeriodNs = (frameCount * 1000000000LL) / mSampleRate;    // 1.00
195            mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate;  // 1.75
196            mOverrunNs = (frameCount * 500000000LL) / mSampleRate;    // 0.50
197            mForceNs = (frameCount * 950000000LL) / mSampleRate;      // 0.95
198            mWarmupNsMin = (frameCount * 750000000LL) / mSampleRate;  // 0.75
199            mWarmupNsMax = (frameCount * 1250000000LL) / mSampleRate; // 1.25
200        } else {
201            mPeriodNs = 0;
202            mUnderrunNs = 0;
203            mOverrunNs = 0;
204            mForceNs = 0;
205            mWarmupNsMin = 0;
206            mWarmupNsMax = LONG_MAX;
207        }
208        mMixerBufferState = UNDEFINED;
209#if !LOG_NDEBUG
210        for (unsigned i = 0; i < FastMixerState::kMaxFastTracks; ++i) {
211            mFastTrackNames[i] = -1;
212        }
213#endif
214        // we need to reconfigure all active tracks
215        previousTrackMask = 0;
216        mFastTracksGen = current->mFastTracksGen - 1;
217        dumpState->mFrameCount = frameCount;
218    } else {
219        previousTrackMask = previous->mTrackMask;
220    }
221
222    // check for change in active track set
223    const unsigned currentTrackMask = current->mTrackMask;
224    dumpState->mTrackMask = currentTrackMask;
225    if (current->mFastTracksGen != mFastTracksGen) {
226        ALOG_ASSERT(mMixerBuffer != NULL);
227        int name;
228
229        // process removed tracks first to avoid running out of track names
230        unsigned removedTracks = previousTrackMask & ~currentTrackMask;
231        while (removedTracks != 0) {
232            int i = __builtin_ctz(removedTracks);
233            removedTracks &= ~(1 << i);
234            const FastTrack* fastTrack = &current->mFastTracks[i];
235            ALOG_ASSERT(fastTrack->mBufferProvider == NULL);
236            if (mMixer != NULL) {
237                name = mFastTrackNames[i];
238                ALOG_ASSERT(name >= 0);
239                mMixer->deleteTrackName(name);
240            }
241#if !LOG_NDEBUG
242            mFastTrackNames[i] = -1;
243#endif
244            // don't reset track dump state, since other side is ignoring it
245            mGenerations[i] = fastTrack->mGeneration;
246        }
247
248        // now process added tracks
249        unsigned addedTracks = currentTrackMask & ~previousTrackMask;
250        while (addedTracks != 0) {
251            int i = __builtin_ctz(addedTracks);
252            addedTracks &= ~(1 << i);
253            const FastTrack* fastTrack = &current->mFastTracks[i];
254            AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
255            ALOG_ASSERT(bufferProvider != NULL && mFastTrackNames[i] == -1);
256            if (mMixer != NULL) {
257                name = mMixer->getTrackName(fastTrack->mChannelMask,
258                        fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
259                ALOG_ASSERT(name >= 0);
260                mFastTrackNames[i] = name;
261                mMixer->setBufferProvider(name, bufferProvider);
262                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
263                        (void *)mMixerBuffer);
264                // newly allocated track names default to full scale volume
265                mMixer->setParameter(
266                        name,
267                        AudioMixer::TRACK,
268                        AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
269                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
270                        (void *)(uintptr_t)fastTrack->mFormat);
271                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
272                        (void *)(uintptr_t)fastTrack->mChannelMask);
273                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
274                        (void *)(uintptr_t)mSinkChannelMask);
275                mMixer->enable(name);
276            }
277            mGenerations[i] = fastTrack->mGeneration;
278        }
279
280        // finally process (potentially) modified tracks; these use the same slot
281        // but may have a different buffer provider or volume provider
282        unsigned modifiedTracks = currentTrackMask & previousTrackMask;
283        while (modifiedTracks != 0) {
284            int i = __builtin_ctz(modifiedTracks);
285            modifiedTracks &= ~(1 << i);
286            const FastTrack* fastTrack = &current->mFastTracks[i];
287            if (fastTrack->mGeneration != mGenerations[i]) {
288                // this track was actually modified
289                AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
290                ALOG_ASSERT(bufferProvider != NULL);
291                if (mMixer != NULL) {
292                    name = mFastTrackNames[i];
293                    ALOG_ASSERT(name >= 0);
294                    mMixer->setBufferProvider(name, bufferProvider);
295                    if (fastTrack->mVolumeProvider == NULL) {
296                        float f = AudioMixer::UNITY_GAIN_FLOAT;
297                        mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &f);
298                        mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &f);
299                    }
300                    mMixer->setParameter(name, AudioMixer::RESAMPLE,
301                            AudioMixer::REMOVE, NULL);
302                    mMixer->setParameter(
303                            name,
304                            AudioMixer::TRACK,
305                            AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
306                    mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
307                            (void *)(uintptr_t)fastTrack->mFormat);
308                    mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
309                            (void *)(uintptr_t)fastTrack->mChannelMask);
310                    mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
311                            (void *)(uintptr_t)mSinkChannelMask);
312                    // already enabled
313                }
314                mGenerations[i] = fastTrack->mGeneration;
315            }
316        }
317
318        mFastTracksGen = current->mFastTracksGen;
319
320        dumpState->mNumTracks = popcount(currentTrackMask);
321    }
322}
323
324void FastMixer::onWork()
325{
326    const FastMixerState * const current = (const FastMixerState *) this->mCurrent;
327    FastMixerDumpState * const dumpState = (FastMixerDumpState *) this->mDumpState;
328    const FastMixerState::Command command = this->mCommand;
329    const size_t frameCount = current->mFrameCount;
330
331    if ((command & FastMixerState::MIX) && (mMixer != NULL) && mIsWarm) {
332        ALOG_ASSERT(mMixerBuffer != NULL);
333        // for each track, update volume and check for underrun
334        unsigned currentTrackMask = current->mTrackMask;
335        while (currentTrackMask != 0) {
336            int i = __builtin_ctz(currentTrackMask);
337            currentTrackMask &= ~(1 << i);
338            const FastTrack* fastTrack = &current->mFastTracks[i];
339
340            // Refresh the per-track timestamp
341            if (mTimestampStatus == NO_ERROR) {
342                uint32_t trackFramesWrittenButNotPresented =
343                    mNativeFramesWrittenButNotPresented;
344                uint32_t trackFramesWritten = fastTrack->mBufferProvider->framesReleased();
345                // Can't provide an AudioTimestamp before first frame presented,
346                // or during the brief 32-bit wraparound window
347                if (trackFramesWritten >= trackFramesWrittenButNotPresented) {
348                    AudioTimestamp perTrackTimestamp;
349                    perTrackTimestamp.mPosition =
350                            trackFramesWritten - trackFramesWrittenButNotPresented;
351                    perTrackTimestamp.mTime = mTimestamp.mTime;
352                    fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp);
353                }
354            }
355
356            int name = mFastTrackNames[i];
357            ALOG_ASSERT(name >= 0);
358            if (fastTrack->mVolumeProvider != NULL) {
359                gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
360                float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
361                float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
362
363                mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &vlf);
364                mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &vrf);
365            }
366            // FIXME The current implementation of framesReady() for fast tracks
367            // takes a tryLock, which can block
368            // up to 1 ms.  If enough active tracks all blocked in sequence, this would result
369            // in the overall fast mix cycle being delayed.  Should use a non-blocking FIFO.
370            size_t framesReady = fastTrack->mBufferProvider->framesReady();
371            if (ATRACE_ENABLED()) {
372                // I wish we had formatted trace names
373                char traceName[16];
374                strcpy(traceName, "fRdy");
375                traceName[4] = i + (i < 10 ? '0' : 'A' - 10);
376                traceName[5] = '\0';
377                ATRACE_INT(traceName, framesReady);
378            }
379            FastTrackDump *ftDump = &dumpState->mTracks[i];
380            FastTrackUnderruns underruns = ftDump->mUnderruns;
381            if (framesReady < frameCount) {
382                if (framesReady == 0) {
383                    underruns.mBitFields.mEmpty++;
384                    underruns.mBitFields.mMostRecent = UNDERRUN_EMPTY;
385                    mMixer->disable(name);
386                } else {
387                    // allow mixing partial buffer
388                    underruns.mBitFields.mPartial++;
389                    underruns.mBitFields.mMostRecent = UNDERRUN_PARTIAL;
390                    mMixer->enable(name);
391                }
392            } else {
393                underruns.mBitFields.mFull++;
394                underruns.mBitFields.mMostRecent = UNDERRUN_FULL;
395                mMixer->enable(name);
396            }
397            ftDump->mUnderruns = underruns;
398            ftDump->mFramesReady = framesReady;
399        }
400
401        int64_t pts;
402        if (mOutputSink == NULL || (OK != mOutputSink->getNextWriteTimestamp(&pts))) {
403            pts = AudioBufferProvider::kInvalidPTS;
404        }
405
406        // process() is CPU-bound
407        mMixer->process(pts);
408        mMixerBufferState = MIXED;
409    } else if (mMixerBufferState == MIXED) {
410        mMixerBufferState = UNDEFINED;
411    }
412    //bool didFullWrite = false;    // dumpsys could display a count of partial writes
413    if ((command & FastMixerState::WRITE) && (mOutputSink != NULL) && (mMixerBuffer != NULL)) {
414        if (mMixerBufferState == UNDEFINED) {
415            memset(mMixerBuffer, 0, mMixerBufferSize);
416            mMixerBufferState = ZEROED;
417        }
418        void *buffer = mSinkBuffer != NULL ? mSinkBuffer : mMixerBuffer;
419        if (mFormat.mFormat != mMixerBufferFormat) { // sink format not the same as mixer format
420            memcpy_by_audio_format(buffer, mFormat.mFormat, mMixerBuffer, mMixerBufferFormat,
421                    frameCount * Format_channelCount(mFormat));
422        }
423        // if non-NULL, then duplicate write() to this non-blocking sink
424        NBAIO_Sink* teeSink;
425        if ((teeSink = current->mTeeSink) != NULL) {
426            (void) teeSink->write(buffer, frameCount);
427        }
428        // FIXME write() is non-blocking and lock-free for a properly implemented NBAIO sink,
429        //       but this code should be modified to handle both non-blocking and blocking sinks
430        dumpState->mWriteSequence++;
431        ATRACE_BEGIN("write");
432        ssize_t framesWritten = mOutputSink->write(buffer, frameCount);
433        ATRACE_END();
434        dumpState->mWriteSequence++;
435        if (framesWritten >= 0) {
436            ALOG_ASSERT((size_t) framesWritten <= frameCount);
437            mTotalNativeFramesWritten += framesWritten;
438            dumpState->mFramesWritten = mTotalNativeFramesWritten;
439            //if ((size_t) framesWritten == frameCount) {
440            //    didFullWrite = true;
441            //}
442        } else {
443            dumpState->mWriteErrors++;
444        }
445        mAttemptedWrite = true;
446        // FIXME count # of writes blocked excessively, CPU usage, etc. for dump
447
448        mTimestampStatus = mOutputSink->getTimestamp(mTimestamp);
449        if (mTimestampStatus == NO_ERROR) {
450            uint32_t totalNativeFramesPresented = mTimestamp.mPosition;
451            if (totalNativeFramesPresented <= mTotalNativeFramesWritten) {
452                mNativeFramesWrittenButNotPresented =
453                    mTotalNativeFramesWritten - totalNativeFramesPresented;
454            } else {
455                // HAL reported that more frames were presented than were written
456                mTimestampStatus = INVALID_OPERATION;
457            }
458        }
459    }
460}
461
462}   // namespace android
463