• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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 #ifndef ANDROID_AUDIO_TRACK_SHARED_H
18 #define ANDROID_AUDIO_TRACK_SHARED_H
19 
20 #include <stdint.h>
21 #include <sys/types.h>
22 
23 #include <audio_utils/minifloat.h>
24 #include <utils/threads.h>
25 #include <utils/Log.h>
26 #include <utils/RefBase.h>
27 #include <audio_utils/roundup.h>
28 #include <media/AudioResamplerPublic.h>
29 #include <media/AudioTimestamp.h>
30 #include <media/Modulo.h>
31 #include <media/SingleStateQueue.h>
32 
33 namespace android {
34 
35 // ----------------------------------------------------------------------------
36 
37 // for audio_track_cblk_t::mFlags
38 #define CBLK_UNDERRUN   0x01 // set by server immediately on output underrun, cleared by client
39 #define CBLK_FORCEREADY 0x02 // set: track is considered ready immediately by AudioFlinger,
40                              // clear: track is ready when buffer full
41 #define CBLK_INVALID    0x04 // track buffer invalidated by AudioFlinger, need to re-create
42 #define CBLK_DISABLED   0x08 // output track disabled by AudioFlinger due to underrun,
43                              // need to re-start.  Unlike CBLK_UNDERRUN, this is not set
44                              // immediately, but only after a long string of underruns.
45 // 0x10 unused
46 #define CBLK_LOOP_CYCLE 0x20 // set by server each time a loop cycle other than final one completes
47 #define CBLK_LOOP_FINAL 0x40 // set by server when the final loop cycle completes
48 #define CBLK_BUFFER_END 0x80 // set by server when the position reaches end of buffer if not looping
49 #define CBLK_OVERRUN   0x100 // set by server immediately on input overrun, cleared by client
50 #define CBLK_INTERRUPT 0x200 // set by client on interrupt(), cleared by client in obtainBuffer()
51 #define CBLK_STREAM_END_DONE 0x400 // set by server on render completion, cleared by client
52 
53 //EL_FIXME 20 seconds may not be enough and must be reconciled with new obtainBuffer implementation
54 #define MAX_RUN_OFFLOADED_TIMEOUT_MS 20000 // assuming up to a maximum of 20 seconds of offloaded
55 
56 struct AudioTrackSharedStreaming {
57     // similar to NBAIO MonoPipe
58     // in continuously incrementing frame units, take modulo buffer size, which must be a power of 2
59     volatile int32_t mFront;    // read by consumer (output: server, input: client)
60     volatile int32_t mRear;     // written by producer (output: client, input: server)
61     volatile int32_t mFlush;    // incremented by client to indicate a request to flush;
62                                 // server notices and discards all data between mFront and mRear
63     volatile uint32_t mUnderrunFrames; // server increments for each unavailable but desired frame
64     volatile uint32_t mUnderrunCount;  // server increments for each underrun occurrence
65 };
66 
67 // Represents a single state of an AudioTrack that was created in static mode (shared memory buffer
68 // supplied by the client).  This state needs to be communicated from the client to server.  As this
69 // state is too large to be updated atomically without a mutex, and mutexes aren't allowed here, the
70 // state is wrapped by a SingleStateQueue.
71 struct StaticAudioTrackState {
72     // Do not define constructors, destructors, or virtual methods as this is part of a
73     // union in shared memory and they will not get called properly.
74 
75     // These fields should both be size_t, but since they are located in shared memory we
76     // force to 32-bit.  The client and server may have different typedefs for size_t.
77 
78     // The state has a sequence counter to indicate whether changes are made to loop or position.
79     // The sequence counter also currently indicates whether loop or position is first depending
80     // on which is greater; it jumps by max(mLoopSequence, mPositionSequence) + 1.
81 
82     uint32_t    mLoopStart;
83     uint32_t    mLoopEnd;
84     int32_t     mLoopCount;
85     uint32_t    mLoopSequence; // a sequence counter to indicate changes to loop
86     uint32_t    mPosition;
87     uint32_t    mPositionSequence; // a sequence counter to indicate changes to position
88 };
89 
90 typedef SingleStateQueue<StaticAudioTrackState> StaticAudioTrackSingleStateQueue;
91 
92 struct StaticAudioTrackPosLoop {
93     // Do not define constructors, destructors, or virtual methods as this is part of a
94     // union in shared memory and will not get called properly.
95 
96     // These fields should both be size_t, but since they are located in shared memory we
97     // force to 32-bit.  The client and server may have different typedefs for size_t.
98 
99     // This struct information is stored in a single state queue to communicate the
100     // static AudioTrack server state to the client while data is consumed.
101     // It is smaller than StaticAudioTrackState to prevent unnecessary information from
102     // being sent.
103 
104     uint32_t mBufferPosition;
105     int32_t  mLoopCount;
106 };
107 
108 typedef SingleStateQueue<StaticAudioTrackPosLoop> StaticAudioTrackPosLoopQueue;
109 
110 struct AudioTrackSharedStatic {
111     // client requests to the server for loop or position changes.
112     StaticAudioTrackSingleStateQueue::Shared
113                     mSingleStateQueue;
114     // position info updated asynchronously by server and read by client,
115     // "for entertainment purposes only"
116     StaticAudioTrackPosLoopQueue::Shared
117                     mPosLoopQueue;
118 };
119 
120 typedef SingleStateQueue<AudioPlaybackRate> PlaybackRateQueue;
121 
122 typedef SingleStateQueue<ExtendedTimestamp> ExtendedTimestampQueue;
123 
124 // ----------------------------------------------------------------------------
125 
126 // Important: do not add any virtual methods, including ~
127 struct audio_track_cblk_t
128 {
129                 // Since the control block is always located in shared memory, this constructor
130                 // is only used for placement new().  It is never used for regular new() or stack.
131                             audio_track_cblk_t();
~audio_track_cblk_taudio_track_cblk_t132                 /*virtual*/ ~audio_track_cblk_t() { }
133 
134                 friend class Proxy;
135                 friend class ClientProxy;
136                 friend class AudioTrackClientProxy;
137                 friend class AudioRecordClientProxy;
138                 friend class ServerProxy;
139                 friend class AudioTrackServerProxy;
140                 friend class AudioRecordServerProxy;
141 
142     // The data members are grouped so that members accessed frequently and in the same context
143     // are in the same line of data cache.
144 
145                 uint32_t    mServer;    // Number of filled frames consumed by server (mIsOut),
146                                         // or filled frames provided by server (!mIsOut).
147                                         // It is updated asynchronously by server without a barrier.
148                                         // The value should be used
149                                         // "for entertainment purposes only",
150                                         // which means don't make important decisions based on it.
151 
152                 uint32_t    mPad1;      // unused
153 
154     volatile    int32_t     mFutex;     // event flag: down (P) by client,
155                                         // up (V) by server or binderDied() or interrupt()
156 #define CBLK_FUTEX_WAKE 1               // if event flag bit is set, then a deferred wake is pending
157 
158 private:
159 
160                 // This field should be a size_t, but since it is located in shared memory we
161                 // force to 32-bit.  The client and server may have different typedefs for size_t.
162                 uint32_t    mMinimum;       // server wakes up client if available >= mMinimum
163 
164                 // Stereo gains for AudioTrack only, not used by AudioRecord.
165                 gain_minifloat_packed_t mVolumeLR;
166 
167                 uint32_t    mSampleRate;    // AudioTrack only: client's requested sample rate in Hz
168                                             // or 0 == default. Write-only client, read-only server.
169 
170                 PlaybackRateQueue::Shared mPlaybackRateQueue;
171 
172                 // client write-only, server read-only
173                 uint16_t    mSendLevel;      // Fixed point U4.12 so 0x1000 means 1.0
174 
175                 uint16_t    mPad2;           // unused
176 
177                 // server write-only, client read
178                 ExtendedTimestampQueue::Shared mExtendedTimestampQueue;
179 
180                 // This is set by AudioTrack.setBufferSizeInFrames().
181                 // A write will not fill the buffer above this limit.
182     volatile    uint32_t   mBufferSizeInFrames;  // effective size of the buffer
183 
184 public:
185 
186     volatile    int32_t     mFlags;         // combinations of CBLK_*
187 
188 public:
189                 union {
190                     AudioTrackSharedStreaming   mStreaming;
191                     AudioTrackSharedStatic      mStatic;
192                     int                         mAlign[8];
193                 } u;
194 
195                 // Cache line boundary (32 bytes)
196 };
197 
198 // ----------------------------------------------------------------------------
199 
200 // Proxy for shared memory control block, to isolate callers from needing to know the details.
201 // There is exactly one ClientProxy and one ServerProxy per shared memory control block.
202 // The proxies are located in normal memory, and are not multi-thread safe within a given side.
203 class Proxy : public RefBase {
204 protected:
205     Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut,
206             bool clientInServer);
~Proxy()207     virtual ~Proxy() { }
208 
209 public:
210     struct Buffer {
211         size_t  mFrameCount;            // number of frames available in this buffer
212         void*   mRaw;                   // pointer to first frame
213         size_t  mNonContig;             // number of additional non-contiguous frames available
214     };
215 
frameCount()216     size_t frameCount() const { return mFrameCount; }
217 
218 protected:
219     // These refer to shared memory, and are virtual addresses with respect to the current process.
220     // They may have different virtual addresses within the other process.
221     audio_track_cblk_t* const   mCblk;  // the control block
222     void* const     mBuffers;           // starting address of buffers
223 
224     const size_t    mFrameCount;        // not necessarily a power of 2
225     const size_t    mFrameSize;         // in bytes
226     const size_t    mFrameCountP2;      // mFrameCount rounded to power of 2, streaming mode
227     const bool      mIsOut;             // true for AudioTrack, false for AudioRecord
228     const bool      mClientInServer;    // true for OutputTrack, false for AudioTrack & AudioRecord
229     bool            mIsShutdown;        // latch set to true when shared memory corruption detected
230     size_t          mUnreleased;        // unreleased frames remaining from most recent obtainBuffer
231 };
232 
233 // ----------------------------------------------------------------------------
234 
235 // Proxy seen by AudioTrack client and AudioRecord client
236 class ClientProxy : public Proxy {
237 public:
238     ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
239             bool isOut, bool clientInServer);
~ClientProxy()240     virtual ~ClientProxy() { }
241 
242     static const struct timespec kForever;
243     static const struct timespec kNonBlocking;
244 
245     // Obtain a buffer with filled frames (reading) or empty frames (writing).
246     // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
247     // calls to releaseBuffer().  In that case, the final obtainBuffer() is the one that effectively
248     // sets or extends the unreleased frame count.
249     // On entry:
250     //  buffer->mFrameCount should be initialized to maximum number of desired frames,
251     //      which must be > 0.
252     //  buffer->mNonContig is unused.
253     //  buffer->mRaw is unused.
254     //  requested is the requested timeout in local monotonic delta time units:
255     //      NULL or &kNonBlocking means non-blocking (zero timeout).
256     //      &kForever means block forever (infinite timeout).
257     //      Other values mean a specific timeout in local monotonic delta time units.
258     //  elapsed is a pointer to a location that will hold the total local monotonic time that
259     //      elapsed while blocked, or NULL if not needed.
260     // On exit:
261     //  buffer->mFrameCount has the actual number of contiguous available frames,
262     //      which is always 0 when the return status != NO_ERROR.
263     //  buffer->mNonContig is the number of additional non-contiguous available frames.
264     //  buffer->mRaw is a pointer to the first available frame,
265     //      or NULL when buffer->mFrameCount == 0.
266     // The return status is one of:
267     //  NO_ERROR    Success, buffer->mFrameCount > 0.
268     //  WOULD_BLOCK Non-blocking mode and no frames are available.
269     //  TIMED_OUT   Timeout occurred before any frames became available.
270     //              This can happen even for infinite timeout, due to a spurious wakeup.
271     //              In this case, the caller should investigate and then re-try as appropriate.
272     //  DEAD_OBJECT Server has died or invalidated, caller should destroy this proxy and re-create.
273     //  -EINTR      Call has been interrupted.  Look around to see why, and then perhaps try again.
274     //  NO_INIT     Shared memory is corrupt.
275     //  NOT_ENOUGH_DATA Server has disabled the track because of underrun: restart the track
276     //              if still in active state.
277     // Assertion failure on entry, if buffer == NULL or buffer->mFrameCount == 0.
278     status_t    obtainBuffer(Buffer* buffer, const struct timespec *requested = NULL,
279             struct timespec *elapsed = NULL);
280 
281     // Release (some of) the frames last obtained.
282     // On entry, buffer->mFrameCount should have the number of frames to release,
283     // which must (cumulatively) be <= the number of frames last obtained but not yet released.
284     // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
285     // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
286     // On exit:
287     //  buffer->mFrameCount is zero.
288     //  buffer->mRaw is NULL.
289     void        releaseBuffer(Buffer* buffer);
290 
291     // Call after detecting server's death
292     void        binderDied();
293 
294     // Call to force an obtainBuffer() to return quickly with -EINTR
295     void        interrupt();
296 
getPosition()297     Modulo<uint32_t> getPosition() {
298         return mEpoch + mCblk->mServer;
299     }
300 
setEpoch(const Modulo<uint32_t> & epoch)301     void        setEpoch(const Modulo<uint32_t> &epoch) {
302         mEpoch = epoch;
303     }
304 
setMinimum(size_t minimum)305     void        setMinimum(size_t minimum) {
306         // This can only happen on a 64-bit client
307         if (minimum > UINT32_MAX) {
308             minimum = UINT32_MAX;
309         }
310         mCblk->mMinimum = (uint32_t) minimum;
311     }
312 
313     // Return the number of frames that would need to be obtained and released
314     // in order for the client to be aligned at start of buffer
315     virtual size_t  getMisalignment();
316 
getEpoch()317     Modulo<uint32_t> getEpoch() const {
318         return mEpoch;
319     }
320 
getBufferSizeInFrames()321     uint32_t      getBufferSizeInFrames() const { return mBufferSizeInFrames; }
322     // See documentation for AudioTrack::setBufferSizeInFrames()
323     uint32_t      setBufferSizeInFrames(uint32_t requestedSize);
324 
getTimestamp(ExtendedTimestamp * timestamp)325     status_t    getTimestamp(ExtendedTimestamp *timestamp) {
326         if (timestamp == nullptr) {
327             return BAD_VALUE;
328         }
329         (void) mTimestampObserver.poll(mTimestamp);
330         *timestamp = mTimestamp;
331         return OK;
332     }
333 
clearTimestamp()334     void        clearTimestamp() {
335         mTimestamp.clear();
336     }
337 
338 private:
339     // This is a copy of mCblk->mBufferSizeInFrames
340     uint32_t   mBufferSizeInFrames;  // effective size of the buffer
341 
342     Modulo<uint32_t> mEpoch;
343 
344     // The shared buffer contents referred to by the timestamp observer
345     // is initialized when the server proxy created.  A local zero timestamp
346     // is initialized by the client constructor.
347     ExtendedTimestampQueue::Observer mTimestampObserver;
348     ExtendedTimestamp mTimestamp; // initialized by constructor
349 };
350 
351 // ----------------------------------------------------------------------------
352 
353 // Proxy used by AudioTrack client, which also includes AudioFlinger::PlaybackThread::OutputTrack
354 class AudioTrackClientProxy : public ClientProxy {
355 public:
356     AudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
357             size_t frameSize, bool clientInServer = false)
ClientProxy(cblk,buffers,frameCount,frameSize,true,clientInServer)358         : ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/,
359           clientInServer),
360           mPlaybackRateMutator(&cblk->mPlaybackRateQueue) {
361     }
362 
~AudioTrackClientProxy()363     virtual ~AudioTrackClientProxy() { }
364 
365     // No barriers on the following operations, so the ordering of loads/stores
366     // with respect to other parameters is UNPREDICTABLE. That's considered safe.
367 
368     // caller must limit to 0.0 <= sendLevel <= 1.0
setSendLevel(float sendLevel)369     void        setSendLevel(float sendLevel) {
370         mCblk->mSendLevel = uint16_t(sendLevel * 0x1000);
371     }
372 
373     // set stereo gains
setVolumeLR(gain_minifloat_packed_t volumeLR)374     void        setVolumeLR(gain_minifloat_packed_t volumeLR) {
375         mCblk->mVolumeLR = volumeLR;
376     }
377 
setSampleRate(uint32_t sampleRate)378     void        setSampleRate(uint32_t sampleRate) {
379         mCblk->mSampleRate = sampleRate;
380     }
381 
setPlaybackRate(const AudioPlaybackRate & playbackRate)382     void        setPlaybackRate(const AudioPlaybackRate& playbackRate) {
383         mPlaybackRateMutator.push(playbackRate);
384     }
385 
386     virtual void flush();
387 
getUnderrunFrames()388     virtual uint32_t    getUnderrunFrames() const {
389         return mCblk->u.mStreaming.mUnderrunFrames;
390     }
getUnderrunCount()391     virtual uint32_t    getUnderrunCount() const {
392         return mCblk->u.mStreaming.mUnderrunCount;
393     }
394 
395     bool        clearStreamEndDone();   // and return previous value
396 
397     bool        getStreamEndDone() const;
398 
399     status_t    waitStreamEndDone(const struct timespec *requested);
400 
401 private:
402     PlaybackRateQueue::Mutator   mPlaybackRateMutator;
403 };
404 
405 class StaticAudioTrackClientProxy : public AudioTrackClientProxy {
406 public:
407     StaticAudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
408             size_t frameSize);
~StaticAudioTrackClientProxy()409     virtual ~StaticAudioTrackClientProxy() { }
410 
411     virtual void    flush();
412 
413 #define MIN_LOOP    16  // minimum length of each loop iteration in frames
414 
415             // setLoop(), setBufferPosition(), and setBufferPositionAndLoop() set the
416             // static buffer position and looping parameters.  These commands are not
417             // synchronous (they do not wait or block); instead they take effect at the
418             // next buffer data read from the server side. However, the client side
419             // getters will read a cached version of the position and loop variables
420             // until the setting takes effect.
421             //
422             // setBufferPositionAndLoop() is equivalent to calling, in order, setLoop() and
423             // setBufferPosition().
424             //
425             // The functions should not be relied upon to do parameter or state checking.
426             // That is done at the AudioTrack level.
427 
428             void    setLoop(size_t loopStart, size_t loopEnd, int loopCount);
429             void    setBufferPosition(size_t position);
430             void    setBufferPositionAndLoop(size_t position, size_t loopStart, size_t loopEnd,
431                                              int loopCount);
432             size_t  getBufferPosition();
433                     // getBufferPositionAndLoopCount() provides the proper snapshot of
434                     // position and loopCount together.
435             void    getBufferPositionAndLoopCount(size_t *position, int *loopCount);
436 
getMisalignment()437     virtual size_t  getMisalignment() {
438         return 0;
439     }
440 
getUnderrunFrames()441     virtual uint32_t    getUnderrunFrames() const {
442         return 0;
443     }
444 
445 private:
446     StaticAudioTrackSingleStateQueue::Mutator   mMutator;
447     StaticAudioTrackPosLoopQueue::Observer      mPosLoopObserver;
448                         StaticAudioTrackState   mState;   // last communicated state to server
449                         StaticAudioTrackPosLoop mPosLoop; // snapshot of position and loop.
450 };
451 
452 // ----------------------------------------------------------------------------
453 
454 // Proxy used by AudioRecord client
455 class AudioRecordClientProxy : public ClientProxy {
456 public:
AudioRecordClientProxy(audio_track_cblk_t * cblk,void * buffers,size_t frameCount,size_t frameSize)457     AudioRecordClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
458             size_t frameSize)
459         : ClientProxy(cblk, buffers, frameCount, frameSize,
460             false /*isOut*/, false /*clientInServer*/) { }
~AudioRecordClientProxy()461     ~AudioRecordClientProxy() { }
462 
463     // Advances the client read pointer to the server write head pointer
464     // effectively flushing the client read buffer. The effect is
465     // instantaneous. Returns the number of frames flushed.
flush()466     uint32_t    flush() {
467         int32_t rear = android_atomic_acquire_load(&mCblk->u.mStreaming.mRear);
468         int32_t front = mCblk->u.mStreaming.mFront;
469         android_atomic_release_store(rear, &mCblk->u.mStreaming.mFront);
470         return (Modulo<int32_t>(rear) - front).unsignedValue();
471     }
472 };
473 
474 // ----------------------------------------------------------------------------
475 
476 // Proxy used by AudioFlinger server
477 class ServerProxy : public Proxy {
478 protected:
479     ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
480             bool isOut, bool clientInServer);
481 public:
~ServerProxy()482     virtual ~ServerProxy() { }
483 
484     // Obtain a buffer with filled frames (writing) or empty frames (reading).
485     // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
486     // calls to releaseBuffer().  In that case, the final obtainBuffer() is the one that effectively
487     // sets or extends the unreleased frame count.
488     // Always non-blocking.
489     // On entry:
490     //  buffer->mFrameCount should be initialized to maximum number of desired frames,
491     //      which must be > 0.
492     //  buffer->mNonContig is unused.
493     //  buffer->mRaw is unused.
494     //  ackFlush is true iff being called from Track::start to acknowledge a pending flush.
495     // On exit:
496     //  buffer->mFrameCount has the actual number of contiguous available frames,
497     //      which is always 0 when the return status != NO_ERROR.
498     //  buffer->mNonContig is the number of additional non-contiguous available frames.
499     //  buffer->mRaw is a pointer to the first available frame,
500     //      or NULL when buffer->mFrameCount == 0.
501     // The return status is one of:
502     //  NO_ERROR    Success, buffer->mFrameCount > 0.
503     //  WOULD_BLOCK No frames are available.
504     //  NO_INIT     Shared memory is corrupt.
505     virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush = false);
506 
507     // Release (some of) the frames last obtained.
508     // On entry, buffer->mFrameCount should have the number of frames to release,
509     // which must (cumulatively) be <= the number of frames last obtained but not yet released.
510     // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
511     // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
512     // On exit:
513     //  buffer->mFrameCount is zero.
514     //  buffer->mRaw is NULL.
515     virtual void        releaseBuffer(Buffer* buffer);
516 
517     // Return the total number of frames that AudioFlinger has obtained and released
framesReleased()518     virtual int64_t     framesReleased() const { return mReleased; }
519 
520     // Expose timestamp to client proxy. Should only be called by a single thread.
setTimestamp(const ExtendedTimestamp & timestamp)521     virtual void        setTimestamp(const ExtendedTimestamp &timestamp) {
522         mTimestampMutator.push(timestamp);
523     }
524 
525     // Flushes the shared ring buffer if the client had requested it using mStreaming.mFlush.
526     // If flush occurs then:
527     //   cblk->u.mStreaming.mFront, ServerProxy::mFlush and ServerProxy::mFlushed will be modified
528     //   client will be notified via Futex
529     virtual void    flushBufferIfNeeded();
530 
531     // Total count of the number of flushed frames since creation (never reset).
framesFlushed()532     virtual int64_t     framesFlushed() const { return mFlushed; }
533 
534     // Get dynamic buffer size from the shared control block.
getBufferSizeInFrames()535     uint32_t            getBufferSizeInFrames() const {
536         return android_atomic_acquire_load((int32_t *)&mCblk->mBufferSizeInFrames);
537     }
538 
539 protected:
540     size_t      mAvailToClient; // estimated frames available to client prior to releaseBuffer()
541     int32_t     mFlush;         // our copy of cblk->u.mStreaming.mFlush, for streaming output only
542     int64_t     mReleased;      // our copy of cblk->mServer, at 64 bit resolution
543     int64_t     mFlushed;       // flushed frames to account for client-server discrepancy
544     ExtendedTimestampQueue::Mutator mTimestampMutator;
545 };
546 
547 // Proxy used by AudioFlinger for servicing AudioTrack
548 class AudioTrackServerProxy : public ServerProxy {
549 public:
550     AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
551             size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0)
ServerProxy(cblk,buffers,frameCount,frameSize,true,clientInServer)552         : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer),
553           mPlaybackRateObserver(&cblk->mPlaybackRateQueue),
554           mUnderrunCount(0), mUnderrunning(false), mDrained(true) {
555         mCblk->mSampleRate = sampleRate;
556         mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
557     }
558 protected:
~AudioTrackServerProxy()559     virtual ~AudioTrackServerProxy() { }
560 
561 public:
562     // return value of these methods must be validated by the caller
getSampleRate()563     uint32_t    getSampleRate() const { return mCblk->mSampleRate; }
getSendLevel_U4_12()564     uint16_t    getSendLevel_U4_12() const { return mCblk->mSendLevel; }
getVolumeLR()565     gain_minifloat_packed_t getVolumeLR() const { return mCblk->mVolumeLR; }
566 
567     // estimated total number of filled frames available to server to read,
568     // which may include non-contiguous frames
569     virtual size_t      framesReady();
570 
571     // Currently AudioFlinger will call framesReady() for a fast track from two threads:
572     // FastMixer thread, and normal mixer thread.  This is dangerous, as the proxy is intended
573     // to be called from at most one thread of server, and one thread of client.
574     // As a temporary workaround, this method informs the proxy implementation that it
575     // should avoid doing a state queue poll from within framesReady().
576     // FIXME Change AudioFlinger to not call framesReady() from normal mixer thread.
framesReadyIsCalledByMultipleThreads()577     virtual void        framesReadyIsCalledByMultipleThreads() { }
578 
579     bool     setStreamEndDone();    // and return previous value
580 
581     // Add to the tally of underrun frames, and inform client of underrun
582     virtual void        tallyUnderrunFrames(uint32_t frameCount);
583 
584     // Return the total number of frames which AudioFlinger desired but were unavailable,
585     // and thus which resulted in an underrun.
getUnderrunFrames()586     virtual uint32_t    getUnderrunFrames() const { return mCblk->u.mStreaming.mUnderrunFrames; }
587 
588     // Return the playback speed and pitch read atomically. Not multi-thread safe on server side.
589     AudioPlaybackRate getPlaybackRate();
590 
591     // Set the internal drain state of the track buffer from the timestamp received.
setDrained(bool drained)592     virtual void        setDrained(bool drained) {
593         mDrained.store(drained);
594     }
595 
596     // Check if the internal drain state of the track buffer.
597     // This is not a guarantee, but advisory for determining whether the track is
598     // fully played out.
isDrained()599     virtual bool        isDrained() const {
600         return mDrained.load();
601     }
602 
603 private:
604     AudioPlaybackRate             mPlaybackRate;  // last observed playback rate
605     PlaybackRateQueue::Observer   mPlaybackRateObserver;
606 
607     // The server keeps a copy here where it is safe from the client.
608     uint32_t                      mUnderrunCount; // echoed to mCblk
609     bool                          mUnderrunning;  // used to detect edge of underrun
610 
611     std::atomic<bool>             mDrained; // is the track buffer drained
612 };
613 
614 class StaticAudioTrackServerProxy : public AudioTrackServerProxy {
615 public:
616     StaticAudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
617             size_t frameSize);
618 protected:
~StaticAudioTrackServerProxy()619     virtual ~StaticAudioTrackServerProxy() { }
620 
621 public:
622     virtual size_t      framesReady();
623     virtual void        framesReadyIsCalledByMultipleThreads();
624     virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush);
625     virtual void        releaseBuffer(Buffer* buffer);
626     virtual void        tallyUnderrunFrames(uint32_t frameCount);
getUnderrunFrames()627     virtual uint32_t    getUnderrunFrames() const { return 0; }
628 
629 private:
630     status_t            updateStateWithLoop(StaticAudioTrackState *localState,
631                                             const StaticAudioTrackState &update) const;
632     status_t            updateStateWithPosition(StaticAudioTrackState *localState,
633                                                 const StaticAudioTrackState &update) const;
634     ssize_t             pollPosition(); // poll for state queue update, and return current position
635     StaticAudioTrackSingleStateQueue::Observer  mObserver;
636     StaticAudioTrackPosLoopQueue::Mutator       mPosLoopMutator;
637     size_t              mFramesReadySafe; // Assuming size_t read/writes are atomic on 32 / 64 bit
638                                           // processors, this is a thread-safe version of
639                                           // mFramesReady.
640     int64_t             mFramesReady;     // The number of frames ready in the static buffer
641                                           // including loops.  This is 64 bits since loop mode
642                                           // can cause a track to appear to have a large number
643                                           // of frames. INT64_MAX means an infinite loop.
644     bool                mFramesReadyIsCalledByMultipleThreads;
645     StaticAudioTrackState mState;         // Server side state. Any updates from client must be
646                                           // passed by the mObserver SingleStateQueue.
647 };
648 
649 // Proxy used by AudioFlinger for servicing AudioRecord
650 class AudioRecordServerProxy : public ServerProxy {
651 public:
AudioRecordServerProxy(audio_track_cblk_t * cblk,void * buffers,size_t frameCount,size_t frameSize,bool clientInServer)652     AudioRecordServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
653             size_t frameSize, bool clientInServer)
654         : ServerProxy(cblk, buffers, frameCount, frameSize, false /*isOut*/, clientInServer) { }
655 
656 protected:
~AudioRecordServerProxy()657     virtual ~AudioRecordServerProxy() { }
658 };
659 
660 // ----------------------------------------------------------------------------
661 
662 }; // namespace android
663 
664 #endif // ANDROID_AUDIO_TRACK_SHARED_H
665