AudioTrackShared.h revision cb2129b3b568a4e31bcbda3545a468024bc972fe
1e5f5895bda30f374b0b51412fd4d837fa59aed66Alexey Samsonov/*
21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany * Copyright (C) 2007 The Android Open Source Project
31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany *
41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany * Licensed under the Apache License, Version 2.0 (the "License");
51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany * you may not use this file except in compliance with the License.
61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany * You may obtain a copy of the License at
71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany *
81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany *      http://www.apache.org/licenses/LICENSE-2.0
91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany *
101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany * Unless required by applicable law or agreed to in writing, software
111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany * distributed under the License is distributed on an "AS IS" BASIS,
121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany * See the License for the specific language governing permissions and
141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany * limitations under the License.
151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany */
167e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov
1755cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov#ifndef ANDROID_AUDIO_TRACK_SHARED_H
181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ANDROID_AUDIO_TRACK_SHARED_H
191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
20e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov#include <stdint.h>
21def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov#include <sys/types.h>
226d95869fa900da9ddd68e15e2aa065854cfa176bKostya Serebryany
232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <audio_utils/minifloat.h>
24f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev#include <utils/threads.h>
251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <utils/Log.h>
261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <utils/RefBase.h>
271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <media/nbaio/roundup.h>
28def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov#include <media/SingleStateQueue.h>
291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <private/media/StaticAudioTrackState.h>
30def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
31def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovnamespace android {
326d95869fa900da9ddd68e15e2aa065854cfa176bKostya Serebryany
336d95869fa900da9ddd68e15e2aa065854cfa176bKostya Serebryany// ----------------------------------------------------------------------------
34def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
35def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov// for audio_track_cblk_t::mFlags
36def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov#define CBLK_UNDERRUN   0x01 // set by server immediately on output underrun, cleared by client
37def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov#define CBLK_FORCEREADY 0x02 // set: track is considered ready immediately by AudioFlinger,
38def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov                             // clear: track is ready when buffer full
39def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov#define CBLK_INVALID    0x04 // track buffer invalidated by AudioFlinger, need to re-create
40def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov#define CBLK_DISABLED   0x08 // output track disabled by AudioFlinger due to underrun,
41def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov                             // need to re-start.  Unlike CBLK_UNDERRUN, this is not set
42def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov                             // immediately, but only after a long string of underruns.
4340527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryany// 0x10 unused
447c9ffde46a475d6dd739e977b547c27ac5968976Timur Iskhodzhanov#define CBLK_LOOP_CYCLE 0x20 // set by server each time a loop cycle other than final one completes
45def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov#define CBLK_LOOP_FINAL 0x40 // set by server when the final loop cycle completes
46def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov#define CBLK_BUFFER_END 0x80 // set by server when the position reaches end of buffer if not looping
471fe68b87dcd9be36b5b4d35e74cc5b0666500ec4Kostya Serebryany#define CBLK_OVERRUN   0x100 // set by server immediately on input overrun, cleared by client
481fe68b87dcd9be36b5b4d35e74cc5b0666500ec4Kostya Serebryany#define CBLK_INTERRUPT 0x200 // set by client on interrupt(), cleared by client in obtainBuffer()
491fe68b87dcd9be36b5b4d35e74cc5b0666500ec4Kostya Serebryany#define CBLK_STREAM_END_DONE 0x400 // set by server on render completion, cleared by client
50def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
511fe68b87dcd9be36b5b4d35e74cc5b0666500ec4Kostya Serebryany//EL_FIXME 20 seconds may not be enough and must be reconciled with new obtainBuffer implementation
5253177247698bfba075f2d5b255a447fc3ced6976Peter Collingbourne#define MAX_RUN_OFFLOADED_TIMEOUT_MS 20000 // assuming up to a maximum of 20 seconds of offloaded
53def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
54def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovstruct AudioTrackSharedStreaming {
55def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    // similar to NBAIO MonoPipe
56def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    // in continuously incrementing frame units, take modulo buffer size, which must be a power of 2
57def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    volatile int32_t mFront;    // read by server
58def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    volatile int32_t mRear;     // write by client
59def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    volatile int32_t mFlush;    // incremented by client to indicate a request to flush;
60def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov                                // server notices and discards all data between mFront and mRear
61def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    volatile uint32_t mUnderrunFrames;  // server increments for each unavailable but desired frame
62def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov};
63def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
64def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovtypedef SingleStateQueue<StaticAudioTrackState> StaticAudioTrackSingleStateQueue;
65def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
66def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovstruct AudioTrackSharedStatic {
67def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    StaticAudioTrackSingleStateQueue::Shared
68def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov                    mSingleStateQueue;
69def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    // This field should be a size_t, but since it is located in shared memory we
70def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    // force to 32-bit.  The client and server may have different typedefs for size_t.
71def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    uint32_t        mBufferPosition;    // updated asynchronously by server,
72def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov                                        // "for entertainment purposes only"
73def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov};
74def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
75def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov// ----------------------------------------------------------------------------
76def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
77def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov// Important: do not add any virtual methods, including ~
78def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovstruct audio_track_cblk_t
79def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov{
80f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany                // Since the control block is always located in shared memory, this constructor
81f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany                // is only used for placement new().  It is never used for regular new() or stack.
822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            audio_track_cblk_t();
8355cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov                /*virtual*/ ~audio_track_cblk_t() { }
8455cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov
8555cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov                friend class Proxy;
8655cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov                friend class ClientProxy;
871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany                friend class AudioTrackClientProxy;
881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany                friend class AudioRecordClientProxy;
89def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov                friend class ServerProxy;
90def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov                friend class AudioTrackServerProxy;
912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                friend class AudioRecordServerProxy;
92def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
93def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    // The data members are grouped so that members accessed frequently and in the same context
94f58f998066db0231e521169d2f50af439ceecb49Kostya Serebryany    // are in the same line of data cache.
95f58f998066db0231e521169d2f50af439ceecb49Kostya Serebryany
96a6b52264e1231bfc4ee9a2d9a4f32678c97295f0Kostya Serebryany                uint32_t    mServer;    // Number of filled frames consumed by server (mIsOut),
972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                        // or filled frames provided by server (!mIsOut).
982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                                        // It is updated asynchronously by server without a barrier.
99f58f998066db0231e521169d2f50af439ceecb49Kostya Serebryany                                        // The value should be used "for entertainment purposes only",
100ae914e2fc00c60d0f8f8b9b06bcc8b0b2d470181Kostya Serebryany                                        // which means don't make important decisions based on it.
1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                uint32_t    mPad1;      // unused
103717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov
1041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    volatile    int32_t     mFutex;     // event flag: down (P) by client,
1051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany                                        // up (V) by server or binderDied() or interrupt()
1061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define CBLK_FUTEX_WAKE 1               // if event flag bit is set, then a deferred wake is pending
10712d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev
1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesprivate:
109f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany
110a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov                // This field should be a size_t, but since it is located in shared memory we
1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                // force to 32-bit.  The client and server may have different typedefs for size_t.
1121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany                uint32_t    mMinimum;       // server wakes up client if available >= mMinimum
1131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
114c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany                // Stereo gains for AudioTrack only, not used by AudioRecord.
115c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany                gain_minifloat_packed_t mVolumeLR;
116c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany
117c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany                uint32_t    mSampleRate;    // AudioTrack only: client's requested sample rate in Hz
118c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany                                            // or 0 == default. Write-only client, read-only server.
119c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany
120c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany                // client write-only, server read-only
121c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany                uint16_t    mSendLevel;      // Fixed point U4.12 so 0x1000 means 1.0
122c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany
123c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany                uint16_t    mPad2;           // unused
124c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany
125c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryanypublic:
1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
127c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany    volatile    int32_t     mFlags;         // combinations of CBLK_*
128c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany
1299433af375c7813486be91d2ac76f5072ee41818dKostya Serebryany                // Cache line boundary (32 bytes)
130230e52f4e91b53f05ce19dbbf11047f4a0113483Kostya Serebryany
1312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinespublic:
1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                union {
1332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                    AudioTrackSharedStreaming   mStreaming;
1342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                    AudioTrackSharedStatic      mStatic;
1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                    int                         mAlign[8];
136230e52f4e91b53f05ce19dbbf11047f4a0113483Kostya Serebryany                } u;
1379433af375c7813486be91d2ac76f5072ee41818dKostya Serebryany
1389433af375c7813486be91d2ac76f5072ee41818dKostya Serebryany                // Cache line boundary (32 bytes)
1399433af375c7813486be91d2ac76f5072ee41818dKostya Serebryany};
140c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany
141c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany// ----------------------------------------------------------------------------
142c98fc1f8e52812cfaf5b19a29db5ed56acb0a682Kostya Serebryany
14369eca73ac96688c8bfe1f23ee006af29c7858c40Kostya Serebryany// Proxy for shared memory control block, to isolate callers from needing to know the details.
1445d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// There is exactly one ClientProxy and one ServerProxy per shared memory control block.
1455d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// The proxies are located in normal memory, and are not multi-thread safe within a given side.
14612d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveevclass Proxy : public RefBase {
1475d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesprotected:
14855cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov    Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut,
149541cfb10f5daa17e48eb42365a74233cd551c545Kostya Serebryany            bool clientInServer);
15012d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev    virtual ~Proxy() { }
1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinespublic:
1532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    struct Buffer {
1542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        size_t  mFrameCount;            // number of frames available in this buffer
15575b19ebf25af204cf209d108997272822241d6daAlexander Potapenko        void*   mRaw;                   // pointer to first frame
15669eca73ac96688c8bfe1f23ee006af29c7858c40Kostya Serebryany        size_t  mNonContig;             // number of additional non-contiguous frames available
15769eca73ac96688c8bfe1f23ee006af29c7858c40Kostya Serebryany    };
158def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
15969eca73ac96688c8bfe1f23ee006af29c7858c40Kostya Serebryanyprotected:
160def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    // These refer to shared memory, and are virtual addresses with respect to the current process.
1612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    // They may have different virtual addresses within the other process.
1621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    audio_track_cblk_t* const   mCblk;  // the control block
1631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    void* const     mBuffers;           // starting address of buffers
1643f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany
1651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    const size_t    mFrameCount;        // not necessarily a power of 2
1661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    const size_t    mFrameSize;         // in bytes
167a27bdf70ca24202dce21cf7c1a387aeaa400d889Kostya Serebryany    const size_t    mFrameCountP2;      // mFrameCount rounded to power of 2, streaming mode
1681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    const bool      mIsOut;             // true for AudioTrack, false for AudioRecord
1691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    const bool      mClientInServer;    // true for OutputTrack, false for AudioTrack & AudioRecord
1701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    bool            mIsShutdown;        // latch set to true when shared memory corruption detected
171600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov    size_t          mUnreleased;        // unreleased frames remaining from most recent obtainBuffer
1721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany};
173e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev
174e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev// ----------------------------------------------------------------------------
175e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev
176e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev// Proxy seen by AudioTrack client and AudioRecord client
177e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveevclass ClientProxy : public Proxy {
178e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveevpublic:
179e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev    ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
180af3441580555ceed092170232cd5f2cc180f19f4Kostya Serebryany            bool isOut, bool clientInServer);
1811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    virtual ~ClientProxy() { }
1821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    static const struct timespec kForever;
18412d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev    static const struct timespec kNonBlocking;
185621770a196153ee61b338d34bafd1170c1899444Kostya Serebryany
186621770a196153ee61b338d34bafd1170c1899444Kostya Serebryany    // Obtain a buffer with filled frames (reading) or empty frames (writing).
18712d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev    // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
188621770a196153ee61b338d34bafd1170c1899444Kostya Serebryany    // calls to releaseBuffer().  In that case, the final obtainBuffer() is the one that effectively
18912d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev    // sets or extends the unreleased frame count.
19012d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev    // On entry:
191e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    //  buffer->mFrameCount should be initialized to maximum number of desired frames,
192e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    //      which must be > 0.
193e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    //  buffer->mNonContig is unused.
194e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    //  buffer->mRaw is unused.
19512d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev    //  requested is the requested timeout in local monotonic delta time units:
19655cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov    //      NULL or &kNonBlocking means non-blocking (zero timeout).
19712d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev    //      &kForever means block forever (infinite timeout).
19812d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev    //      Other values mean a specific timeout in local monotonic delta time units.
19955cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov    //  elapsed is a pointer to a location that will hold the total local monotonic time that
20055cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov    //      elapsed while blocked, or NULL if not needed.
20150f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany    // On exit:
20250f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany    //  buffer->mFrameCount has the actual number of contiguous available frames,
2033f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    //      which is always 0 when the return status != NO_ERROR.
2041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    //  buffer->mNonContig is the number of additional non-contiguous available frames.
2051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    //  buffer->mRaw is a pointer to the first available frame,
206dcf98bf49d68533c7aebadbf6c4467afdd486c99Kostya Serebryany    //      or NULL when buffer->mFrameCount == 0.
2077a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany    // The return status is one of:
2081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    //  NO_ERROR    Success, buffer->mFrameCount > 0.
209e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko    //  WOULD_BLOCK Non-blocking mode and no frames are available.
21050f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany    //  TIMED_OUT   Timeout occurred before any frames became available.
211e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko    //              This can happen even for infinite timeout, due to a spurious wakeup.
2121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    //              In this case, the caller should investigate and then re-try as appropriate.
2135af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany    //  DEAD_OBJECT Server has died or invalidated, caller should destroy this proxy and re-create.
214ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany    //  -EINTR      Call has been interrupted.  Look around to see why, and then perhaps try again.
215ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany    //  NO_INIT     Shared memory is corrupt.
2163972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov    // Assertion failure on entry, if buffer == NULL or buffer->mFrameCount == 0.
2173972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov    status_t    obtainBuffer(Buffer* buffer, const struct timespec *requested = NULL,
218e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko            struct timespec *elapsed = NULL);
2193972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov
2203972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov    // Release (some of) the frames last obtained.
2213972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov    // On entry, buffer->mFrameCount should have the number of frames to release,
2223972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov    // which must (cumulatively) be <= the number of frames last obtained but not yet released.
223e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko    // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
2243972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov    // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
2251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    // On exit:
2263972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov    //  buffer->mFrameCount is zero.
2273972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov    //  buffer->mRaw is NULL.
228e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko    void        releaseBuffer(Buffer* buffer);
229e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko
2303972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov    // Call after detecting server's death
2313972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov    void        binderDied();
2323f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany
233e406c8c47570659287e619e23479f9fb6640299eAlexander Potapenko    // Call to force an obtainBuffer() to return quickly with -EINTR
2343f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    void        interrupt();
23550f3daa00d3da0a80c8798a3e977705e96ec106fKostya Serebryany
2363972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov    size_t      getPosition() {
2371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany        return mEpoch + mCblk->mServer;
2381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    }
239def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
240def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    void        setEpoch(size_t epoch) {
241def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov        mEpoch = epoch;
242def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    }
2437a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany
2447a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany    void        setMinimum(size_t minimum) {
245b39a604ff9d68ba7400197fca341771878443a69Kostya Serebryany        // This can only happen on a 64-bit client
2467a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany        if (minimum > UINT32_MAX) {
2477a0bba457ee05ced3adf37a0c0790d0ed23a5446Kostya Serebryany            minimum = UINT32_MAX;
248def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov        }
249def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov        mCblk->mMinimum = (uint32_t) minimum;
25089c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov    }
251c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev
252c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev    // Return the number of frames that would need to be obtained and released
253def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    // in order for the client to be aligned at start of buffer
254def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    virtual size_t  getMisalignment();
255def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
256def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    size_t      getEpoch() const {
257def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov        return mEpoch;
258195369bb7f59896487c4542716ca9c5d53975e78Dmitry Vyukov    }
259195369bb7f59896487c4542716ca9c5d53975e78Dmitry Vyukov
260def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    size_t      getFramesFilled();
261def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
262def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonovprivate:
263def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    size_t      mEpoch;
264def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov};
26589c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov
26689c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov// ----------------------------------------------------------------------------
26789c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov
268def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov// Proxy used by AudioTrack client, which also includes AudioFlinger::PlaybackThread::OutputTrack
26989c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonovclass AudioTrackClientProxy : public ClientProxy {
27089c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonovpublic:
27189c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov    AudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
272def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov            size_t frameSize, bool clientInServer = false)
2732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        : ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/,
2742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines          clientInServer) { }
27589c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov    virtual ~AudioTrackClientProxy() { }
276def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
277def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    // No barriers on the following operations, so the ordering of loads/stores
278def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    // with respect to other parameters is UNPREDICTABLE. That's considered safe.
27989c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov
28089c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov    // caller must limit to 0.0 <= sendLevel <= 1.0
28189c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov    void        setSendLevel(float sendLevel) {
28289c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov        mCblk->mSendLevel = uint16_t(sendLevel * 0x1000);
28389c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov    }
28489c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov
28589c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov    // set stereo gains
286def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    void        setVolumeLR(gain_minifloat_packed_t volumeLR) {
287def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov        mCblk->mVolumeLR = volumeLR;
288def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    }
289def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov
290def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    void        setSampleRate(uint32_t sampleRate) {
291def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov        mCblk->mSampleRate = sampleRate;
292def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov    }
293c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev
294c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev    virtual void flush();
295c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev
296c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev    virtual uint32_t    getUnderrunFrames() const {
297c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev        return mCblk->u.mStreaming.mUnderrunFrames;
298c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev    }
299c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev
300c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev    bool        clearStreamEndDone();   // and return previous value
301c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev
302c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev    bool        getStreamEndDone() const;
303c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev
304c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev    status_t    waitStreamEndDone(const struct timespec *requested);
305c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev};
306c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev
3071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyclass StaticAudioTrackClientProxy : public AudioTrackClientProxy {
308f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveevpublic:
309f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev    StaticAudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
310f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev            size_t frameSize);
311f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev    virtual ~StaticAudioTrackClientProxy() { }
312f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev
313f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev    virtual void    flush();
314c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev
31512d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev#define MIN_LOOP    16  // minimum length of each loop iteration in frames
31612d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev            void    setLoop(size_t loopStart, size_t loopEnd, int loopCount);
31712d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev            size_t  getBufferPosition();
31812d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev
31912d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev    virtual size_t  getMisalignment() {
32012d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev        return 0;
32112d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev    }
32212d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev
32312d01bac1c09a8412546e71485a3cba2d416c0fcSergey Matveev    virtual uint32_t    getUnderrunFrames() const {
324f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev        return 0;
325f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev    }
326c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev
327c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveevprivate:
328c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev    StaticAudioTrackSingleStateQueue::Mutator   mMutator;
329c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev    size_t          mBufferPosition;    // so that getBufferPosition() appears to be synchronous
330c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev};
331c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev
332c519335c2d6d32acaac32c0595f08a05081567e7Sergey Matveev// ----------------------------------------------------------------------------
333f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev
334f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev// Proxy used by AudioRecord client
335f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveevclass AudioRecordClientProxy : public ClientProxy {
336f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveevpublic:
337f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev    AudioRecordClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
338f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev            size_t frameSize)
339f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev        : ClientProxy(cblk, buffers, frameCount, frameSize,
340c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev            false /*isOut*/, false /*clientInServer*/) { }
341c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev    ~AudioRecordClientProxy() { }
342c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev};
343c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev
344f1ac1a44b4ed022f0a587a6bd711b1afbd3f8f62Sergey Matveev// ----------------------------------------------------------------------------
345
346// Proxy used by AudioFlinger server
347class ServerProxy : public Proxy {
348protected:
349    ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
350            bool isOut, bool clientInServer);
351public:
352    virtual ~ServerProxy() { }
353
354    // Obtain a buffer with filled frames (writing) or empty frames (reading).
355    // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
356    // calls to releaseBuffer().  In that case, the final obtainBuffer() is the one that effectively
357    // sets or extends the unreleased frame count.
358    // Always non-blocking.
359    // On entry:
360    //  buffer->mFrameCount should be initialized to maximum number of desired frames,
361    //      which must be > 0.
362    //  buffer->mNonContig is unused.
363    //  buffer->mRaw is unused.
364    //  ackFlush is true iff being called from Track::start to acknowledge a pending flush.
365    // On exit:
366    //  buffer->mFrameCount has the actual number of contiguous available frames,
367    //      which is always 0 when the return status != NO_ERROR.
368    //  buffer->mNonContig is the number of additional non-contiguous available frames.
369    //  buffer->mRaw is a pointer to the first available frame,
370    //      or NULL when buffer->mFrameCount == 0.
371    // The return status is one of:
372    //  NO_ERROR    Success, buffer->mFrameCount > 0.
373    //  WOULD_BLOCK No frames are available.
374    //  NO_INIT     Shared memory is corrupt.
375    virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush = false);
376
377    // Release (some of) the frames last obtained.
378    // On entry, buffer->mFrameCount should have the number of frames to release,
379    // which must (cumulatively) be <= the number of frames last obtained but not yet released.
380    // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
381    // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
382    // On exit:
383    //  buffer->mFrameCount is zero.
384    //  buffer->mRaw is NULL.
385    virtual void        releaseBuffer(Buffer* buffer);
386
387protected:
388    size_t      mAvailToClient; // estimated frames available to client prior to releaseBuffer()
389    int32_t     mFlush;         // our copy of cblk->u.mStreaming.mFlush, for streaming output only
390};
391
392// Proxy used by AudioFlinger for servicing AudioTrack
393class AudioTrackServerProxy : public ServerProxy {
394public:
395    AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
396            size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0)
397        : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer) {
398        mCblk->mSampleRate = sampleRate;
399    }
400protected:
401    virtual ~AudioTrackServerProxy() { }
402
403public:
404    // return value of these methods must be validated by the caller
405    uint32_t    getSampleRate() const { return mCblk->mSampleRate; }
406    uint16_t    getSendLevel_U4_12() const { return mCblk->mSendLevel; }
407    gain_minifloat_packed_t getVolumeLR() const { return mCblk->mVolumeLR; }
408
409    // estimated total number of filled frames available to server to read,
410    // which may include non-contiguous frames
411    virtual size_t      framesReady();
412
413    // Currently AudioFlinger will call framesReady() for a fast track from two threads:
414    // FastMixer thread, and normal mixer thread.  This is dangerous, as the proxy is intended
415    // to be called from at most one thread of server, and one thread of client.
416    // As a temporary workaround, this method informs the proxy implementation that it
417    // should avoid doing a state queue poll from within framesReady().
418    // FIXME Change AudioFlinger to not call framesReady() from normal mixer thread.
419    virtual void        framesReadyIsCalledByMultipleThreads() { }
420
421    bool     setStreamEndDone();    // and return previous value
422
423    // Add to the tally of underrun frames, and inform client of underrun
424    virtual void        tallyUnderrunFrames(uint32_t frameCount);
425
426    // Return the total number of frames which AudioFlinger desired but were unavailable,
427    // and thus which resulted in an underrun.
428    virtual uint32_t    getUnderrunFrames() const { return mCblk->u.mStreaming.mUnderrunFrames; }
429
430    // Return the total number of frames that AudioFlinger has obtained and released
431    virtual size_t      framesReleased() const { return mCblk->mServer; }
432};
433
434class StaticAudioTrackServerProxy : public AudioTrackServerProxy {
435public:
436    StaticAudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
437            size_t frameSize);
438protected:
439    virtual ~StaticAudioTrackServerProxy() { }
440
441public:
442    virtual size_t      framesReady();
443    virtual void        framesReadyIsCalledByMultipleThreads();
444    virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush);
445    virtual void        releaseBuffer(Buffer* buffer);
446    virtual void        tallyUnderrunFrames(uint32_t frameCount);
447    virtual uint32_t    getUnderrunFrames() const { return 0; }
448
449private:
450    ssize_t             pollPosition(); // poll for state queue update, and return current position
451    StaticAudioTrackSingleStateQueue::Observer  mObserver;
452    size_t              mPosition;  // server's current play position in frames, relative to 0
453
454    size_t              mFramesReadySafe; // Assuming size_t read/writes are atomic on 32 / 64 bit
455                                          // processors, this is a thread-safe version of
456                                          // mFramesReady.
457    int64_t             mFramesReady;     // The number of frames ready in the static buffer
458                                          // including loops.  This is 64 bits since loop mode
459                                          // can cause a track to appear to have a large number
460                                          // of frames. INT64_MAX means an infinite loop.
461    bool                mFramesReadyIsCalledByMultipleThreads;
462    StaticAudioTrackState   mState;
463};
464
465// Proxy used by AudioFlinger for servicing AudioRecord
466class AudioRecordServerProxy : public ServerProxy {
467public:
468    AudioRecordServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
469            size_t frameSize, bool clientInServer)
470        : ServerProxy(cblk, buffers, frameCount, frameSize, false /*isOut*/, clientInServer) { }
471protected:
472    virtual ~AudioRecordServerProxy() { }
473};
474
475// ----------------------------------------------------------------------------
476
477}; // namespace android
478
479#endif // ANDROID_AUDIO_TRACK_SHARED_H
480