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 
46 namespace android {
47 
48 /*static*/ const FastMixerState FastMixer::sInitial;
49 
FastMixer()50 FastMixer::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 
~FastMixer()91 FastMixer::~FastMixer()
92 {
93 }
94 
sq()95 FastMixerStateQueue* FastMixer::sq()
96 {
97     return &mSQ;
98 }
99 
poll()100 const FastThreadState *FastMixer::poll()
101 {
102     return mSQ.poll();
103 }
104 
setLog(NBLog::Writer * logWriter)105 void FastMixer::setLog(NBLog::Writer *logWriter)
106 {
107     if (mMixer != NULL) {
108         mMixer->setLog(logWriter);
109     }
110 }
111 
onIdle()112 void FastMixer::onIdle()
113 {
114     mPreIdle = *(const FastMixerState *)mCurrent;
115     mCurrent = &mPreIdle;
116 }
117 
onExit()118 void FastMixer::onExit()
119 {
120     delete mMixer;
121     free(mMixerBuffer);
122     free(mSinkBuffer);
123 }
124 
isSubClassCommand(FastThreadState::Command command)125 bool 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 
onStateChange()137 void 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     // 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             // The mixer produces either 16 bit PCM or float output, select
181             // float output if the HAL supports higher than 16 bit precision.
182             mMixerBufferFormat = mFormat.mFormat == AUDIO_FORMAT_PCM_16_BIT ?
183                     AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_FLOAT;
184             // FIXME new may block for unbounded time at internal mutex of the heap
185             //       implementation; it would be better to have normal mixer allocate for us
186             //       to avoid blocking here and to prevent possible priority inversion
187             mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::kMaxFastTracks);
188             const size_t mixerFrameSize = mSinkChannelCount
189                     * audio_bytes_per_sample(mMixerBufferFormat);
190             mMixerBufferSize = mixerFrameSize * frameCount;
191             (void)posix_memalign(&mMixerBuffer, 32, mMixerBufferSize);
192             const size_t sinkFrameSize = mSinkChannelCount
193                     * audio_bytes_per_sample(mFormat.mFormat);
194             if (sinkFrameSize > mixerFrameSize) { // need a sink buffer
195                 mSinkBufferSize = sinkFrameSize * frameCount;
196                 (void)posix_memalign(&mSinkBuffer, 32, mSinkBufferSize);
197             }
198             mPeriodNs = (frameCount * 1000000000LL) / mSampleRate;    // 1.00
199             mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate;  // 1.75
200             mOverrunNs = (frameCount * 500000000LL) / mSampleRate;    // 0.50
201             mForceNs = (frameCount * 950000000LL) / mSampleRate;      // 0.95
202             mWarmupNsMin = (frameCount * 750000000LL) / mSampleRate;  // 0.75
203             mWarmupNsMax = (frameCount * 1250000000LL) / mSampleRate; // 1.25
204         } else {
205             mPeriodNs = 0;
206             mUnderrunNs = 0;
207             mOverrunNs = 0;
208             mForceNs = 0;
209             mWarmupNsMin = 0;
210             mWarmupNsMax = LONG_MAX;
211         }
212         mMixerBufferState = UNDEFINED;
213 #if !LOG_NDEBUG
214         for (unsigned i = 0; i < FastMixerState::kMaxFastTracks; ++i) {
215             mFastTrackNames[i] = -1;
216         }
217 #endif
218         // we need to reconfigure all active tracks
219         previousTrackMask = 0;
220         mFastTracksGen = current->mFastTracksGen - 1;
221         dumpState->mFrameCount = frameCount;
222     } else {
223         previousTrackMask = previous->mTrackMask;
224     }
225 
226     // check for change in active track set
227     const unsigned currentTrackMask = current->mTrackMask;
228     dumpState->mTrackMask = currentTrackMask;
229     if (current->mFastTracksGen != mFastTracksGen) {
230         ALOG_ASSERT(mMixerBuffer != NULL);
231         int name;
232 
233         // process removed tracks first to avoid running out of track names
234         unsigned removedTracks = previousTrackMask & ~currentTrackMask;
235         while (removedTracks != 0) {
236             int i = __builtin_ctz(removedTracks);
237             removedTracks &= ~(1 << i);
238             const FastTrack* fastTrack = &current->mFastTracks[i];
239             ALOG_ASSERT(fastTrack->mBufferProvider == NULL);
240             if (mMixer != NULL) {
241                 name = mFastTrackNames[i];
242                 ALOG_ASSERT(name >= 0);
243                 mMixer->deleteTrackName(name);
244             }
245 #if !LOG_NDEBUG
246             mFastTrackNames[i] = -1;
247 #endif
248             // don't reset track dump state, since other side is ignoring it
249             mGenerations[i] = fastTrack->mGeneration;
250         }
251 
252         // now process added tracks
253         unsigned addedTracks = currentTrackMask & ~previousTrackMask;
254         while (addedTracks != 0) {
255             int i = __builtin_ctz(addedTracks);
256             addedTracks &= ~(1 << i);
257             const FastTrack* fastTrack = &current->mFastTracks[i];
258             AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
259             ALOG_ASSERT(bufferProvider != NULL && mFastTrackNames[i] == -1);
260             if (mMixer != NULL) {
261                 name = mMixer->getTrackName(fastTrack->mChannelMask,
262                         fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
263                 ALOG_ASSERT(name >= 0);
264                 mFastTrackNames[i] = name;
265                 mMixer->setBufferProvider(name, bufferProvider);
266                 mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
267                         (void *)mMixerBuffer);
268                 // newly allocated track names default to full scale volume
269                 mMixer->setParameter(
270                         name,
271                         AudioMixer::TRACK,
272                         AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
273                 mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
274                         (void *)(uintptr_t)fastTrack->mFormat);
275                 mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
276                         (void *)(uintptr_t)fastTrack->mChannelMask);
277                 mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
278                         (void *)(uintptr_t)mSinkChannelMask);
279                 mMixer->enable(name);
280             }
281             mGenerations[i] = fastTrack->mGeneration;
282         }
283 
284         // finally process (potentially) modified tracks; these use the same slot
285         // but may have a different buffer provider or volume provider
286         unsigned modifiedTracks = currentTrackMask & previousTrackMask;
287         while (modifiedTracks != 0) {
288             int i = __builtin_ctz(modifiedTracks);
289             modifiedTracks &= ~(1 << i);
290             const FastTrack* fastTrack = &current->mFastTracks[i];
291             if (fastTrack->mGeneration != mGenerations[i]) {
292                 // this track was actually modified
293                 AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
294                 ALOG_ASSERT(bufferProvider != NULL);
295                 if (mMixer != NULL) {
296                     name = mFastTrackNames[i];
297                     ALOG_ASSERT(name >= 0);
298                     mMixer->setBufferProvider(name, bufferProvider);
299                     if (fastTrack->mVolumeProvider == NULL) {
300                         float f = AudioMixer::UNITY_GAIN_FLOAT;
301                         mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &f);
302                         mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &f);
303                     }
304                     mMixer->setParameter(name, AudioMixer::RESAMPLE,
305                             AudioMixer::REMOVE, NULL);
306                     mMixer->setParameter(
307                             name,
308                             AudioMixer::TRACK,
309                             AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
310                     mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
311                             (void *)(uintptr_t)fastTrack->mFormat);
312                     mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
313                             (void *)(uintptr_t)fastTrack->mChannelMask);
314                     mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
315                             (void *)(uintptr_t)mSinkChannelMask);
316                     // already enabled
317                 }
318                 mGenerations[i] = fastTrack->mGeneration;
319             }
320         }
321 
322         mFastTracksGen = current->mFastTracksGen;
323 
324         dumpState->mNumTracks = popcount(currentTrackMask);
325     }
326 }
327 
onWork()328 void FastMixer::onWork()
329 {
330     const FastMixerState * const current = (const FastMixerState *) mCurrent;
331     FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
332     const FastMixerState::Command command = mCommand;
333     const size_t frameCount = current->mFrameCount;
334 
335     if ((command & FastMixerState::MIX) && (mMixer != NULL) && mIsWarm) {
336         ALOG_ASSERT(mMixerBuffer != NULL);
337         // for each track, update volume and check for underrun
338         unsigned currentTrackMask = current->mTrackMask;
339         while (currentTrackMask != 0) {
340             int i = __builtin_ctz(currentTrackMask);
341             currentTrackMask &= ~(1 << i);
342             const FastTrack* fastTrack = &current->mFastTracks[i];
343 
344             // Refresh the per-track timestamp
345             if (mTimestampStatus == NO_ERROR) {
346                 uint32_t trackFramesWrittenButNotPresented =
347                     mNativeFramesWrittenButNotPresented;
348                 uint32_t trackFramesWritten = fastTrack->mBufferProvider->framesReleased();
349                 // Can't provide an AudioTimestamp before first frame presented,
350                 // or during the brief 32-bit wraparound window
351                 if (trackFramesWritten >= trackFramesWrittenButNotPresented) {
352                     AudioTimestamp perTrackTimestamp;
353                     perTrackTimestamp.mPosition =
354                             trackFramesWritten - trackFramesWrittenButNotPresented;
355                     perTrackTimestamp.mTime = mTimestamp.mTime;
356                     fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp);
357                 }
358             }
359 
360             int name = mFastTrackNames[i];
361             ALOG_ASSERT(name >= 0);
362             if (fastTrack->mVolumeProvider != NULL) {
363                 gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
364                 float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
365                 float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
366 
367                 mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &vlf);
368                 mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &vrf);
369             }
370             // FIXME The current implementation of framesReady() for fast tracks
371             // takes a tryLock, which can block
372             // up to 1 ms.  If enough active tracks all blocked in sequence, this would result
373             // in the overall fast mix cycle being delayed.  Should use a non-blocking FIFO.
374             size_t framesReady = fastTrack->mBufferProvider->framesReady();
375             if (ATRACE_ENABLED()) {
376                 // I wish we had formatted trace names
377                 char traceName[16];
378                 strcpy(traceName, "fRdy");
379                 traceName[4] = i + (i < 10 ? '0' : 'A' - 10);
380                 traceName[5] = '\0';
381                 ATRACE_INT(traceName, framesReady);
382             }
383             FastTrackDump *ftDump = &dumpState->mTracks[i];
384             FastTrackUnderruns underruns = ftDump->mUnderruns;
385             if (framesReady < frameCount) {
386                 if (framesReady == 0) {
387                     underruns.mBitFields.mEmpty++;
388                     underruns.mBitFields.mMostRecent = UNDERRUN_EMPTY;
389                     mMixer->disable(name);
390                 } else {
391                     // allow mixing partial buffer
392                     underruns.mBitFields.mPartial++;
393                     underruns.mBitFields.mMostRecent = UNDERRUN_PARTIAL;
394                     mMixer->enable(name);
395                 }
396             } else {
397                 underruns.mBitFields.mFull++;
398                 underruns.mBitFields.mMostRecent = UNDERRUN_FULL;
399                 mMixer->enable(name);
400             }
401             ftDump->mUnderruns = underruns;
402             ftDump->mFramesReady = framesReady;
403         }
404 
405         int64_t pts;
406         if (mOutputSink == NULL || (OK != mOutputSink->getNextWriteTimestamp(&pts))) {
407             pts = AudioBufferProvider::kInvalidPTS;
408         }
409 
410         // process() is CPU-bound
411         mMixer->process(pts);
412         mMixerBufferState = MIXED;
413     } else if (mMixerBufferState == MIXED) {
414         mMixerBufferState = UNDEFINED;
415     }
416     //bool didFullWrite = false;    // dumpsys could display a count of partial writes
417     if ((command & FastMixerState::WRITE) && (mOutputSink != NULL) && (mMixerBuffer != NULL)) {
418         if (mMixerBufferState == UNDEFINED) {
419             memset(mMixerBuffer, 0, mMixerBufferSize);
420             mMixerBufferState = ZEROED;
421         }
422         // prepare the buffer used to write to sink
423         void *buffer = mSinkBuffer != NULL ? mSinkBuffer : mMixerBuffer;
424         if (mFormat.mFormat != mMixerBufferFormat) { // sink format not the same as mixer format
425             memcpy_by_audio_format(buffer, mFormat.mFormat, mMixerBuffer, mMixerBufferFormat,
426                     frameCount * Format_channelCount(mFormat));
427         }
428         // if non-NULL, then duplicate write() to this non-blocking sink
429         NBAIO_Sink* teeSink;
430         if ((teeSink = current->mTeeSink) != NULL) {
431             (void) teeSink->write(buffer, frameCount);
432         }
433         // FIXME write() is non-blocking and lock-free for a properly implemented NBAIO sink,
434         //       but this code should be modified to handle both non-blocking and blocking sinks
435         dumpState->mWriteSequence++;
436         ATRACE_BEGIN("write");
437         ssize_t framesWritten = mOutputSink->write(buffer, frameCount);
438         ATRACE_END();
439         dumpState->mWriteSequence++;
440         if (framesWritten >= 0) {
441             ALOG_ASSERT((size_t) framesWritten <= frameCount);
442             mTotalNativeFramesWritten += framesWritten;
443             dumpState->mFramesWritten = mTotalNativeFramesWritten;
444             //if ((size_t) framesWritten == frameCount) {
445             //    didFullWrite = true;
446             //}
447         } else {
448             dumpState->mWriteErrors++;
449         }
450         mAttemptedWrite = true;
451         // FIXME count # of writes blocked excessively, CPU usage, etc. for dump
452 
453         mTimestampStatus = mOutputSink->getTimestamp(mTimestamp);
454         if (mTimestampStatus == NO_ERROR) {
455             uint32_t totalNativeFramesPresented = mTimestamp.mPosition;
456             if (totalNativeFramesPresented <= mTotalNativeFramesWritten) {
457                 mNativeFramesWrittenButNotPresented =
458                     mTotalNativeFramesWritten - totalNativeFramesPresented;
459             } else {
460                 // HAL reported that more frames were presented than were written
461                 mTimestampStatus = INVALID_OPERATION;
462             }
463         }
464     }
465 }
466 
467 }   // namespace android
468