AudioTrackShared.h revision f59497bd3c190e087202043de5450ef06e92b27d
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>
289f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#include <media/SingleStateQueue.h>
2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android {
3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ----------------------------------------------------------------------------
3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3496f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten// for audio_track_cblk_t::mFlags
359f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_UNDERRUN   0x01 // set by server immediately on output underrun, cleared by client
36864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten#define CBLK_FORCEREADY 0x02 // set: track is considered ready immediately by AudioFlinger,
379c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten                             // clear: track is ready when buffer full
38864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten#define CBLK_INVALID    0x04 // track buffer invalidated by AudioFlinger, need to re-create
399f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_DISABLED   0x08 // output track disabled by AudioFlinger due to underrun,
409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                             // need to re-start.  Unlike CBLK_UNDERRUN, this is not set
419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                             // immediately, but only after a long string of underruns.
429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten// 0x10 unused
439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_LOOP_CYCLE 0x20 // set by server each time a loop cycle other than final one completes
449f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_LOOP_FINAL 0x40 // set by server when the final loop cycle completes
459f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_BUFFER_END 0x80 // set by server when the position reaches end of buffer if not looping
469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_OVERRUN   0x100 // set by server immediately on input overrun, cleared by client
479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define CBLK_INTERRUPT 0x200 // set by client on interrupt(), cleared by client in obtainBuffer()
48ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald#define CBLK_STREAM_END_DONE 0x400 // set by server on render completion, cleared by client
49ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
50ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald//EL_FIXME 20 seconds may not be enough and must be reconciled with new obtainBuffer implementation
51e198c360d5e75a9b2097844c495c10902e7e8500Glenn Kasten#define MAX_RUN_OFFLOADED_TIMEOUT_MS 20000 // assuming up to a maximum of 20 seconds of offloaded
5289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
53e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenstruct AudioTrackSharedStreaming {
54e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // similar to NBAIO MonoPipe
559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // in continuously incrementing frame units, take modulo buffer size, which must be a power of 2
56f59497bd3c190e087202043de5450ef06e92b27dGlenn Kasten    volatile int32_t mFront;    // read by consumer (output: server, input: client)
57f59497bd3c190e087202043de5450ef06e92b27dGlenn Kasten    volatile int32_t mRear;     // written by producer (output: client, input: server)
589f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    volatile int32_t mFlush;    // incremented by client to indicate a request to flush;
599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                                // server notices and discards all data between mFront and mRear
609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    volatile uint32_t mUnderrunFrames;  // server increments for each unavailable but desired frame
61e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
62e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
639b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung// Represents a single state of an AudioTrack that was created in static mode (shared memory buffer
649b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung// supplied by the client).  This state needs to be communicated from the client to server.  As this
659b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung// state is too large to be updated atomically without a mutex, and mutexes aren't allowed here, the
669b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung// state is wrapped by a SingleStateQueue.
679b4615887c23548438fd0d8e3d8f04ac21912850Andy Hungstruct StaticAudioTrackState {
689b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // Do not define constructors, destructors, or virtual methods as this is part of a
699b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // union in shared memory and they will not get called properly.
709b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
719b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // These fields should both be size_t, but since they are located in shared memory we
729b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // force to 32-bit.  The client and server may have different typedefs for size_t.
739b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
749b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // The state has a sequence counter to indicate whether changes are made to loop or position.
759b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // The sequence counter also currently indicates whether loop or position is first depending
769b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    // on which is greater; it jumps by max(mLoopSequence, mPositionSequence) + 1.
779b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
789b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    uint32_t    mLoopStart;
799b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    uint32_t    mLoopEnd;
809b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    int32_t     mLoopCount;
819b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    uint32_t    mLoopSequence; // a sequence counter to indicate changes to loop
829b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    uint32_t    mPosition;
839b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    uint32_t    mPositionSequence; // a sequence counter to indicate changes to position
849b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung};
859b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
869f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastentypedef SingleStateQueue<StaticAudioTrackState> StaticAudioTrackSingleStateQueue;
879f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
884ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hungstruct StaticAudioTrackPosLoop {
894ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // Do not define constructors, destructors, or virtual methods as this is part of a
904ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // union in shared memory and will not get called properly.
914ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
924ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // These fields should both be size_t, but since they are located in shared memory we
934ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // force to 32-bit.  The client and server may have different typedefs for size_t.
944ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
954ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // This struct information is stored in a single state queue to communicate the
964ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // static AudioTrack server state to the client while data is consumed.
974ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // It is smaller than StaticAudioTrackState to prevent unnecessary information from
984ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // being sent.
994ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
1004ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    uint32_t mBufferPosition;
1014ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    int32_t  mLoopCount;
1024ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung};
1034ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
1044ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hungtypedef SingleStateQueue<StaticAudioTrackPosLoop> StaticAudioTrackPosLoopQueue;
1054ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung
106e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenstruct AudioTrackSharedStatic {
1074ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // client requests to the server for loop or position changes.
1089f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    StaticAudioTrackSingleStateQueue::Shared
1099f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                    mSingleStateQueue;
1104ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // position info updated asynchronously by server and read by client,
1114ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    // "for entertainment purposes only"
1124ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    StaticAudioTrackPosLoopQueue::Shared
1134ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung                    mPosLoopQueue;
114e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
115e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
116e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// ----------------------------------------------------------------------------
117e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
1181a0ae5be3d1273cba12584b33830d859510fbf82Glenn Kasten// Important: do not add any virtual methods, including ~
11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstruct audio_track_cblk_t
12089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
1219f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                // Since the control block is always located in shared memory, this constructor
1229f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                // is only used for placement new().  It is never used for regular new() or stack.
1239f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                            audio_track_cblk_t();
1249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                /*virtual*/ ~audio_track_cblk_t() { }
1259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
126e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                friend class Proxy;
1279f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                friend class ClientProxy;
128e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                friend class AudioTrackClientProxy;
129e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                friend class AudioRecordClientProxy;
130e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                friend class ServerProxy;
1319f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                friend class AudioTrackServerProxy;
1329f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                friend class AudioRecordServerProxy;
13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // The data members are grouped so that members accessed frequently and in the same context
13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // are in the same line of data cache.
13699e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten
137f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten                uint32_t    mServer;    // Number of filled frames consumed by server (mIsOut),
138f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten                                        // or filled frames provided by server (!mIsOut).
139f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten                                        // It is updated asynchronously by server without a barrier.
140b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten                                        // The value should be used
141b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten                                        // "for entertainment purposes only",
142f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten                                        // which means don't make important decisions based on it.
14322eb4e239fbe9103568147d566d7482e480350b8Glenn Kasten
14474935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten                uint32_t    mPad1;      // unused
14599e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten
1460d09a9bec07b3bec78bd473ff0bfcf0a261f3f25Glenn Kasten    volatile    int32_t     mFutex;     // event flag: down (P) by client,
1479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                                        // up (V) by server or binderDied() or interrupt()
1480d09a9bec07b3bec78bd473ff0bfcf0a261f3f25Glenn Kasten#define CBLK_FUTEX_WAKE 1               // if event flag bit is set, then a deferred wake is pending
1499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
1509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprivate:
15199e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten
152fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten                // This field should be a size_t, but since it is located in shared memory we
153fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten                // force to 32-bit.  The client and server may have different typedefs for size_t.
154fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten                uint32_t    mMinimum;       // server wakes up client if available >= mMinimum
155b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten
156c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten                // Stereo gains for AudioTrack only, not used by AudioRecord.
157c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten                gain_minifloat_packed_t mVolumeLR;
158b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten
159e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                uint32_t    mSampleRate;    // AudioTrack only: client's requested sample rate in Hz
160e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                                            // or 0 == default. Write-only client, read-only server.
16199e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten
1629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                // client write-only, server read-only
1639f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                uint16_t    mSendLevel;      // Fixed point U4.12 so 0x1000 means 1.0
1649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
165d054c32443a493513ab63529b0c8b1aca290278cGlenn Kasten                uint16_t    mPad2;           // unused
166d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent
167e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenpublic:
16899e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten
16996f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten    volatile    int32_t     mFlags;         // combinations of CBLK_*
17038ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent
171d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent                // Cache line boundary (32 bytes)
1720d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi
1739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
174e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                union {
175e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                    AudioTrackSharedStreaming   mStreaming;
176e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                    AudioTrackSharedStatic      mStatic;
177e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                    int                         mAlign[8];
178e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                } u;
179e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
180e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                // Cache line boundary (32 bytes)
18189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project};
18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
183e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// ----------------------------------------------------------------------------
184e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
185e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// Proxy for shared memory control block, to isolate callers from needing to know the details.
186e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// There is exactly one ClientProxy and one ServerProxy per shared memory control block.
187e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// The proxies are located in normal memory, and are not multi-thread safe within a given side.
1889f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenclass Proxy : public RefBase {
189e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenprotected:
1909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut,
1919f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            bool clientInServer);
192e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    virtual ~Proxy() { }
193e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
194e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenpublic:
1959f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    struct Buffer {
1969f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        size_t  mFrameCount;            // number of frames available in this buffer
1979f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        void*   mRaw;                   // pointer to first frame
1989f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        size_t  mNonContig;             // number of additional non-contiguous frames available
1999f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    };
200e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
201e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenprotected:
202e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // These refer to shared memory, and are virtual addresses with respect to the current process.
203e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // They may have different virtual addresses within the other process.
2049f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    audio_track_cblk_t* const   mCblk;  // the control block
2059f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void* const     mBuffers;           // starting address of buffers
2069f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2079f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const size_t    mFrameCount;        // not necessarily a power of 2
2089f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const size_t    mFrameSize;         // in bytes
2099f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const size_t    mFrameCountP2;      // mFrameCount rounded to power of 2, streaming mode
2109f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const bool      mIsOut;             // true for AudioTrack, false for AudioRecord
2119f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    const bool      mClientInServer;    // true for OutputTrack, false for AudioTrack & AudioRecord
2129f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    bool            mIsShutdown;        // latch set to true when shared memory corruption detected
2137db7df0e8d9d7cee8ba374468cdbfa0108e3337cGlenn Kasten    size_t          mUnreleased;        // unreleased frames remaining from most recent obtainBuffer
214e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
215e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
216e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// ----------------------------------------------------------------------------
217e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
218e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// Proxy seen by AudioTrack client and AudioRecord client
219e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenclass ClientProxy : public Proxy {
22083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentpublic:
2219f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
2229f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            bool isOut, bool clientInServer);
223e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    virtual ~ClientProxy() { }
2249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    static const struct timespec kForever;
2269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    static const struct timespec kNonBlocking;
2279f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2289f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Obtain a buffer with filled frames (reading) or empty frames (writing).
2299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
2309f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // calls to releaseBuffer().  In that case, the final obtainBuffer() is the one that effectively
2319f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // sets or extends the unreleased frame count.
2329f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On entry:
2339f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mFrameCount should be initialized to maximum number of desired frames,
2349f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      which must be > 0.
2359f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mNonContig is unused.
2369f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mRaw is unused.
2379f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  requested is the requested timeout in local monotonic delta time units:
2389f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      NULL or &kNonBlocking means non-blocking (zero timeout).
2399f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      &kForever means block forever (infinite timeout).
2409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      Other values mean a specific timeout in local monotonic delta time units.
2419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  elapsed is a pointer to a location that will hold the total local monotonic time that
2429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      elapsed while blocked, or NULL if not needed.
2439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On exit:
2449f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mFrameCount has the actual number of contiguous available frames,
2459f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      which is always 0 when the return status != NO_ERROR.
2469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mNonContig is the number of additional non-contiguous available frames.
2479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mRaw is a pointer to the first available frame,
2489f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      or NULL when buffer->mFrameCount == 0.
2499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // The return status is one of:
2509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  NO_ERROR    Success, buffer->mFrameCount > 0.
2519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  WOULD_BLOCK Non-blocking mode and no frames are available.
2529f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  TIMED_OUT   Timeout occurred before any frames became available.
2539f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //              This can happen even for infinite timeout, due to a spurious wakeup.
2549f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //              In this case, the caller should investigate and then re-try as appropriate.
2559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  DEAD_OBJECT Server has died or invalidated, caller should destroy this proxy and re-create.
2569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  -EINTR      Call has been interrupted.  Look around to see why, and then perhaps try again.
2579f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  NO_INIT     Shared memory is corrupt.
2587db7df0e8d9d7cee8ba374468cdbfa0108e3337cGlenn Kasten    // Assertion failure on entry, if buffer == NULL or buffer->mFrameCount == 0.
2599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t    obtainBuffer(Buffer* buffer, const struct timespec *requested = NULL,
2609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            struct timespec *elapsed = NULL);
2619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Release (some of) the frames last obtained.
2639f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On entry, buffer->mFrameCount should have the number of frames to release,
2649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // which must (cumulatively) be <= the number of frames last obtained but not yet released.
2659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
2669f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
2679f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On exit:
2689f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mFrameCount is zero.
2699f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mRaw is NULL.
2709f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void        releaseBuffer(Buffer* buffer);
2719f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2729f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Call after detecting server's death
2739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void        binderDied();
2749f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2759f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Call to force an obtainBuffer() to return quickly with -EINTR
2769f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void        interrupt();
2779f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2789f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    size_t      getPosition() {
279f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten        return mEpoch + mCblk->mServer;
2809f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
2819f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2829f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void        setEpoch(size_t epoch) {
2839f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mEpoch = epoch;
2849f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
2859f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2869f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    void        setMinimum(size_t minimum) {
287fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten        // This can only happen on a 64-bit client
288fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten        if (minimum > UINT32_MAX) {
289fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten            minimum = UINT32_MAX;
290fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten        }
291fdac7c00f9201bb3a9862069145f01d37e39755bGlenn Kasten        mCblk->mMinimum = (uint32_t) minimum;
2929f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
2939f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2949f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Return the number of frames that would need to be obtained and released
2959f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // in order for the client to be aligned at start of buffer
2969f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual size_t  getMisalignment();
2979f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2989f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    size_t      getEpoch() const {
2999f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return mEpoch;
3009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
3019f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
302cc21e4f1e41dfa17e7e2bef995fcd22c45f6bcd0Eric Laurent    size_t      getFramesFilled();
303cc21e4f1e41dfa17e7e2bef995fcd22c45f6bcd0Eric Laurent
3049f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprivate:
3059f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    size_t      mEpoch;
306e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
307e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
308e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// ----------------------------------------------------------------------------
309e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
310e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// Proxy used by AudioTrack client, which also includes AudioFlinger::PlaybackThread::OutputTrack
311e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenclass AudioTrackClientProxy : public ClientProxy {
312e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenpublic:
3139f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    AudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
3149f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            size_t frameSize, bool clientInServer = false)
3159f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        : ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/,
3169f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten          clientInServer) { }
317e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    virtual ~AudioTrackClientProxy() { }
318e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
319e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // No barriers on the following operations, so the ordering of loads/stores
320e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // with respect to other parameters is UNPREDICTABLE. That's considered safe.
321e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
322e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // caller must limit to 0.0 <= sendLevel <= 1.0
323e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    void        setSendLevel(float sendLevel) {
324e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mCblk->mSendLevel = uint16_t(sendLevel * 0x1000);
325e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    }
326e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
327c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    // set stereo gains
328c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    void        setVolumeLR(gain_minifloat_packed_t volumeLR) {
329e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mCblk->mVolumeLR = volumeLR;
330e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    }
331e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
332e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    void        setSampleRate(uint32_t sampleRate) {
333e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mCblk->mSampleRate = sampleRate;
334e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    }
335e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
3369f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual void flush();
3379f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
3389f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual uint32_t    getUnderrunFrames() const {
3399f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return mCblk->u.mStreaming.mUnderrunFrames;
340e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    }
341bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
342bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    bool        clearStreamEndDone();   // and return previous value
343bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
344bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    bool        getStreamEndDone() const;
345bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
346b1a270d1e926fb9a01b4265a7675ed0c2c8f4868Richard Fitzgerald    status_t    waitStreamEndDone(const struct timespec *requested);
3479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten};
3489f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
3499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenclass StaticAudioTrackClientProxy : public AudioTrackClientProxy {
3509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
3519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    StaticAudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
3529f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            size_t frameSize);
3539f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual ~StaticAudioTrackClientProxy() { }
3549f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
3559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual void    flush();
3569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
3579f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#define MIN_LOOP    16  // minimum length of each loop iteration in frames
3589b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
3599b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // setLoop(), setBufferPosition(), and setBufferPositionAndLoop() set the
3609b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // static buffer position and looping parameters.  These commands are not
3619b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // synchronous (they do not wait or block); instead they take effect at the
3629b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // next buffer data read from the server side. However, the client side
3639b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // getters will read a cached version of the position and loop variables
3649b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // until the setting takes effect.
3659b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            //
3669b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // setBufferPositionAndLoop() is equivalent to calling, in order, setLoop() and
3679b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // setBufferPosition().
3689b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            //
3699b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // The functions should not be relied upon to do parameter or state checking.
3709b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            // That is done at the AudioTrack level.
3719b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung
3729f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            void    setLoop(size_t loopStart, size_t loopEnd, int loopCount);
3739b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            void    setBufferPosition(size_t position);
3749b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung            void    setBufferPositionAndLoop(size_t position, size_t loopStart, size_t loopEnd,
3759b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung                                             int loopCount);
3769f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            size_t  getBufferPosition();
3774ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung                    // getBufferPositionAndLoopCount() provides the proper snapshot of
3784ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung                    // position and loopCount together.
3794ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung            void    getBufferPositionAndLoopCount(size_t *position, int *loopCount);
380e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
3819f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual size_t  getMisalignment() {
3829f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return 0;
383e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    }
384e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
3859f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual uint32_t    getUnderrunFrames() const {
3869f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        return 0;
387e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    }
388e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
3899f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprivate:
3909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    StaticAudioTrackSingleStateQueue::Mutator   mMutator;
3914ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    StaticAudioTrackPosLoopQueue::Observer      mPosLoopObserver;
3929b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung                        StaticAudioTrackState   mState;   // last communicated state to server
3934ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung                        StaticAudioTrackPosLoop mPosLoop; // snapshot of position and loop.
394e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
395e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
396e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// ----------------------------------------------------------------------------
397e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
398e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// Proxy used by AudioRecord client
399e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenclass AudioRecordClientProxy : public ClientProxy {
400e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenpublic:
4019f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    AudioRecordClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
4029f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            size_t frameSize)
4039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        : ClientProxy(cblk, buffers, frameCount, frameSize,
4049f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            false /*isOut*/, false /*clientInServer*/) { }
405e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    ~AudioRecordClientProxy() { }
406e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
407e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
408e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// ----------------------------------------------------------------------------
409e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
410e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten// Proxy used by AudioFlinger server
411e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenclass ServerProxy : public Proxy {
4129f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprotected:
4139f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
4149f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            bool isOut, bool clientInServer);
415e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenpublic:
416e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    virtual ~ServerProxy() { }
417e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
4189f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Obtain a buffer with filled frames (writing) or empty frames (reading).
4199f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
4209f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // calls to releaseBuffer().  In that case, the final obtainBuffer() is the one that effectively
4219f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // sets or extends the unreleased frame count.
4229f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Always non-blocking.
4239f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On entry:
4249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mFrameCount should be initialized to maximum number of desired frames,
4259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      which must be > 0.
4269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mNonContig is unused.
4279f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mRaw is unused.
4282e422c472c91aa7912befd0fc038d1e11f354bc1Glenn Kasten    //  ackFlush is true iff being called from Track::start to acknowledge a pending flush.
4299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On exit:
4309f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mFrameCount has the actual number of contiguous available frames,
4319f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      which is always 0 when the return status != NO_ERROR.
4329f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mNonContig is the number of additional non-contiguous available frames.
4339f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mRaw is a pointer to the first available frame,
4349f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //      or NULL when buffer->mFrameCount == 0.
4359f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // The return status is one of:
4369f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  NO_ERROR    Success, buffer->mFrameCount > 0.
4379f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  WOULD_BLOCK No frames are available.
4389f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  NO_INIT     Shared memory is corrupt.
4392e422c472c91aa7912befd0fc038d1e11f354bc1Glenn Kasten    virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush = false);
4409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
4419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Release (some of) the frames last obtained.
4429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On entry, buffer->mFrameCount should have the number of frames to release,
4439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // which must (cumulatively) be <= the number of frames last obtained but not yet released.
4449f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
4459f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
4469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // On exit:
4479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mFrameCount is zero.
4489f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    //  buffer->mRaw is NULL.
4499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual void        releaseBuffer(Buffer* buffer);
450e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
4519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprotected:
4529f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    size_t      mAvailToClient; // estimated frames available to client prior to releaseBuffer()
4539f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    int32_t     mFlush;         // our copy of cblk->u.mStreaming.mFlush, for streaming output only
4549f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten};
4559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
4569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten// Proxy used by AudioFlinger for servicing AudioTrack
4579f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenclass AudioTrackServerProxy : public ServerProxy {
4589f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
4599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
46083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0)
46183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer) {
46283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        mCblk->mSampleRate = sampleRate;
46383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
4649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprotected:
4659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual ~AudioTrackServerProxy() { }
4669f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
4679f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
468e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // return value of these methods must be validated by the caller
469e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    uint32_t    getSampleRate() const { return mCblk->mSampleRate; }
470e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    uint16_t    getSendLevel_U4_12() const { return mCblk->mSendLevel; }
471c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    gain_minifloat_packed_t getVolumeLR() const { return mCblk->mVolumeLR; }
472e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
4739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // estimated total number of filled frames available to server to read,
4749f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // which may include non-contiguous frames
4759f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual size_t      framesReady();
4769f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
4779f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // Currently AudioFlinger will call framesReady() for a fast track from two threads:
4789f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // FastMixer thread, and normal mixer thread.  This is dangerous, as the proxy is intended
4799f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // to be called from at most one thread of server, and one thread of client.
4809f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // As a temporary workaround, this method informs the proxy implementation that it
4819f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // should avoid doing a state queue poll from within framesReady().
4829f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // FIXME Change AudioFlinger to not call framesReady() from normal mixer thread.
4839f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual void        framesReadyIsCalledByMultipleThreads() { }
484bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
485bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    bool     setStreamEndDone();    // and return previous value
48682aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten
48782aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    // Add to the tally of underrun frames, and inform client of underrun
48882aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    virtual void        tallyUnderrunFrames(uint32_t frameCount);
48982aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten
49082aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    // Return the total number of frames which AudioFlinger desired but were unavailable,
49182aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    // and thus which resulted in an underrun.
49282aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    virtual uint32_t    getUnderrunFrames() const { return mCblk->u.mStreaming.mUnderrunFrames; }
493bd096fd9d8e5fc0e62f98807f4818a06f70d0812Glenn Kasten
494bd096fd9d8e5fc0e62f98807f4818a06f70d0812Glenn Kasten    // Return the total number of frames that AudioFlinger has obtained and released
495bd096fd9d8e5fc0e62f98807f4818a06f70d0812Glenn Kasten    virtual size_t      framesReleased() const { return mCblk->mServer; }
4969f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten};
497e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
4989f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenclass StaticAudioTrackServerProxy : public AudioTrackServerProxy {
4999f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
5009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    StaticAudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
5019f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            size_t frameSize);
5029f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprotected:
5039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual ~StaticAudioTrackServerProxy() { }
5049f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
5059f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
5069f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual size_t      framesReady();
5079f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual void        framesReadyIsCalledByMultipleThreads();
5082e422c472c91aa7912befd0fc038d1e11f354bc1Glenn Kasten    virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush);
5099f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual void        releaseBuffer(Buffer* buffer);
51082aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    virtual void        tallyUnderrunFrames(uint32_t frameCount);
51182aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    virtual uint32_t    getUnderrunFrames() const { return 0; }
512e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
513e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kastenprivate:
5149b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    status_t            updateStateWithLoop(StaticAudioTrackState *localState,
5159b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung                                            const StaticAudioTrackState &update) const;
5169b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    status_t            updateStateWithPosition(StaticAudioTrackState *localState,
5179b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung                                                const StaticAudioTrackState &update) const;
5189f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ssize_t             pollPosition(); // poll for state queue update, and return current position
5199f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    StaticAudioTrackSingleStateQueue::Observer  mObserver;
5204ede21d9c1f957baf5e561849ff9bbe4bcbefc20Andy Hung    StaticAudioTrackPosLoopQueue::Mutator       mPosLoopMutator;
521cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung    size_t              mFramesReadySafe; // Assuming size_t read/writes are atomic on 32 / 64 bit
522cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung                                          // processors, this is a thread-safe version of
523cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung                                          // mFramesReady.
524cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung    int64_t             mFramesReady;     // The number of frames ready in the static buffer
525cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung                                          // including loops.  This is 64 bits since loop mode
526cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung                                          // can cause a track to appear to have a large number
527cb2129b3b568a4e31bcbda3545a468024bc972feAndy Hung                                          // of frames. INT64_MAX means an infinite loop.
5289f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    bool                mFramesReadyIsCalledByMultipleThreads;
5299b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung    StaticAudioTrackState mState;         // Server side state. Any updates from client must be
5309b4615887c23548438fd0d8e3d8f04ac21912850Andy Hung                                          // passed by the mObserver SingleStateQueue.
5319f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten};
532e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten
5339f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten// Proxy used by AudioFlinger for servicing AudioRecord
5349f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenclass AudioRecordServerProxy : public ServerProxy {
5359f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenpublic:
5369f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    AudioRecordServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
53783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            size_t frameSize, bool clientInServer)
53883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        : ServerProxy(cblk, buffers, frameCount, frameSize, false /*isOut*/, clientInServer) { }
5399f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenprotected:
5409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    virtual ~AudioRecordServerProxy() { }
541e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten};
54289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
54389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ----------------------------------------------------------------------------
54489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
54589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android
54689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
54789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#endif // ANDROID_AUDIO_TRACK_SHARED_H
548