blob: 770f007e612425eda5b08c9fdb5f493ec5b86435 [file] [log] [blame]
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -08001/*
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
Glenn Kastenc56f3422014-03-21 17:53:17 -070023#include <audio_utils/minifloat.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080024#include <utils/threads.h>
Glenn Kastene3aa6592012-12-04 12:22:46 -080025#include <utils/Log.h>
Glenn Kasten9f80dd22012-12-18 15:57:32 -080026#include <utils/RefBase.h>
Glenn Kasten53dbe772015-01-06 10:46:38 -080027#include <audio_utils/roundup.h>
Andy Hung8edb8dc2015-03-26 19:13:55 -070028#include <media/AudioResamplerPublic.h>
Andy Hung90e8a972015-11-09 16:42:40 -080029#include <media/Modulo.h>
Glenn Kasten9f80dd22012-12-18 15:57:32 -080030#include <media/SingleStateQueue.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080031
32namespace android {
33
34// ----------------------------------------------------------------------------
35
Glenn Kasten96f60d82013-07-12 10:21:18 -070036// for audio_track_cblk_t::mFlags
Glenn Kasten9f80dd22012-12-18 15:57:32 -080037#define CBLK_UNDERRUN 0x01 // set by server immediately on output underrun, cleared by client
Glenn Kasten864585d2012-11-06 16:15:41 -080038#define CBLK_FORCEREADY 0x02 // set: track is considered ready immediately by AudioFlinger,
Glenn Kasten9c5fdd82012-11-05 13:38:15 -080039 // clear: track is ready when buffer full
Glenn Kasten864585d2012-11-06 16:15:41 -080040#define CBLK_INVALID 0x04 // track buffer invalidated by AudioFlinger, need to re-create
Glenn Kasten9f80dd22012-12-18 15:57:32 -080041#define CBLK_DISABLED 0x08 // output track disabled by AudioFlinger due to underrun,
42 // need to re-start. Unlike CBLK_UNDERRUN, this is not set
43 // immediately, but only after a long string of underruns.
44// 0x10 unused
45#define CBLK_LOOP_CYCLE 0x20 // set by server each time a loop cycle other than final one completes
46#define CBLK_LOOP_FINAL 0x40 // set by server when the final loop cycle completes
47#define CBLK_BUFFER_END 0x80 // set by server when the position reaches end of buffer if not looping
48#define CBLK_OVERRUN 0x100 // set by server immediately on input overrun, cleared by client
49#define CBLK_INTERRUPT 0x200 // set by client on interrupt(), cleared by client in obtainBuffer()
Richard Fitzgeraldad3af332013-03-25 16:54:37 +000050#define CBLK_STREAM_END_DONE 0x400 // set by server on render completion, cleared by client
51
52//EL_FIXME 20 seconds may not be enough and must be reconciled with new obtainBuffer implementation
Glenn Kastene198c362013-08-13 09:13:36 -070053#define MAX_RUN_OFFLOADED_TIMEOUT_MS 20000 // assuming up to a maximum of 20 seconds of offloaded
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080054
Glenn Kastene3aa6592012-12-04 12:22:46 -080055struct AudioTrackSharedStreaming {
56 // similar to NBAIO MonoPipe
Glenn Kasten9f80dd22012-12-18 15:57:32 -080057 // in continuously incrementing frame units, take modulo buffer size, which must be a power of 2
Glenn Kastenf59497b2015-01-26 16:35:47 -080058 volatile int32_t mFront; // read by consumer (output: server, input: client)
59 volatile int32_t mRear; // written by producer (output: client, input: server)
Glenn Kasten9f80dd22012-12-18 15:57:32 -080060 volatile int32_t mFlush; // incremented by client to indicate a request to flush;
61 // server notices and discards all data between mFront and mRear
Phil Burk2812d9e2016-01-04 10:34:30 -080062 volatile uint32_t mUnderrunFrames; // server increments for each unavailable but desired frame
63 volatile uint32_t mUnderrunCount; // server increments for each underrun occurrence
Glenn Kastene3aa6592012-12-04 12:22:46 -080064};
65
Andy Hung9b461582014-12-01 17:56:29 -080066// Represents a single state of an AudioTrack that was created in static mode (shared memory buffer
67// supplied by the client). This state needs to be communicated from the client to server. As this
68// state is too large to be updated atomically without a mutex, and mutexes aren't allowed here, the
69// state is wrapped by a SingleStateQueue.
70struct StaticAudioTrackState {
71 // Do not define constructors, destructors, or virtual methods as this is part of a
72 // union in shared memory and they will not get called properly.
73
74 // These fields should both be size_t, but since they are located in shared memory we
75 // force to 32-bit. The client and server may have different typedefs for size_t.
76
77 // The state has a sequence counter to indicate whether changes are made to loop or position.
78 // The sequence counter also currently indicates whether loop or position is first depending
79 // on which is greater; it jumps by max(mLoopSequence, mPositionSequence) + 1.
80
81 uint32_t mLoopStart;
82 uint32_t mLoopEnd;
83 int32_t mLoopCount;
84 uint32_t mLoopSequence; // a sequence counter to indicate changes to loop
85 uint32_t mPosition;
86 uint32_t mPositionSequence; // a sequence counter to indicate changes to position
87};
88
Glenn Kasten9f80dd22012-12-18 15:57:32 -080089typedef SingleStateQueue<StaticAudioTrackState> StaticAudioTrackSingleStateQueue;
90
Andy Hung4ede21d2014-12-12 15:37:34 -080091struct StaticAudioTrackPosLoop {
92 // Do not define constructors, destructors, or virtual methods as this is part of a
93 // union in shared memory and will not get called properly.
94
95 // These fields should both be size_t, but since they are located in shared memory we
96 // force to 32-bit. The client and server may have different typedefs for size_t.
97
98 // This struct information is stored in a single state queue to communicate the
99 // static AudioTrack server state to the client while data is consumed.
100 // It is smaller than StaticAudioTrackState to prevent unnecessary information from
101 // being sent.
102
103 uint32_t mBufferPosition;
104 int32_t mLoopCount;
105};
106
107typedef SingleStateQueue<StaticAudioTrackPosLoop> StaticAudioTrackPosLoopQueue;
108
Glenn Kastene3aa6592012-12-04 12:22:46 -0800109struct AudioTrackSharedStatic {
Andy Hung4ede21d2014-12-12 15:37:34 -0800110 // client requests to the server for loop or position changes.
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800111 StaticAudioTrackSingleStateQueue::Shared
112 mSingleStateQueue;
Andy Hung4ede21d2014-12-12 15:37:34 -0800113 // position info updated asynchronously by server and read by client,
114 // "for entertainment purposes only"
115 StaticAudioTrackPosLoopQueue::Shared
116 mPosLoopQueue;
Glenn Kastene3aa6592012-12-04 12:22:46 -0800117};
118
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700119typedef SingleStateQueue<AudioPlaybackRate> PlaybackRateQueue;
Andy Hung8edb8dc2015-03-26 19:13:55 -0700120
Glenn Kastene3aa6592012-12-04 12:22:46 -0800121// ----------------------------------------------------------------------------
122
Glenn Kasten1a0ae5b2012-02-03 10:24:48 -0800123// Important: do not add any virtual methods, including ~
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800124struct audio_track_cblk_t
125{
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800126 // Since the control block is always located in shared memory, this constructor
127 // is only used for placement new(). It is never used for regular new() or stack.
128 audio_track_cblk_t();
129 /*virtual*/ ~audio_track_cblk_t() { }
130
Glenn Kastene3aa6592012-12-04 12:22:46 -0800131 friend class Proxy;
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800132 friend class ClientProxy;
Glenn Kastene3aa6592012-12-04 12:22:46 -0800133 friend class AudioTrackClientProxy;
134 friend class AudioRecordClientProxy;
135 friend class ServerProxy;
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800136 friend class AudioTrackServerProxy;
137 friend class AudioRecordServerProxy;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800138
139 // The data members are grouped so that members accessed frequently and in the same context
140 // are in the same line of data cache.
Glenn Kasten99e53b82012-01-19 08:59:58 -0800141
Glenn Kastenf20e1d82013-07-12 09:45:18 -0700142 uint32_t mServer; // Number of filled frames consumed by server (mIsOut),
143 // or filled frames provided by server (!mIsOut).
144 // It is updated asynchronously by server without a barrier.
Glenn Kastenb187de12014-12-30 08:18:15 -0800145 // The value should be used
146 // "for entertainment purposes only",
Glenn Kastenf20e1d82013-07-12 09:45:18 -0700147 // which means don't make important decisions based on it.
Glenn Kasten22eb4e22012-11-07 14:03:00 -0800148
Glenn Kasten74935e42013-12-19 08:56:45 -0800149 uint32_t mPad1; // unused
Glenn Kasten99e53b82012-01-19 08:59:58 -0800150
Glenn Kasten0d09a9b2013-06-24 12:06:46 -0700151 volatile int32_t mFutex; // event flag: down (P) by client,
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800152 // up (V) by server or binderDied() or interrupt()
Glenn Kasten0d09a9b2013-06-24 12:06:46 -0700153#define CBLK_FUTEX_WAKE 1 // if event flag bit is set, then a deferred wake is pending
Glenn Kasten99e53b82012-01-19 08:59:58 -0800154
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800155private:
156
Glenn Kastenfdac7c02014-01-28 11:03:28 -0800157 // This field should be a size_t, but since it is located in shared memory we
158 // force to 32-bit. The client and server may have different typedefs for size_t.
159 uint32_t mMinimum; // server wakes up client if available >= mMinimum
Glenn Kastenb1cf75c2012-01-17 12:20:54 -0800160
Glenn Kastenc56f3422014-03-21 17:53:17 -0700161 // Stereo gains for AudioTrack only, not used by AudioRecord.
162 gain_minifloat_packed_t mVolumeLR;
Glenn Kastenb1cf75c2012-01-17 12:20:54 -0800163
Glenn Kastene3aa6592012-12-04 12:22:46 -0800164 uint32_t mSampleRate; // AudioTrack only: client's requested sample rate in Hz
165 // or 0 == default. Write-only client, read-only server.
Glenn Kasten99e53b82012-01-19 08:59:58 -0800166
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700167 PlaybackRateQueue::Shared mPlaybackRateQueue;
Andy Hung8edb8dc2015-03-26 19:13:55 -0700168
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800169 // client write-only, server read-only
170 uint16_t mSendLevel; // Fixed point U4.12 so 0x1000 means 1.0
171
Glenn Kastend054c322013-07-12 12:59:20 -0700172 uint16_t mPad2; // unused
Eric Laurentd1b449a2010-05-14 03:26:45 -0700173
Glenn Kastene3aa6592012-12-04 12:22:46 -0800174public:
Glenn Kasten99e53b82012-01-19 08:59:58 -0800175
Glenn Kasten96f60d82013-07-12 10:21:18 -0700176 volatile int32_t mFlags; // combinations of CBLK_*
Eric Laurent38ccae22011-03-28 18:37:07 -0700177
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800178public:
Glenn Kastene3aa6592012-12-04 12:22:46 -0800179 union {
180 AudioTrackSharedStreaming mStreaming;
181 AudioTrackSharedStatic mStatic;
182 int mAlign[8];
183 } u;
184
185 // Cache line boundary (32 bytes)
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800186};
187
Glenn Kastene3aa6592012-12-04 12:22:46 -0800188// ----------------------------------------------------------------------------
189
190// Proxy for shared memory control block, to isolate callers from needing to know the details.
191// There is exactly one ClientProxy and one ServerProxy per shared memory control block.
192// The proxies are located in normal memory, and are not multi-thread safe within a given side.
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800193class Proxy : public RefBase {
Glenn Kastene3aa6592012-12-04 12:22:46 -0800194protected:
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800195 Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut,
196 bool clientInServer);
Glenn Kastene3aa6592012-12-04 12:22:46 -0800197 virtual ~Proxy() { }
198
199public:
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800200 struct Buffer {
201 size_t mFrameCount; // number of frames available in this buffer
202 void* mRaw; // pointer to first frame
203 size_t mNonContig; // number of additional non-contiguous frames available
204 };
Glenn Kastene3aa6592012-12-04 12:22:46 -0800205
Phil Burkc0adecb2016-01-08 12:44:11 -0800206 size_t frameCount() const { return mFrameCount; }
207
Glenn Kastene3aa6592012-12-04 12:22:46 -0800208protected:
209 // These refer to shared memory, and are virtual addresses with respect to the current process.
210 // They may have different virtual addresses within the other process.
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800211 audio_track_cblk_t* const mCblk; // the control block
212 void* const mBuffers; // starting address of buffers
Glenn Kastene3aa6592012-12-04 12:22:46 -0800213
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800214 const size_t mFrameCount; // not necessarily a power of 2
215 const size_t mFrameSize; // in bytes
216 const size_t mFrameCountP2; // mFrameCount rounded to power of 2, streaming mode
217 const bool mIsOut; // true for AudioTrack, false for AudioRecord
218 const bool mClientInServer; // true for OutputTrack, false for AudioTrack & AudioRecord
219 bool mIsShutdown; // latch set to true when shared memory corruption detected
Glenn Kasten7db7df02013-06-25 16:13:23 -0700220 size_t mUnreleased; // unreleased frames remaining from most recent obtainBuffer
Glenn Kastene3aa6592012-12-04 12:22:46 -0800221};
222
223// ----------------------------------------------------------------------------
224
225// Proxy seen by AudioTrack client and AudioRecord client
226class ClientProxy : public Proxy {
Eric Laurent83b88082014-06-20 18:31:16 -0700227public:
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800228 ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
229 bool isOut, bool clientInServer);
Glenn Kastene3aa6592012-12-04 12:22:46 -0800230 virtual ~ClientProxy() { }
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800231
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800232 static const struct timespec kForever;
233 static const struct timespec kNonBlocking;
234
235 // Obtain a buffer with filled frames (reading) or empty frames (writing).
236 // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
237 // calls to releaseBuffer(). In that case, the final obtainBuffer() is the one that effectively
238 // sets or extends the unreleased frame count.
239 // On entry:
240 // buffer->mFrameCount should be initialized to maximum number of desired frames,
241 // which must be > 0.
242 // buffer->mNonContig is unused.
243 // buffer->mRaw is unused.
244 // requested is the requested timeout in local monotonic delta time units:
245 // NULL or &kNonBlocking means non-blocking (zero timeout).
246 // &kForever means block forever (infinite timeout).
247 // Other values mean a specific timeout in local monotonic delta time units.
248 // elapsed is a pointer to a location that will hold the total local monotonic time that
249 // elapsed while blocked, or NULL if not needed.
250 // On exit:
251 // buffer->mFrameCount has the actual number of contiguous available frames,
252 // which is always 0 when the return status != NO_ERROR.
253 // buffer->mNonContig is the number of additional non-contiguous available frames.
254 // buffer->mRaw is a pointer to the first available frame,
255 // or NULL when buffer->mFrameCount == 0.
256 // The return status is one of:
257 // NO_ERROR Success, buffer->mFrameCount > 0.
258 // WOULD_BLOCK Non-blocking mode and no frames are available.
259 // TIMED_OUT Timeout occurred before any frames became available.
260 // This can happen even for infinite timeout, due to a spurious wakeup.
261 // In this case, the caller should investigate and then re-try as appropriate.
262 // DEAD_OBJECT Server has died or invalidated, caller should destroy this proxy and re-create.
263 // -EINTR Call has been interrupted. Look around to see why, and then perhaps try again.
264 // NO_INIT Shared memory is corrupt.
Glenn Kasten7db7df02013-06-25 16:13:23 -0700265 // Assertion failure on entry, if buffer == NULL or buffer->mFrameCount == 0.
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800266 status_t obtainBuffer(Buffer* buffer, const struct timespec *requested = NULL,
267 struct timespec *elapsed = NULL);
268
269 // Release (some of) the frames last obtained.
270 // On entry, buffer->mFrameCount should have the number of frames to release,
271 // which must (cumulatively) be <= the number of frames last obtained but not yet released.
272 // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
273 // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
274 // On exit:
275 // buffer->mFrameCount is zero.
276 // buffer->mRaw is NULL.
277 void releaseBuffer(Buffer* buffer);
278
279 // Call after detecting server's death
280 void binderDied();
281
282 // Call to force an obtainBuffer() to return quickly with -EINTR
283 void interrupt();
284
Andy Hung90e8a972015-11-09 16:42:40 -0800285 Modulo<uint32_t> getPosition() {
Glenn Kastenf20e1d82013-07-12 09:45:18 -0700286 return mEpoch + mCblk->mServer;
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800287 }
288
Phil Burkc0adecb2016-01-08 12:44:11 -0800289 void setEpoch(const Modulo<uint32_t> &epoch) {
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800290 mEpoch = epoch;
291 }
292
293 void setMinimum(size_t minimum) {
Glenn Kastenfdac7c02014-01-28 11:03:28 -0800294 // This can only happen on a 64-bit client
295 if (minimum > UINT32_MAX) {
296 minimum = UINT32_MAX;
297 }
298 mCblk->mMinimum = (uint32_t) minimum;
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800299 }
300
301 // Return the number of frames that would need to be obtained and released
302 // in order for the client to be aligned at start of buffer
303 virtual size_t getMisalignment();
304
Andy Hung90e8a972015-11-09 16:42:40 -0800305 Modulo<uint32_t> getEpoch() const {
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800306 return mEpoch;
307 }
308
Phil Burkc0adecb2016-01-08 12:44:11 -0800309 size_t getBufferSizeInFrames() const { return mBufferSizeInFrames; }
310 // See documentation for AudioTrack.setBufferSizeInFrames()
311 size_t setBufferSizeInFrames(size_t requestedSize);
312
313protected:
314 // This is set by AudioTrack.setBufferSizeInFrames().
315 // A write will not fill the buffer above this limit.
316 size_t mBufferSizeInFrames; // effective size of the buffer
317
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800318private:
Andy Hung90e8a972015-11-09 16:42:40 -0800319 Modulo<uint32_t> mEpoch;
Glenn Kastene3aa6592012-12-04 12:22:46 -0800320};
321
322// ----------------------------------------------------------------------------
323
324// Proxy used by AudioTrack client, which also includes AudioFlinger::PlaybackThread::OutputTrack
325class AudioTrackClientProxy : public ClientProxy {
326public:
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800327 AudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
328 size_t frameSize, bool clientInServer = false)
329 : ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/,
Andy Hung8edb8dc2015-03-26 19:13:55 -0700330 clientInServer),
331 mPlaybackRateMutator(&cblk->mPlaybackRateQueue) { }
Glenn Kastene3aa6592012-12-04 12:22:46 -0800332 virtual ~AudioTrackClientProxy() { }
333
334 // No barriers on the following operations, so the ordering of loads/stores
335 // with respect to other parameters is UNPREDICTABLE. That's considered safe.
336
337 // caller must limit to 0.0 <= sendLevel <= 1.0
338 void setSendLevel(float sendLevel) {
339 mCblk->mSendLevel = uint16_t(sendLevel * 0x1000);
340 }
341
Glenn Kastenc56f3422014-03-21 17:53:17 -0700342 // set stereo gains
343 void setVolumeLR(gain_minifloat_packed_t volumeLR) {
Glenn Kastene3aa6592012-12-04 12:22:46 -0800344 mCblk->mVolumeLR = volumeLR;
345 }
346
347 void setSampleRate(uint32_t sampleRate) {
348 mCblk->mSampleRate = sampleRate;
349 }
350
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700351 void setPlaybackRate(const AudioPlaybackRate& playbackRate) {
Andy Hung8edb8dc2015-03-26 19:13:55 -0700352 mPlaybackRateMutator.push(playbackRate);
353 }
354
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800355 virtual void flush();
356
357 virtual uint32_t getUnderrunFrames() const {
358 return mCblk->u.mStreaming.mUnderrunFrames;
359 }
Phil Burk2812d9e2016-01-04 10:34:30 -0800360 virtual uint32_t getUnderrunCount() const {
361 return mCblk->u.mStreaming.mUnderrunCount;
362 }
Eric Laurentbfb1b832013-01-07 09:53:42 -0800363
364 bool clearStreamEndDone(); // and return previous value
365
366 bool getStreamEndDone() const;
367
Richard Fitzgeraldb1a270d2013-05-14 12:12:21 +0100368 status_t waitStreamEndDone(const struct timespec *requested);
Andy Hung8edb8dc2015-03-26 19:13:55 -0700369
370private:
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700371 PlaybackRateQueue::Mutator mPlaybackRateMutator;
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800372};
373
374class StaticAudioTrackClientProxy : public AudioTrackClientProxy {
375public:
376 StaticAudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
377 size_t frameSize);
378 virtual ~StaticAudioTrackClientProxy() { }
379
380 virtual void flush();
381
382#define MIN_LOOP 16 // minimum length of each loop iteration in frames
Andy Hung9b461582014-12-01 17:56:29 -0800383
384 // setLoop(), setBufferPosition(), and setBufferPositionAndLoop() set the
385 // static buffer position and looping parameters. These commands are not
386 // synchronous (they do not wait or block); instead they take effect at the
387 // next buffer data read from the server side. However, the client side
388 // getters will read a cached version of the position and loop variables
389 // until the setting takes effect.
390 //
391 // setBufferPositionAndLoop() is equivalent to calling, in order, setLoop() and
392 // setBufferPosition().
393 //
394 // The functions should not be relied upon to do parameter or state checking.
395 // That is done at the AudioTrack level.
396
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800397 void setLoop(size_t loopStart, size_t loopEnd, int loopCount);
Andy Hung9b461582014-12-01 17:56:29 -0800398 void setBufferPosition(size_t position);
399 void setBufferPositionAndLoop(size_t position, size_t loopStart, size_t loopEnd,
400 int loopCount);
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800401 size_t getBufferPosition();
Andy Hung4ede21d2014-12-12 15:37:34 -0800402 // getBufferPositionAndLoopCount() provides the proper snapshot of
403 // position and loopCount together.
404 void getBufferPositionAndLoopCount(size_t *position, int *loopCount);
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800405
406 virtual size_t getMisalignment() {
407 return 0;
Glenn Kastene3aa6592012-12-04 12:22:46 -0800408 }
409
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800410 virtual uint32_t getUnderrunFrames() const {
411 return 0;
Glenn Kastene3aa6592012-12-04 12:22:46 -0800412 }
413
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800414private:
415 StaticAudioTrackSingleStateQueue::Mutator mMutator;
Andy Hung4ede21d2014-12-12 15:37:34 -0800416 StaticAudioTrackPosLoopQueue::Observer mPosLoopObserver;
Andy Hung9b461582014-12-01 17:56:29 -0800417 StaticAudioTrackState mState; // last communicated state to server
Andy Hung4ede21d2014-12-12 15:37:34 -0800418 StaticAudioTrackPosLoop mPosLoop; // snapshot of position and loop.
Glenn Kastene3aa6592012-12-04 12:22:46 -0800419};
420
421// ----------------------------------------------------------------------------
422
423// Proxy used by AudioRecord client
424class AudioRecordClientProxy : public ClientProxy {
425public:
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800426 AudioRecordClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
427 size_t frameSize)
428 : ClientProxy(cblk, buffers, frameCount, frameSize,
429 false /*isOut*/, false /*clientInServer*/) { }
Glenn Kastene3aa6592012-12-04 12:22:46 -0800430 ~AudioRecordClientProxy() { }
Glenn Kastene3aa6592012-12-04 12:22:46 -0800431};
432
433// ----------------------------------------------------------------------------
434
435// Proxy used by AudioFlinger server
436class ServerProxy : public Proxy {
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800437protected:
438 ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
439 bool isOut, bool clientInServer);
Glenn Kastene3aa6592012-12-04 12:22:46 -0800440public:
Glenn Kastene3aa6592012-12-04 12:22:46 -0800441 virtual ~ServerProxy() { }
442
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800443 // Obtain a buffer with filled frames (writing) or empty frames (reading).
444 // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
445 // calls to releaseBuffer(). In that case, the final obtainBuffer() is the one that effectively
446 // sets or extends the unreleased frame count.
447 // Always non-blocking.
448 // On entry:
449 // buffer->mFrameCount should be initialized to maximum number of desired frames,
450 // which must be > 0.
451 // buffer->mNonContig is unused.
452 // buffer->mRaw is unused.
Glenn Kasten2e422c42013-10-18 13:00:29 -0700453 // ackFlush is true iff being called from Track::start to acknowledge a pending flush.
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800454 // On exit:
455 // buffer->mFrameCount has the actual number of contiguous available frames,
456 // which is always 0 when the return status != NO_ERROR.
457 // buffer->mNonContig is the number of additional non-contiguous available frames.
458 // buffer->mRaw is a pointer to the first available frame,
459 // or NULL when buffer->mFrameCount == 0.
460 // The return status is one of:
461 // NO_ERROR Success, buffer->mFrameCount > 0.
462 // WOULD_BLOCK No frames are available.
463 // NO_INIT Shared memory is corrupt.
Glenn Kasten2e422c42013-10-18 13:00:29 -0700464 virtual status_t obtainBuffer(Buffer* buffer, bool ackFlush = false);
Glenn Kastene3aa6592012-12-04 12:22:46 -0800465
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800466 // Release (some of) the frames last obtained.
467 // On entry, buffer->mFrameCount should have the number of frames to release,
468 // which must (cumulatively) be <= the number of frames last obtained but not yet released.
469 // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
470 // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
471 // On exit:
472 // buffer->mFrameCount is zero.
473 // buffer->mRaw is NULL.
474 virtual void releaseBuffer(Buffer* buffer);
475
476protected:
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800477 size_t mAvailToClient; // estimated frames available to client prior to releaseBuffer()
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800478 int32_t mFlush; // our copy of cblk->u.mStreaming.mFlush, for streaming output only
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800479};
480
481// Proxy used by AudioFlinger for servicing AudioTrack
482class AudioTrackServerProxy : public ServerProxy {
483public:
484 AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
Eric Laurent83b88082014-06-20 18:31:16 -0700485 size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0)
Andy Hung8edb8dc2015-03-26 19:13:55 -0700486 : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer),
Phil Burk2812d9e2016-01-04 10:34:30 -0800487 mPlaybackRateObserver(&cblk->mPlaybackRateQueue),
488 mUnderrunCount(0), mUnderrunning(false) {
Eric Laurent83b88082014-06-20 18:31:16 -0700489 mCblk->mSampleRate = sampleRate;
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700490 mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
Eric Laurent83b88082014-06-20 18:31:16 -0700491 }
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800492protected:
493 virtual ~AudioTrackServerProxy() { }
494
495public:
Glenn Kastene3aa6592012-12-04 12:22:46 -0800496 // return value of these methods must be validated by the caller
497 uint32_t getSampleRate() const { return mCblk->mSampleRate; }
498 uint16_t getSendLevel_U4_12() const { return mCblk->mSendLevel; }
Glenn Kastenc56f3422014-03-21 17:53:17 -0700499 gain_minifloat_packed_t getVolumeLR() const { return mCblk->mVolumeLR; }
Glenn Kastene3aa6592012-12-04 12:22:46 -0800500
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800501 // estimated total number of filled frames available to server to read,
502 // which may include non-contiguous frames
503 virtual size_t framesReady();
Glenn Kastene3aa6592012-12-04 12:22:46 -0800504
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800505 // Currently AudioFlinger will call framesReady() for a fast track from two threads:
506 // FastMixer thread, and normal mixer thread. This is dangerous, as the proxy is intended
507 // to be called from at most one thread of server, and one thread of client.
508 // As a temporary workaround, this method informs the proxy implementation that it
509 // should avoid doing a state queue poll from within framesReady().
510 // FIXME Change AudioFlinger to not call framesReady() from normal mixer thread.
511 virtual void framesReadyIsCalledByMultipleThreads() { }
Eric Laurentbfb1b832013-01-07 09:53:42 -0800512
513 bool setStreamEndDone(); // and return previous value
Glenn Kasten82aaf942013-07-17 16:05:07 -0700514
515 // Add to the tally of underrun frames, and inform client of underrun
516 virtual void tallyUnderrunFrames(uint32_t frameCount);
517
518 // Return the total number of frames which AudioFlinger desired but were unavailable,
519 // and thus which resulted in an underrun.
520 virtual uint32_t getUnderrunFrames() const { return mCblk->u.mStreaming.mUnderrunFrames; }
Glenn Kastenbd096fd2013-08-23 13:53:56 -0700521
522 // Return the total number of frames that AudioFlinger has obtained and released
523 virtual size_t framesReleased() const { return mCblk->mServer; }
Andy Hung8edb8dc2015-03-26 19:13:55 -0700524
525 // Return the playback speed and pitch read atomically. Not multi-thread safe on server side.
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700526 AudioPlaybackRate getPlaybackRate();
Andy Hung8edb8dc2015-03-26 19:13:55 -0700527
528private:
Ricardo Garcia5a8a95d2015-04-18 14:47:04 -0700529 AudioPlaybackRate mPlaybackRate; // last observed playback rate
530 PlaybackRateQueue::Observer mPlaybackRateObserver;
Phil Burk2812d9e2016-01-04 10:34:30 -0800531
532 // The server keeps a copy here where it is safe from the client.
533 uint32_t mUnderrunCount; // echoed to mCblk
534 bool mUnderrunning; // used to detect edge of underrun
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800535};
536
537class StaticAudioTrackServerProxy : public AudioTrackServerProxy {
538public:
539 StaticAudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
540 size_t frameSize);
541protected:
542 virtual ~StaticAudioTrackServerProxy() { }
543
544public:
545 virtual size_t framesReady();
546 virtual void framesReadyIsCalledByMultipleThreads();
Glenn Kasten2e422c42013-10-18 13:00:29 -0700547 virtual status_t obtainBuffer(Buffer* buffer, bool ackFlush);
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800548 virtual void releaseBuffer(Buffer* buffer);
Glenn Kasten82aaf942013-07-17 16:05:07 -0700549 virtual void tallyUnderrunFrames(uint32_t frameCount);
550 virtual uint32_t getUnderrunFrames() const { return 0; }
Glenn Kastene3aa6592012-12-04 12:22:46 -0800551
552private:
Andy Hung9b461582014-12-01 17:56:29 -0800553 status_t updateStateWithLoop(StaticAudioTrackState *localState,
554 const StaticAudioTrackState &update) const;
555 status_t updateStateWithPosition(StaticAudioTrackState *localState,
556 const StaticAudioTrackState &update) const;
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800557 ssize_t pollPosition(); // poll for state queue update, and return current position
558 StaticAudioTrackSingleStateQueue::Observer mObserver;
Andy Hung4ede21d2014-12-12 15:37:34 -0800559 StaticAudioTrackPosLoopQueue::Mutator mPosLoopMutator;
Andy Hungcb2129b2014-11-11 12:17:22 -0800560 size_t mFramesReadySafe; // Assuming size_t read/writes are atomic on 32 / 64 bit
561 // processors, this is a thread-safe version of
562 // mFramesReady.
563 int64_t mFramesReady; // The number of frames ready in the static buffer
564 // including loops. This is 64 bits since loop mode
565 // can cause a track to appear to have a large number
566 // of frames. INT64_MAX means an infinite loop.
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800567 bool mFramesReadyIsCalledByMultipleThreads;
Andy Hung9b461582014-12-01 17:56:29 -0800568 StaticAudioTrackState mState; // Server side state. Any updates from client must be
569 // passed by the mObserver SingleStateQueue.
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800570};
Glenn Kastene3aa6592012-12-04 12:22:46 -0800571
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800572// Proxy used by AudioFlinger for servicing AudioRecord
573class AudioRecordServerProxy : public ServerProxy {
574public:
575 AudioRecordServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
Eric Laurent83b88082014-06-20 18:31:16 -0700576 size_t frameSize, bool clientInServer)
577 : ServerProxy(cblk, buffers, frameCount, frameSize, false /*isOut*/, clientInServer) { }
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800578protected:
579 virtual ~AudioRecordServerProxy() { }
Glenn Kastene3aa6592012-12-04 12:22:46 -0800580};
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800581
582// ----------------------------------------------------------------------------
583
584}; // namespace android
585
586#endif // ANDROID_AUDIO_TRACK_SHARED_H