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