FastMixer.cpp revision 818e7a32ce3633980138aff2c2bfcc5158b3cfcc
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/conversion.h>
41#include <audio_utils/format.h>
42#include "AudioMixer.h"
43#include "FastMixer.h"
44
45namespace android {
46
47/*static*/ const FastMixerState FastMixer::sInitial;
48
49FastMixer::FastMixer() : FastThread(),
50    mSlopNs(0),
51    // mFastTrackNames
52    // mGenerations
53    mOutputSink(NULL),
54    mOutputSinkGen(0),
55    mMixer(NULL),
56    mSinkBuffer(NULL),
57    mSinkBufferSize(0),
58    mSinkChannelCount(FCC_2),
59    mMixerBuffer(NULL),
60    mMixerBufferSize(0),
61    mMixerBufferFormat(AUDIO_FORMAT_PCM_16_BIT),
62    mMixerBufferState(UNDEFINED),
63    mFormat(Format_Invalid),
64    mSampleRate(0),
65    mFastTracksGen(0),
66    mTotalNativeFramesWritten(0),
67    // timestamp
68    mNativeFramesWrittenButNotPresented(0),   // the = 0 is to silence the compiler
69    mMasterMono(false)
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 *) mCurrent;
140    const FastMixerState * const previous = (const FastMixerState *) mPrevious;
141    FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
142    const size_t frameCount = current->mFrameCount;
143
144    // update boottime offset, in case it has changed
145    mTimestamp.mTimebaseOffset[ExtendedTimestamp::TIMEBASE_BOOTTIME] =
146            mBoottimeOffset.load();
147
148    // handle state change here, but since we want to diff the state,
149    // we're prepared for previous == &sInitial the first time through
150    unsigned previousTrackMask;
151
152    // check for change in output HAL configuration
153    NBAIO_Format previousFormat = mFormat;
154    if (current->mOutputSinkGen != mOutputSinkGen) {
155        mOutputSink = current->mOutputSink;
156        mOutputSinkGen = current->mOutputSinkGen;
157        if (mOutputSink == NULL) {
158            mFormat = Format_Invalid;
159            mSampleRate = 0;
160            mSinkChannelCount = 0;
161            mSinkChannelMask = AUDIO_CHANNEL_NONE;
162        } else {
163            mFormat = mOutputSink->format();
164            mSampleRate = Format_sampleRate(mFormat);
165            mSinkChannelCount = Format_channelCount(mFormat);
166            LOG_ALWAYS_FATAL_IF(mSinkChannelCount > AudioMixer::MAX_NUM_CHANNELS);
167
168            // TODO: Add channel mask to NBAIO_Format
169            // We assume that the channel mask must be a valid positional channel mask.
170            mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount);
171        }
172        dumpState->mSampleRate = mSampleRate;
173    }
174
175    if ((!Format_isEqual(mFormat, previousFormat)) || (frameCount != previous->mFrameCount)) {
176        // FIXME to avoid priority inversion, don't delete here
177        delete mMixer;
178        mMixer = NULL;
179        free(mMixerBuffer);
180        mMixerBuffer = NULL;
181        free(mSinkBuffer);
182        mSinkBuffer = NULL;
183        if (frameCount > 0 && mSampleRate > 0) {
184            // The mixer produces either 16 bit PCM or float output, select
185            // float output if the HAL supports higher than 16 bit precision.
186            mMixerBufferFormat = mFormat.mFormat == AUDIO_FORMAT_PCM_16_BIT ?
187                    AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_FLOAT;
188            // FIXME new may block for unbounded time at internal mutex of the heap
189            //       implementation; it would be better to have normal mixer allocate for us
190            //       to avoid blocking here and to prevent possible priority inversion
191            mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::kMaxFastTracks);
192            const size_t mixerFrameSize = mSinkChannelCount
193                    * audio_bytes_per_sample(mMixerBufferFormat);
194            mMixerBufferSize = mixerFrameSize * frameCount;
195            (void)posix_memalign(&mMixerBuffer, 32, mMixerBufferSize);
196            const size_t sinkFrameSize = mSinkChannelCount
197                    * audio_bytes_per_sample(mFormat.mFormat);
198            if (sinkFrameSize > mixerFrameSize) { // need a sink buffer
199                mSinkBufferSize = sinkFrameSize * frameCount;
200                (void)posix_memalign(&mSinkBuffer, 32, mSinkBufferSize);
201            }
202            mPeriodNs = (frameCount * 1000000000LL) / mSampleRate;    // 1.00
203            mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate;  // 1.75
204            mOverrunNs = (frameCount * 500000000LL) / mSampleRate;    // 0.50
205            mForceNs = (frameCount * 950000000LL) / mSampleRate;      // 0.95
206            mWarmupNsMin = (frameCount * 750000000LL) / mSampleRate;  // 0.75
207            mWarmupNsMax = (frameCount * 1250000000LL) / mSampleRate; // 1.25
208        } else {
209            mPeriodNs = 0;
210            mUnderrunNs = 0;
211            mOverrunNs = 0;
212            mForceNs = 0;
213            mWarmupNsMin = 0;
214            mWarmupNsMax = LONG_MAX;
215        }
216        mMixerBufferState = UNDEFINED;
217#if !LOG_NDEBUG
218        for (unsigned i = 0; i < FastMixerState::kMaxFastTracks; ++i) {
219            mFastTrackNames[i] = -1;
220        }
221#endif
222        // we need to reconfigure all active tracks
223        previousTrackMask = 0;
224        mFastTracksGen = current->mFastTracksGen - 1;
225        dumpState->mFrameCount = frameCount;
226    } else {
227        previousTrackMask = previous->mTrackMask;
228    }
229
230    // check for change in active track set
231    const unsigned currentTrackMask = current->mTrackMask;
232    dumpState->mTrackMask = currentTrackMask;
233    if (current->mFastTracksGen != mFastTracksGen) {
234        ALOG_ASSERT(mMixerBuffer != NULL);
235        int name;
236
237        // process removed tracks first to avoid running out of track names
238        unsigned removedTracks = previousTrackMask & ~currentTrackMask;
239        while (removedTracks != 0) {
240            int i = __builtin_ctz(removedTracks);
241            removedTracks &= ~(1 << i);
242            const FastTrack* fastTrack = &current->mFastTracks[i];
243            ALOG_ASSERT(fastTrack->mBufferProvider == NULL);
244            if (mMixer != NULL) {
245                name = mFastTrackNames[i];
246                ALOG_ASSERT(name >= 0);
247                mMixer->deleteTrackName(name);
248            }
249#if !LOG_NDEBUG
250            mFastTrackNames[i] = -1;
251#endif
252            // don't reset track dump state, since other side is ignoring it
253            mGenerations[i] = fastTrack->mGeneration;
254        }
255
256        // now process added tracks
257        unsigned addedTracks = currentTrackMask & ~previousTrackMask;
258        while (addedTracks != 0) {
259            int i = __builtin_ctz(addedTracks);
260            addedTracks &= ~(1 << i);
261            const FastTrack* fastTrack = &current->mFastTracks[i];
262            AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
263            ALOG_ASSERT(bufferProvider != NULL && mFastTrackNames[i] == -1);
264            if (mMixer != NULL) {
265                name = mMixer->getTrackName(fastTrack->mChannelMask,
266                        fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
267                ALOG_ASSERT(name >= 0);
268                mFastTrackNames[i] = name;
269                mMixer->setBufferProvider(name, bufferProvider);
270                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
271                        (void *)mMixerBuffer);
272                // newly allocated track names default to full scale volume
273                mMixer->setParameter(
274                        name,
275                        AudioMixer::TRACK,
276                        AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
277                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
278                        (void *)(uintptr_t)fastTrack->mFormat);
279                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
280                        (void *)(uintptr_t)fastTrack->mChannelMask);
281                mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
282                        (void *)(uintptr_t)mSinkChannelMask);
283                mMixer->enable(name);
284            }
285            mGenerations[i] = fastTrack->mGeneration;
286        }
287
288        // finally process (potentially) modified tracks; these use the same slot
289        // but may have a different buffer provider or volume provider
290        unsigned modifiedTracks = currentTrackMask & previousTrackMask;
291        while (modifiedTracks != 0) {
292            int i = __builtin_ctz(modifiedTracks);
293            modifiedTracks &= ~(1 << i);
294            const FastTrack* fastTrack = &current->mFastTracks[i];
295            if (fastTrack->mGeneration != mGenerations[i]) {
296                // this track was actually modified
297                AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
298                ALOG_ASSERT(bufferProvider != NULL);
299                if (mMixer != NULL) {
300                    name = mFastTrackNames[i];
301                    ALOG_ASSERT(name >= 0);
302                    mMixer->setBufferProvider(name, bufferProvider);
303                    if (fastTrack->mVolumeProvider == NULL) {
304                        float f = AudioMixer::UNITY_GAIN_FLOAT;
305                        mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &f);
306                        mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &f);
307                    }
308                    mMixer->setParameter(name, AudioMixer::RESAMPLE,
309                            AudioMixer::REMOVE, NULL);
310                    mMixer->setParameter(
311                            name,
312                            AudioMixer::TRACK,
313                            AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
314                    mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
315                            (void *)(uintptr_t)fastTrack->mFormat);
316                    mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
317                            (void *)(uintptr_t)fastTrack->mChannelMask);
318                    mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
319                            (void *)(uintptr_t)mSinkChannelMask);
320                    // already enabled
321                }
322                mGenerations[i] = fastTrack->mGeneration;
323            }
324        }
325
326        mFastTracksGen = current->mFastTracksGen;
327
328        dumpState->mNumTracks = popcount(currentTrackMask);
329    }
330}
331
332void FastMixer::onWork()
333{
334    const FastMixerState * const current = (const FastMixerState *) mCurrent;
335    FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
336    const FastMixerState::Command command = mCommand;
337    const size_t frameCount = current->mFrameCount;
338
339    if ((command & FastMixerState::MIX) && (mMixer != NULL) && mIsWarm) {
340        ALOG_ASSERT(mMixerBuffer != NULL);
341        // for each track, update volume and check for underrun
342        unsigned currentTrackMask = current->mTrackMask;
343        while (currentTrackMask != 0) {
344            int i = __builtin_ctz(currentTrackMask);
345            currentTrackMask &= ~(1 << i);
346            const FastTrack* fastTrack = &current->mFastTracks[i];
347
348            const int64_t trackFramesWrittenButNotPresented =
349                mNativeFramesWrittenButNotPresented;
350            const int64_t trackFramesWritten = fastTrack->mBufferProvider->framesReleased();
351            ExtendedTimestamp perTrackTimestamp(mTimestamp);
352
353            // Can't provide an ExtendedTimestamp before first frame presented.
354            // Also, timestamp may not go to very last frame on stop().
355            if (trackFramesWritten >= trackFramesWrittenButNotPresented &&
356                    perTrackTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] > 0) {
357                perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] =
358                        trackFramesWritten - trackFramesWrittenButNotPresented;
359            } else {
360                perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = 0;
361                perTrackTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = -1;
362            }
363            perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = trackFramesWritten;
364            fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp);
365
366            int name = mFastTrackNames[i];
367            ALOG_ASSERT(name >= 0);
368            if (fastTrack->mVolumeProvider != NULL) {
369                gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
370                float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
371                float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
372
373                mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &vlf);
374                mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &vrf);
375            }
376            // FIXME The current implementation of framesReady() for fast tracks
377            // takes a tryLock, which can block
378            // up to 1 ms.  If enough active tracks all blocked in sequence, this would result
379            // in the overall fast mix cycle being delayed.  Should use a non-blocking FIFO.
380            size_t framesReady = fastTrack->mBufferProvider->framesReady();
381            if (ATRACE_ENABLED()) {
382                // I wish we had formatted trace names
383                char traceName[16];
384                strcpy(traceName, "fRdy");
385                traceName[4] = i + (i < 10 ? '0' : 'A' - 10);
386                traceName[5] = '\0';
387                ATRACE_INT(traceName, framesReady);
388            }
389            FastTrackDump *ftDump = &dumpState->mTracks[i];
390            FastTrackUnderruns underruns = ftDump->mUnderruns;
391            if (framesReady < frameCount) {
392                if (framesReady == 0) {
393                    underruns.mBitFields.mEmpty++;
394                    underruns.mBitFields.mMostRecent = UNDERRUN_EMPTY;
395                    mMixer->disable(name);
396                } else {
397                    // allow mixing partial buffer
398                    underruns.mBitFields.mPartial++;
399                    underruns.mBitFields.mMostRecent = UNDERRUN_PARTIAL;
400                    mMixer->enable(name);
401                }
402            } else {
403                underruns.mBitFields.mFull++;
404                underruns.mBitFields.mMostRecent = UNDERRUN_FULL;
405                mMixer->enable(name);
406            }
407            ftDump->mUnderruns = underruns;
408            ftDump->mFramesReady = framesReady;
409        }
410
411        // process() is CPU-bound
412        mMixer->process();
413        mMixerBufferState = MIXED;
414    } else if (mMixerBufferState == MIXED) {
415        mMixerBufferState = UNDEFINED;
416    }
417    //bool didFullWrite = false;    // dumpsys could display a count of partial writes
418    if ((command & FastMixerState::WRITE) && (mOutputSink != NULL) && (mMixerBuffer != NULL)) {
419        if (mMixerBufferState == UNDEFINED) {
420            memset(mMixerBuffer, 0, mMixerBufferSize);
421            mMixerBufferState = ZEROED;
422        }
423
424        if (mMasterMono.load()) {  // memory_order_seq_cst
425            mono_blend(mMixerBuffer, mMixerBufferFormat, Format_channelCount(mFormat), frameCount, true /*limit*/);
426        }
427        // prepare the buffer used to write to sink
428        void *buffer = mSinkBuffer != NULL ? mSinkBuffer : mMixerBuffer;
429        if (mFormat.mFormat != mMixerBufferFormat) { // sink format not the same as mixer format
430            memcpy_by_audio_format(buffer, mFormat.mFormat, mMixerBuffer, mMixerBufferFormat,
431                    frameCount * Format_channelCount(mFormat));
432        }
433        // if non-NULL, then duplicate write() to this non-blocking sink
434        NBAIO_Sink* teeSink;
435        if ((teeSink = current->mTeeSink) != NULL) {
436            (void) teeSink->write(buffer, frameCount);
437        }
438        // FIXME write() is non-blocking and lock-free for a properly implemented NBAIO sink,
439        //       but this code should be modified to handle both non-blocking and blocking sinks
440        dumpState->mWriteSequence++;
441        ATRACE_BEGIN("write");
442        ssize_t framesWritten = mOutputSink->write(buffer, frameCount);
443        ATRACE_END();
444        dumpState->mWriteSequence++;
445        if (framesWritten >= 0) {
446            ALOG_ASSERT((size_t) framesWritten <= frameCount);
447            mTotalNativeFramesWritten += framesWritten;
448            dumpState->mFramesWritten = mTotalNativeFramesWritten;
449            //if ((size_t) framesWritten == frameCount) {
450            //    didFullWrite = true;
451            //}
452        } else {
453            dumpState->mWriteErrors++;
454        }
455        mAttemptedWrite = true;
456        // FIXME count # of writes blocked excessively, CPU usage, etc. for dump
457
458        ExtendedTimestamp timestamp; // local
459        status_t status = mOutputSink->getTimestamp(timestamp);
460        if (status == NO_ERROR) {
461            const int64_t totalNativeFramesPresented =
462                    timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
463            if (totalNativeFramesPresented <= mTotalNativeFramesWritten) {
464                mNativeFramesWrittenButNotPresented =
465                    mTotalNativeFramesWritten - totalNativeFramesPresented;
466                mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] =
467                        timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
468                mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
469                        timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
470            } else {
471                // HAL reported that more frames were presented than were written
472                mNativeFramesWrittenButNotPresented = 0;
473                mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = 0;
474                mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = -1;
475                status = INVALID_OPERATION;
476            }
477        }
478        if (status == NO_ERROR) {
479            mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] =
480                    mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
481        } else {
482            // fetch server time if we can't get timestamp
483            mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] =
484                    systemTime(SYSTEM_TIME_MONOTONIC);
485        }
486    }
487}
488
489}   // namespace android
490