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