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