189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/*
289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * you may not use this file except in compliance with the License.
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * You may obtain a copy of the License at
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * See the License for the specific language governing permissions and
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * limitations under the License.
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#ifndef ANDROID_AUDIO_TRACK_SHARED_H
1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define ANDROID_AUDIO_TRACK_SHARED_H
1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <stdint.h>
2189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/types.h>
2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten#include <audio_utils/minifloat.h>
2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/threads.h>
25e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten#include <utils/Log.h>
269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#include <utils/RefBase.h>
2753dbe77b9f50cdd0de88b9d25dd643e90c8ba68bGlenn Kasten#include <audio_utils/roundup.h>
288edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung#include <media/AudioResamplerPublic.h>
293f0c902beb53a245c9db35e871607dba05b8d391Andy Hung#include <media/AudioTimestamp.h>
3090e8a97dd5c9d391d7a2ea6a2290ed976f928379Andy Hung#include <media/Modulo.h>
319f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#include <media/SingleStateQueue.h>
3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android {
3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ----------------------------------------------------------------------------
3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3796f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten// for audio_track_cblk_t::mFlags
389f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_UNDERRUN   0x01 // set by server immediately on output underrun, cleared by client
39864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten#define CBLK_FORCEREADY 0x02 // set: track is considered ready immediately by AudioFlinger,
409c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten                             // clear: track is ready when buffer full
41864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten#define CBLK_INVALID    0x04 // track buffer invalidated by AudioFlinger, need to re-create
429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_DISABLED   0x08 // output track disabled by AudioFlinger due to underrun,
439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                             // need to re-start.  Unlike CBLK_UNDERRUN, this is not set
449f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                             // immediately, but only after a long string of underruns.
459f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten// 0x10 unused
469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_LOOP_CYCLE 0x20 // set by server each time a loop cycle other than final one completes
479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_LOOP_FINAL 0x40 // set by server when the final loop cycle completes
489f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_BUFFER_END 0x80 // set by server when the position reaches end of buffer if not looping
499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_OVERRUN   0x100 // set by server immediately on input overrun, cleared by client
509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_INTERRUPT 0x200 // set by client on interrupt(), cleared by client in obtainBuffer()
51ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald#define CBLK_STREAM_END_DONE 0x400 // set by server on render completion, cleared by client
52ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
53ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald//EL_FIXME 20 seconds may not be enough and must be reconciled with new obtainBuffer implementation
54e198c360d5e75a9b2097844c495c10902e7e8500Glenn Kasten#define MAX_RUN_OFFLOADED_TIMEOUT_MS 20000 // assuming up to a maximum of 20 seconds of offloaded
5589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
56e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenstruct AudioTrackSharedStreaming {
57e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // similar to NBAIO MonoPipe
589f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // in continuously incrementing frame units, take modulo buffer size, which must be a power of 2
59f59497bd3c190e087202043de5450ef06e92b27dGlenn Kasten    volatile int32_t mFront;    // read by consumer (output: server, input: client)
60f59497bd3c190e087202043de5450ef06e92b27dGlenn Kasten    volatile int32_t mRear;     // written by producer (output: client, input: server)
619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    volatile int32_t mFlush;    // incremented by client to indicate a request to flush;
629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                                // server notices and discards all data between mFront and mRear
632812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk    volatile uint32_t mUnderrunFrames; // server increments for each unavailable but desired frame
642812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk    volatile uint32_t mUnderrunCount;  // server increments for each underrun occurrence
65e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
66e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
679b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung// Represents a single state of an AudioTrack that was created in static mode (shared memory buffer
689b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung// supplied by the client).  This state needs to be communicated from the client to server.  As this
699b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung// state is too large to be updated atomically without a mutex, and mutexes aren't allowed here, the
709b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung// state is wrapped by a SingleStateQueue.
719b4615887c23548438fd0d8e3d8f04ac21912850Andy Hungstruct StaticAudioTrackState {
729b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // Do not define constructors, destructors, or virtual methods as this is part of a
739b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // union in shared memory and they will not get called properly.
749b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
759b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // These fields should both be size_t, but since they are located in shared memory we
769b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // force to 32-bit.  The client and server may have different typedefs for size_t.
779b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
789b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // The state has a sequence counter to indicate whether changes are made to loop or position.
799b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // The sequence counter also currently indicates whether loop or position is first depending
809b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // on which is greater; it jumps by max(mLoopSequence, mPositionSequence) + 1.
819b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
829b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    uint32_t    mLoopStart;
839b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    uint32_t    mLoopEnd;
849b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    int32_t     mLoopCount;
859b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    uint32_t    mLoopSequence; // a sequence counter to indicate changes to loop
869b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    uint32_t    mPosition;
879b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    uint32_t    mPositionSequence; // a sequence counter to indicate changes to position
889b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung};
899b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastentypedef SingleStateQueue<StaticAudioTrackState> StaticAudioTrackSingleStateQueue;
919f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
924ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hungstruct StaticAudioTrackPosLoop {
934ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // Do not define constructors, destructors, or virtual methods as this is part of a
944ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // union in shared memory and will not get called properly.
954ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
964ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // These fields should both be size_t, but since they are located in shared memory we
974ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // force to 32-bit.  The client and server may have different typedefs for size_t.
984ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
994ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // This struct information is stored in a single state queue to communicate the
1004ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // static AudioTrack server state to the client while data is consumed.
1014ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // It is smaller than StaticAudioTrackState to prevent unnecessary information from
1024ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // being sent.
1034ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
1044ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    uint32_t mBufferPosition;
1054ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    int32_t  mLoopCount;
1064ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung};
1074ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
1084ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hungtypedef SingleStateQueue<StaticAudioTrackPosLoop> StaticAudioTrackPosLoopQueue;
1094ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
110e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenstruct AudioTrackSharedStatic {
1114ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // client requests to the server for loop or position changes.
1129f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    StaticAudioTrackSingleStateQueue::Shared
1139f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                    mSingleStateQueue;
1144ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // position info updated asynchronously by server and read by client,
1154ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // "for entertainment purposes only"
1164ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    StaticAudioTrackPosLoopQueue::Shared
1174ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung                    mPosLoopQueue;
118e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
119e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
1205a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garciatypedef SingleStateQueue<AudioPlaybackRate> PlaybackRateQueue;
1218edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung
1223f0c902beb53a245c9db35e871607dba05b8d391Andy Hungtypedef SingleStateQueue<ExtendedTimestamp> ExtendedTimestampQueue;
1233f0c902beb53a245c9db35e871607dba05b8d391Andy Hung
124e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// ----------------------------------------------------------------------------
125e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
1261a0ae5be3d1273cba12584b33830d859510fbf82Glenn Kasten// Important: do not add any virtual methods, including ~
12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstruct audio_track_cblk_t
12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
1299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                // Since the control block is always located in shared memory, this constructor
1309f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                // is only used for placement new().  It is never used for regular new() or stack.
1319f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                            audio_track_cblk_t();
1329f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                /*virtual*/ ~audio_track_cblk_t() { }
1339f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
134e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                friend class Proxy;
1359f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                friend class ClientProxy;
136e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                friend class AudioTrackClientProxy;
137e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                friend class AudioRecordClientProxy;
138e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                friend class ServerProxy;
1399f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                friend class AudioTrackServerProxy;
1409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                friend class AudioRecordServerProxy;
14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // The data members are grouped so that members accessed frequently and in the same context
14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // are in the same line of data cache.
14499e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten
145f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten                uint32_t    mServer;    // Number of filled frames consumed by server (mIsOut),
146f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten                                        // or filled frames provided by server (!mIsOut).
147f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten                                        // It is updated asynchronously by server without a barrier.
148b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten                                        // The value should be used
149b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten                                        // "for entertainment purposes only",
150f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten                                        // which means don't make important decisions based on it.
15122eb4e239fbe9103568147d566d7482e480350b8Glenn Kasten
15274935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten                uint32_t    mPad1;      // unused
15399e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten
1540d09a9bec07b3bec78bd473ff0bfcf0a261f3f25Glenn Kasten    volatile    int32_t     mFutex;     // event flag: down (P) by client,
1559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                                        // up (V) by server or binderDied() or interrupt()
1560d09a9bec07b3bec78bd473ff0bfcf0a261f3f25Glenn Kasten#define CBLK_FUTEX_WAKE 1               // if event flag bit is set, then a deferred wake is pending
1579f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
1589f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprivate:
15999e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten
160fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten                // This field should be a size_t, but since it is located in shared memory we
161fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten                // force to 32-bit.  The client and server may have different typedefs for size_t.
162fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten                uint32_t    mMinimum;       // server wakes up client if available >= mMinimum
163b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten
164c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten                // Stereo gains for AudioTrack only, not used by AudioRecord.
165c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten                gain_minifloat_packed_t mVolumeLR;
166b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten
167e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                uint32_t    mSampleRate;    // AudioTrack only: client's requested sample rate in Hz
168e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                                            // or 0 == default. Write-only client, read-only server.
16999e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten
1705a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia                PlaybackRateQueue::Shared mPlaybackRateQueue;
1718edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung
1729f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                // client write-only, server read-only
1739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                uint16_t    mSendLevel;      // Fixed point U4.12 so 0x1000 means 1.0
1749f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
175d054c32443a493513ab63529b0c8b1aca290278cGlenn Kasten                uint16_t    mPad2;           // unused
176d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent
1773f0c902beb53a245c9db35e871607dba05b8d391Andy Hung                // server write-only, client read
1788ce8e264d0bf09ec131e4a7701fe1ebc3a678f8bEric Laurent                ExtendedTimestampQueue::Shared mExtendedTimestampQueue;
179818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
180e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk                // This is set by AudioTrack.setBufferSizeInFrames().
181e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk                // A write will not fill the buffer above this limit.
182e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk    volatile    uint32_t   mBufferSizeInFrames;  // effective size of the buffer
183e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk
184e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenpublic:
18599e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten
18696f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten    volatile    int32_t     mFlags;         // combinations of CBLK_*
18738ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent
1889f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
189e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                union {
190e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                    AudioTrackSharedStreaming   mStreaming;
191e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                    AudioTrackSharedStatic      mStatic;
192e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                    int                         mAlign[8];
193e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                } u;
194e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
195e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                // Cache line boundary (32 bytes)
19689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project};
19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
198e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// ----------------------------------------------------------------------------
199e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
200e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// Proxy for shared memory control block, to isolate callers from needing to know the details.
201e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// There is exactly one ClientProxy and one ServerProxy per shared memory control block.
202e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// The proxies are located in normal memory, and are not multi-thread safe within a given side.
2039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenclass Proxy : public RefBase {
204e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenprotected:
2059f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut,
2069f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            bool clientInServer);
207e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    virtual ~Proxy() { }
208e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
209e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenpublic:
2109f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    struct Buffer {
2119f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        size_t  mFrameCount;            // number of frames available in this buffer
2129f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        void*   mRaw;                   // pointer to first frame
2139f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        size_t  mNonContig;             // number of additional non-contiguous frames available
2149f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    };
215e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
216c0adecb800b197cb8c028513130ebabf2d0f37baPhil Burk    size_t frameCount() const { return mFrameCount; }
217c0adecb800b197cb8c028513130ebabf2d0f37baPhil Burk
218e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenprotected:
219e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // These refer to shared memory, and are virtual addresses with respect to the current process.
220e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // They may have different virtual addresses within the other process.
2219f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    audio_track_cblk_t* const   mCblk;  // the control block
2229f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void* const     mBuffers;           // starting address of buffers
2239f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const size_t    mFrameCount;        // not necessarily a power of 2
2259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const size_t    mFrameSize;         // in bytes
2269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const size_t    mFrameCountP2;      // mFrameCount rounded to power of 2, streaming mode
2279f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const bool      mIsOut;             // true for AudioTrack, false for AudioRecord
2289f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const bool      mClientInServer;    // true for OutputTrack, false for AudioTrack & AudioRecord
2299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    bool            mIsShutdown;        // latch set to true when shared memory corruption detected
2307db7df0e8d9d7cee8ba374468cdbfa0108e3337cGlenn Kasten    size_t          mUnreleased;        // unreleased frames remaining from most recent obtainBuffer
231e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
232e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
233e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// ----------------------------------------------------------------------------
234e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
235e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// Proxy seen by AudioTrack client and AudioRecord client
236e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenclass ClientProxy : public Proxy {
23783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentpublic:
2389f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
2399f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            bool isOut, bool clientInServer);
240e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    virtual ~ClientProxy() { }
2419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    static const struct timespec kForever;
2439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    static const struct timespec kNonBlocking;
2449f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2459f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Obtain a buffer with filled frames (reading) or empty frames (writing).
2469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
2479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // calls to releaseBuffer().  In that case, the final obtainBuffer() is the one that effectively
2489f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // sets or extends the unreleased frame count.
2499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On entry:
2509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mFrameCount should be initialized to maximum number of desired frames,
2519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      which must be > 0.
2529f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mNonContig is unused.
2539f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mRaw is unused.
2549f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  requested is the requested timeout in local monotonic delta time units:
2559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      NULL or &kNonBlocking means non-blocking (zero timeout).
2569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      &kForever means block forever (infinite timeout).
2579f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      Other values mean a specific timeout in local monotonic delta time units.
2589f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  elapsed is a pointer to a location that will hold the total local monotonic time that
2599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      elapsed while blocked, or NULL if not needed.
2609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On exit:
2619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mFrameCount has the actual number of contiguous available frames,
2629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      which is always 0 when the return status != NO_ERROR.
2639f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mNonContig is the number of additional non-contiguous available frames.
2649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mRaw is a pointer to the first available frame,
2659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      or NULL when buffer->mFrameCount == 0.
2669f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // The return status is one of:
2679f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  NO_ERROR    Success, buffer->mFrameCount > 0.
2689f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  WOULD_BLOCK Non-blocking mode and no frames are available.
2699f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  TIMED_OUT   Timeout occurred before any frames became available.
2709f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //              This can happen even for infinite timeout, due to a spurious wakeup.
2719f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //              In this case, the caller should investigate and then re-try as appropriate.
2729f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  DEAD_OBJECT Server has died or invalidated, caller should destroy this proxy and re-create.
2739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  -EINTR      Call has been interrupted.  Look around to see why, and then perhaps try again.
2749f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  NO_INIT     Shared memory is corrupt.
2754d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    //  NOT_ENOUGH_DATA Server has disabled the track because of underrun: restart the track
2764d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    //              if still in active state.
2777db7df0e8d9d7cee8ba374468cdbfa0108e3337cGlenn Kasten    // Assertion failure on entry, if buffer == NULL or buffer->mFrameCount == 0.
2789f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t    obtainBuffer(Buffer* buffer, const struct timespec *requested = NULL,
2799f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            struct timespec *elapsed = NULL);
2809f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2819f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Release (some of) the frames last obtained.
2829f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On entry, buffer->mFrameCount should have the number of frames to release,
2839f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // which must (cumulatively) be <= the number of frames last obtained but not yet released.
2849f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
2859f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
2869f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On exit:
2879f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mFrameCount is zero.
2889f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mRaw is NULL.
2899f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void        releaseBuffer(Buffer* buffer);
2909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2919f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Call after detecting server's death
2929f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void        binderDied();
2939f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2949f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Call to force an obtainBuffer() to return quickly with -EINTR
2959f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void        interrupt();
2969f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
29790e8a97dd5c9d391d7a2ea6a2290ed976f928379Andy Hung    Modulo<uint32_t> getPosition() {
298f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten        return mEpoch + mCblk->mServer;
2999f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
3009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
301c0adecb800b197cb8c028513130ebabf2d0f37baPhil Burk    void        setEpoch(const Modulo<uint32_t> &epoch) {
3029f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mEpoch = epoch;
3039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
3049f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
3059f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void        setMinimum(size_t minimum) {
306fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten        // This can only happen on a 64-bit client
307fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten        if (minimum > UINT32_MAX) {
308fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten            minimum = UINT32_MAX;
309fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten        }
310fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten        mCblk->mMinimum = (uint32_t) minimum;
3119f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
3129f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
3139f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Return the number of frames that would need to be obtained and released
3149f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // in order for the client to be aligned at start of buffer
3159f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual size_t  getMisalignment();
3169f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
31790e8a97dd5c9d391d7a2ea6a2290ed976f928379Andy Hung    Modulo<uint32_t> getEpoch() const {
3189f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return mEpoch;
3199f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
3209f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
321e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk    uint32_t      getBufferSizeInFrames() const { return mBufferSizeInFrames; }
322e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk    // See documentation for AudioTrack::setBufferSizeInFrames()
323e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk    uint32_t      setBufferSizeInFrames(uint32_t requestedSize);
324c0adecb800b197cb8c028513130ebabf2d0f37baPhil Burk
3256ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    status_t    getTimestamp(ExtendedTimestamp *timestamp) {
3266ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung        if (timestamp == nullptr) {
3276ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung            return BAD_VALUE;
3286ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung        }
3296ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung        (void) mTimestampObserver.poll(mTimestamp);
3306ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung        *timestamp = mTimestamp;
3316ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung        return OK;
3326ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    }
3336ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung
3346ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    void        clearTimestamp() {
3356ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung        mTimestamp.clear();
3366ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    }
3376ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung
3389f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprivate:
339e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk    // This is a copy of mCblk->mBufferSizeInFrames
340e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk    uint32_t   mBufferSizeInFrames;  // effective size of the buffer
341e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk
34290e8a97dd5c9d391d7a2ea6a2290ed976f928379Andy Hung    Modulo<uint32_t> mEpoch;
3436ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung
3446ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    // The shared buffer contents referred to by the timestamp observer
3456ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    // is initialized when the server proxy created.  A local zero timestamp
3466ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    // is initialized by the client constructor.
3476ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    ExtendedTimestampQueue::Observer mTimestampObserver;
3486ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    ExtendedTimestamp mTimestamp; // initialized by constructor
349e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
350e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
351e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// ----------------------------------------------------------------------------
352e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
353e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// Proxy used by AudioTrack client, which also includes AudioFlinger::PlaybackThread::OutputTrack
354e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenclass AudioTrackClientProxy : public ClientProxy {
355e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenpublic:
3569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    AudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
3579f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            size_t frameSize, bool clientInServer = false)
3589f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        : ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/,
3598edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung          clientInServer),
3606ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung          mPlaybackRateMutator(&cblk->mPlaybackRateQueue) {
3616ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    }
3626ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung
363e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    virtual ~AudioTrackClientProxy() { }
364e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
365e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // No barriers on the following operations, so the ordering of loads/stores
366e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // with respect to other parameters is UNPREDICTABLE. That's considered safe.
367e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
368e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // caller must limit to 0.0 <= sendLevel <= 1.0
369e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    void        setSendLevel(float sendLevel) {
370e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mCblk->mSendLevel = uint16_t(sendLevel * 0x1000);
371e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    }
372e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
373c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    // set stereo gains
374c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    void        setVolumeLR(gain_minifloat_packed_t volumeLR) {
375e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mCblk->mVolumeLR = volumeLR;
376e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    }
377e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
378e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    void        setSampleRate(uint32_t sampleRate) {
379e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mCblk->mSampleRate = sampleRate;
380e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    }
381e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
3825a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    void        setPlaybackRate(const AudioPlaybackRate& playbackRate) {
3838edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung        mPlaybackRateMutator.push(playbackRate);
3848edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung    }
3858edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung
3869f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual void flush();
3879f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
3889f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual uint32_t    getUnderrunFrames() const {
3899f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return mCblk->u.mStreaming.mUnderrunFrames;
390e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    }
3912812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk    virtual uint32_t    getUnderrunCount() const {
3922812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk        return mCblk->u.mStreaming.mUnderrunCount;
3932812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk    }
394bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
395bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    bool        clearStreamEndDone();   // and return previous value
396bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
397bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    bool        getStreamEndDone() const;
398bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
399b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    status_t    waitStreamEndDone(const struct timespec *requested);
4008edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung
4018edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hungprivate:
4025a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    PlaybackRateQueue::Mutator   mPlaybackRateMutator;
4039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten};
4049f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
4059f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenclass StaticAudioTrackClientProxy : public AudioTrackClientProxy {
4069f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
4079f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    StaticAudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
4089f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            size_t frameSize);
4099f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual ~StaticAudioTrackClientProxy() { }
4109f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
4119f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual void    flush();
4129f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
4139f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define MIN_LOOP    16  // minimum length of each loop iteration in frames
4149b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
4159b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // setLoop(), setBufferPosition(), and setBufferPositionAndLoop() set the
4169b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // static buffer position and looping parameters.  These commands are not
4179b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // synchronous (they do not wait or block); instead they take effect at the
4189b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // next buffer data read from the server side. However, the client side
4199b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // getters will read a cached version of the position and loop variables
4209b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // until the setting takes effect.
4219b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            //
4229b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // setBufferPositionAndLoop() is equivalent to calling, in order, setLoop() and
4239b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // setBufferPosition().
4249b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            //
4259b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // The functions should not be relied upon to do parameter or state checking.
4269b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // That is done at the AudioTrack level.
4279b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
4289f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            void    setLoop(size_t loopStart, size_t loopEnd, int loopCount);
4299b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            void    setBufferPosition(size_t position);
4309b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            void    setBufferPositionAndLoop(size_t position, size_t loopStart, size_t loopEnd,
4319b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung                                             int loopCount);
4329f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            size_t  getBufferPosition();
4334ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung                    // getBufferPositionAndLoopCount() provides the proper snapshot of
4344ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung                    // position and loopCount together.
4354ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung            void    getBufferPositionAndLoopCount(size_t *position, int *loopCount);
436e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
4379f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual size_t  getMisalignment() {
4389f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return 0;
439e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    }
440e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
4419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual uint32_t    getUnderrunFrames() const {
4429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return 0;
443e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    }
444e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
4459f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprivate:
4469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    StaticAudioTrackSingleStateQueue::Mutator   mMutator;
4474ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    StaticAudioTrackPosLoopQueue::Observer      mPosLoopObserver;
4489b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung                        StaticAudioTrackState   mState;   // last communicated state to server
4494ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung                        StaticAudioTrackPosLoop mPosLoop; // snapshot of position and loop.
450e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
451e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
452e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// ----------------------------------------------------------------------------
453e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
454e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// Proxy used by AudioRecord client
455e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenclass AudioRecordClientProxy : public ClientProxy {
456e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenpublic:
4579f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    AudioRecordClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
4589f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            size_t frameSize)
4599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        : ClientProxy(cblk, buffers, frameCount, frameSize,
4606ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung            false /*isOut*/, false /*clientInServer*/) { }
461e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    ~AudioRecordClientProxy() { }
4623f0c902beb53a245c9db35e871607dba05b8d391Andy Hung
4633f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    // Advances the client read pointer to the server write head pointer
4643f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    // effectively flushing the client read buffer. The effect is
4653f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    // instantaneous. Returns the number of frames flushed.
4663f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    uint32_t    flush() {
4673f0c902beb53a245c9db35e871607dba05b8d391Andy Hung        int32_t rear = android_atomic_acquire_load(&mCblk->u.mStreaming.mRear);
4683f0c902beb53a245c9db35e871607dba05b8d391Andy Hung        int32_t front = mCblk->u.mStreaming.mFront;
4693f0c902beb53a245c9db35e871607dba05b8d391Andy Hung        android_atomic_release_store(rear, &mCblk->u.mStreaming.mFront);
4703f0c902beb53a245c9db35e871607dba05b8d391Andy Hung        return (Modulo<int32_t>(rear) - front).unsignedValue();
4713f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    }
472e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
473e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
474e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// ----------------------------------------------------------------------------
475e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
476e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// Proxy used by AudioFlinger server
477e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenclass ServerProxy : public Proxy {
4789f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprotected:
4799f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
4809f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            bool isOut, bool clientInServer);
481e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenpublic:
482e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    virtual ~ServerProxy() { }
483e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
4849f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Obtain a buffer with filled frames (writing) or empty frames (reading).
4859f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
4869f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // calls to releaseBuffer().  In that case, the final obtainBuffer() is the one that effectively
4879f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // sets or extends the unreleased frame count.
4889f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Always non-blocking.
4899f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On entry:
4909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mFrameCount should be initialized to maximum number of desired frames,
4919f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      which must be > 0.
4929f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mNonContig is unused.
4939f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mRaw is unused.
4942e422c472c91aa7912befd0fc038d1e11f354bc1Glenn Kasten    //  ackFlush is true iff being called from Track::start to acknowledge a pending flush.
4959f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On exit:
4969f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mFrameCount has the actual number of contiguous available frames,
4979f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      which is always 0 when the return status != NO_ERROR.
4989f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mNonContig is the number of additional non-contiguous available frames.
4999f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mRaw is a pointer to the first available frame,
5009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      or NULL when buffer->mFrameCount == 0.
5019f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // The return status is one of:
5029f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  NO_ERROR    Success, buffer->mFrameCount > 0.
5039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  WOULD_BLOCK No frames are available.
5049f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  NO_INIT     Shared memory is corrupt.
5052e422c472c91aa7912befd0fc038d1e11f354bc1Glenn Kasten    virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush = false);
5069f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
5079f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Release (some of) the frames last obtained.
5089f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On entry, buffer->mFrameCount should have the number of frames to release,
5099f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // which must (cumulatively) be <= the number of frames last obtained but not yet released.
5109f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
5119f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
5129f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On exit:
5139f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mFrameCount is zero.
5149f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mRaw is NULL.
5159f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual void        releaseBuffer(Buffer* buffer);
516e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
5176ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    // Return the total number of frames that AudioFlinger has obtained and released
5186ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    virtual int64_t     framesReleased() const { return mReleased; }
5196ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung
5206ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    // Expose timestamp to client proxy. Should only be called by a single thread.
5216ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    virtual void        setTimestamp(const ExtendedTimestamp &timestamp) {
5226ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung        mTimestampMutator.push(timestamp);
5236ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    }
5246ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung
525ea2b9c07b34079f0dbd8610a511e006e69a15adcAndy Hung    // Total count of the number of flushed frames since creation (never reset).
526ea2b9c07b34079f0dbd8610a511e006e69a15adcAndy Hung    virtual int64_t     framesFlushed() const { return mFlushed; }
527ea2b9c07b34079f0dbd8610a511e006e69a15adcAndy Hung
528e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk    // Get dynamic buffer size from the shared control block.
529e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk    uint32_t            getBufferSizeInFrames() const {
530e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk        return android_atomic_acquire_load((int32_t *)&mCblk->mBufferSizeInFrames);
531e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk    }
532e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk
5339f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprotected:
5349f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    size_t      mAvailToClient; // estimated frames available to client prior to releaseBuffer()
5359f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    int32_t     mFlush;         // our copy of cblk->u.mStreaming.mFlush, for streaming output only
5363f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    int64_t     mReleased;      // our copy of cblk->mServer, at 64 bit resolution
537ea2b9c07b34079f0dbd8610a511e006e69a15adcAndy Hung    int64_t     mFlushed;       // flushed frames to account for client-server discrepancy
5386ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    ExtendedTimestampQueue::Mutator mTimestampMutator;
5399f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten};
5409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
5419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten// Proxy used by AudioFlinger for servicing AudioTrack
5429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenclass AudioTrackServerProxy : public ServerProxy {
5439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
5449f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
54583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0)
5468edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung        : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer),
5472812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk          mPlaybackRateObserver(&cblk->mPlaybackRateQueue),
548818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung          mUnderrunCount(0), mUnderrunning(false), mDrained(true) {
54983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        mCblk->mSampleRate = sampleRate;
5505a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia        mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
55183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
5529f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprotected:
5539f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual ~AudioTrackServerProxy() { }
5549f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
5559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
556e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // return value of these methods must be validated by the caller
557e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    uint32_t    getSampleRate() const { return mCblk->mSampleRate; }
558e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    uint16_t    getSendLevel_U4_12() const { return mCblk->mSendLevel; }
559c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    gain_minifloat_packed_t getVolumeLR() const { return mCblk->mVolumeLR; }
560e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
5619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // estimated total number of filled frames available to server to read,
5629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // which may include non-contiguous frames
5639f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual size_t      framesReady();
5649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
5659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Currently AudioFlinger will call framesReady() for a fast track from two threads:
5669f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // FastMixer thread, and normal mixer thread.  This is dangerous, as the proxy is intended
5679f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // to be called from at most one thread of server, and one thread of client.
5689f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // As a temporary workaround, this method informs the proxy implementation that it
5699f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // should avoid doing a state queue poll from within framesReady().
5709f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // FIXME Change AudioFlinger to not call framesReady() from normal mixer thread.
5719f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual void        framesReadyIsCalledByMultipleThreads() { }
572bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
573bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    bool     setStreamEndDone();    // and return previous value
57482aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten
57582aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    // Add to the tally of underrun frames, and inform client of underrun
57682aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    virtual void        tallyUnderrunFrames(uint32_t frameCount);
57782aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten
57882aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    // Return the total number of frames which AudioFlinger desired but were unavailable,
57982aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    // and thus which resulted in an underrun.
58082aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    virtual uint32_t    getUnderrunFrames() const { return mCblk->u.mStreaming.mUnderrunFrames; }
581bd096fd9d8e5fc0e62f98807f4818a06f70d0812Glenn Kasten
5828edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung    // Return the playback speed and pitch read atomically. Not multi-thread safe on server side.
5835a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    AudioPlaybackRate getPlaybackRate();
5848edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung
585818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // Set the internal drain state of the track buffer from the timestamp received.
586818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    virtual void        setDrained(bool drained) {
587818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        mDrained.store(drained);
588818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    }
589818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
590818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // Check if the internal drain state of the track buffer.
591818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // This is not a guarantee, but advisory for determining whether the track is
592818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // fully played out.
593818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    virtual bool        isDrained() const {
594818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        return mDrained.load();
595818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    }
596818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
5978edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hungprivate:
5985a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    AudioPlaybackRate             mPlaybackRate;  // last observed playback rate
5995a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    PlaybackRateQueue::Observer   mPlaybackRateObserver;
6002812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk
6012812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk    // The server keeps a copy here where it is safe from the client.
6022812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk    uint32_t                      mUnderrunCount; // echoed to mCblk
6032812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk    bool                          mUnderrunning;  // used to detect edge of underrun
604818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
605818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    std::atomic<bool>             mDrained; // is the track buffer drained
6069f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten};
607e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
6089f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenclass StaticAudioTrackServerProxy : public AudioTrackServerProxy {
6099f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
6109f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    StaticAudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
6119f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            size_t frameSize);
6129f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprotected:
6139f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual ~StaticAudioTrackServerProxy() { }
6149f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
6159f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
6169f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual size_t      framesReady();
6179f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual void        framesReadyIsCalledByMultipleThreads();
6182e422c472c91aa7912befd0fc038d1e11f354bc1Glenn Kasten    virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush);
6199f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual void        releaseBuffer(Buffer* buffer);
62082aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    virtual void        tallyUnderrunFrames(uint32_t frameCount);
62182aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    virtual uint32_t    getUnderrunFrames() const { return 0; }
622e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
623e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenprivate:
6249b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    status_t            updateStateWithLoop(StaticAudioTrackState *localState,
6259b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung                                            const StaticAudioTrackState &update) const;
6269b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    status_t            updateStateWithPosition(StaticAudioTrackState *localState,
6279b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung                                                const StaticAudioTrackState &update) const;
6289f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ssize_t             pollPosition(); // poll for state queue update, and return current position
6299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    StaticAudioTrackSingleStateQueue::Observer  mObserver;
6304ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    StaticAudioTrackPosLoopQueue::Mutator       mPosLoopMutator;
631cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung    size_t              mFramesReadySafe; // Assuming size_t read/writes are atomic on 32 / 64 bit
632cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung                                          // processors, this is a thread-safe version of
633cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung                                          // mFramesReady.
634cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung    int64_t             mFramesReady;     // The number of frames ready in the static buffer
635cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung                                          // including loops.  This is 64 bits since loop mode
636cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung                                          // can cause a track to appear to have a large number
637cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung                                          // of frames. INT64_MAX means an infinite loop.
6389f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    bool                mFramesReadyIsCalledByMultipleThreads;
6399b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    StaticAudioTrackState mState;         // Server side state. Any updates from client must be
6409b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung                                          // passed by the mObserver SingleStateQueue.
6419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten};
642e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
6439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten// Proxy used by AudioFlinger for servicing AudioRecord
6449f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenclass AudioRecordServerProxy : public ServerProxy {
6459f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
6469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    AudioRecordServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
64783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            size_t frameSize, bool clientInServer)
6486ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung        : ServerProxy(cblk, buffers, frameCount, frameSize, false /*isOut*/, clientInServer) { }
6493f0c902beb53a245c9db35e871607dba05b8d391Andy Hung
6509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprotected:
6519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual ~AudioRecordServerProxy() { }
652e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
65389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
65489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ----------------------------------------------------------------------------
65589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
65689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android
65789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
65889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#endif // ANDROID_AUDIO_TRACK_SHARED_H
659