blob: 41e20f809bf09d3c4f72ca4b45604df60032b249 [file] [log] [blame]
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_AUDIO_TRACK_SHARED_H
18#define ANDROID_AUDIO_TRACK_SHARED_H
19
20#include <stdint.h>
21#include <sys/types.h>
22
23#include <utils/threads.h>
Glenn Kastene3aa6592012-12-04 12:22:46 -080024#include <utils/Log.h>
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080025
26namespace android {
27
28// ----------------------------------------------------------------------------
29
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080030// Maximum cumulated timeout milliseconds before restarting audioflinger thread
Glenn Kasten85ab62c2012-11-01 11:11:38 -070031#define MAX_STARTUP_TIMEOUT_MS 3000 // Longer timeout period at startup to cope with A2DP
32 // init time
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080033#define MAX_RUN_TIMEOUT_MS 1000
34#define WAIT_PERIOD_MS 10
35
Glenn Kasten9c5fdd82012-11-05 13:38:15 -080036#define CBLK_UNDERRUN 0x01 // set: underrun (out) or overrrun (in), clear: no underrun or overrun
Glenn Kasten864585d2012-11-06 16:15:41 -080037#define CBLK_FORCEREADY 0x02 // set: track is considered ready immediately by AudioFlinger,
Glenn Kasten9c5fdd82012-11-05 13:38:15 -080038 // clear: track is ready when buffer full
Glenn Kasten864585d2012-11-06 16:15:41 -080039#define CBLK_INVALID 0x04 // track buffer invalidated by AudioFlinger, need to re-create
40#define CBLK_DISABLED 0x08 // track disabled by AudioFlinger due to underrun, need to re-start
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080041
Glenn Kastene3aa6592012-12-04 12:22:46 -080042struct AudioTrackSharedStreaming {
43 // similar to NBAIO MonoPipe
44 volatile int32_t mFront;
45 volatile int32_t mRear;
46};
47
48// future
49struct AudioTrackSharedStatic {
50 int mReserved;
51};
52
53// ----------------------------------------------------------------------------
54
Glenn Kasten1a0ae5b2012-02-03 10:24:48 -080055// Important: do not add any virtual methods, including ~
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080056struct audio_track_cblk_t
57{
Glenn Kastene3aa6592012-12-04 12:22:46 -080058 friend class Proxy;
59 friend class AudioTrackClientProxy;
60 friend class AudioRecordClientProxy;
61 friend class ServerProxy;
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080062
63 // The data members are grouped so that members accessed frequently and in the same context
64 // are in the same line of data cache.
Glenn Kasten362c4e62011-12-14 10:28:06 -080065 Mutex lock; // sizeof(int)
66 Condition cv; // sizeof(int)
Glenn Kasten99e53b82012-01-19 08:59:58 -080067
68 // next 4 are offsets within "buffers"
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -080069 volatile uint32_t user;
70 volatile uint32_t server;
71 uint32_t userBase;
72 uint32_t serverBase;
Glenn Kasten99e53b82012-01-19 08:59:58 -080073
Glenn Kastenb929e412012-11-08 12:13:58 -080074 int mPad1; // unused, but preserves cache line alignment
Glenn Kasten22eb4e22012-11-07 14:03:00 -080075
Glenn Kastenb6037442012-11-14 13:42:25 -080076 size_t frameCount_; // used during creation to pass actual track buffer size
77 // from AudioFlinger to client, and not referenced again
78 // FIXME remove here and replace by createTrack() in/out parameter
79 // renamed to "_" to detect incorrect use
Glenn Kasten99e53b82012-01-19 08:59:58 -080080
Glenn Kasten22eb4e22012-11-07 14:03:00 -080081 // Cache line boundary (32 bytes)
Glenn Kasten99e53b82012-01-19 08:59:58 -080082
Eric Laurentd1b449a2010-05-14 03:26:45 -070083 uint32_t loopStart;
Glenn Kasten99e53b82012-01-19 08:59:58 -080084 uint32_t loopEnd; // read-only for server, read/write for client
85 int loopCount; // read/write for client
Glenn Kastenb1cf75c2012-01-17 12:20:54 -080086
87 // Channel volumes are fixed point U4.12, so 0x1000 means 1.0.
88 // Left channel is in [0:15], right channel is in [16:31].
89 // Always read and write the combined pair atomically.
90 // For AudioTrack only, not used by AudioRecord.
Glenn Kasten83d86532012-01-17 14:39:34 -080091private:
92 uint32_t mVolumeLR;
Glenn Kastenb1cf75c2012-01-17 12:20:54 -080093
Glenn Kastene3aa6592012-12-04 12:22:46 -080094 uint32_t mSampleRate; // AudioTrack only: client's requested sample rate in Hz
95 // or 0 == default. Write-only client, read-only server.
Glenn Kasten99e53b82012-01-19 08:59:58 -080096
Glenn Kasten83a03822012-11-12 07:58:20 -080097 uint8_t mPad2; // unused
Eric Laurentd1b449a2010-05-14 03:26:45 -070098
Glenn Kastene3aa6592012-12-04 12:22:46 -080099public:
Glenn Kasten99e53b82012-01-19 08:59:58 -0800100 // read-only for client, server writes once at initialization and is then read-only
Glenn Kasten0c9d26d2012-05-31 14:35:01 -0700101 uint8_t mName; // normal tracks: track name, fast tracks: track index
Glenn Kasten99e53b82012-01-19 08:59:58 -0800102
103 // used by client only
Glenn Kasten85ab62c2012-11-01 11:11:38 -0700104 uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting
105 // audioflinger
Eric Laurentc2f1f072009-07-17 12:17:14 -0700106
Glenn Kasten99e53b82012-01-19 08:59:58 -0800107 uint16_t waitTimeMs; // Cumulated wait time, used by client only
Glenn Kasten05632a52012-01-03 14:22:33 -0800108private:
Glenn Kasten99e53b82012-01-19 08:59:58 -0800109 // client write-only, server read-only
Glenn Kasten05632a52012-01-03 14:22:33 -0800110 uint16_t mSendLevel; // Fixed point U4.12 so 0x1000 means 1.0
111public:
Eric Laurent38ccae22011-03-28 18:37:07 -0700112 volatile int32_t flags;
113
Eric Laurentd1b449a2010-05-14 03:26:45 -0700114 // Cache line boundary (32 bytes)
Jean-Michel Trivi0d255b22011-05-24 15:53:33 -0700115
Glenn Kastene3aa6592012-12-04 12:22:46 -0800116#if 0
117 union {
118 AudioTrackSharedStreaming mStreaming;
119 AudioTrackSharedStatic mStatic;
120 int mAlign[8];
121 } u;
122
123 // Cache line boundary (32 bytes)
124#endif
125
Glenn Kasten99e53b82012-01-19 08:59:58 -0800126 // Since the control block is always located in shared memory, this constructor
127 // is only used for placement new(). It is never used for regular new() or stack.
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800128 audio_track_cblk_t();
Glenn Kasten864585d2012-11-06 16:15:41 -0800129
Glenn Kastene3aa6592012-12-04 12:22:46 -0800130private:
Glenn Kastenb929e412012-11-08 12:13:58 -0800131 // if there is a shared buffer, "buffers" is the value of pointer() for the shared
132 // buffer, otherwise "buffers" points immediately after the control block
Glenn Kastene3aa6592012-12-04 12:22:46 -0800133 void* buffer(void *buffers, uint32_t frameSize, size_t offset) const;
Glenn Kasten864585d2012-11-06 16:15:41 -0800134
Eric Laurent38ccae22011-03-28 18:37:07 -0700135 bool tryLock();
Glenn Kasten05632a52012-01-03 14:22:33 -0800136
Glenn Kasten864585d2012-11-06 16:15:41 -0800137 // isOut == true means AudioTrack, isOut == false means AudioRecord
Glenn Kastene3aa6592012-12-04 12:22:46 -0800138 bool stepServer(size_t stepCount, size_t frameCount, bool isOut);
Glenn Kastenb6037442012-11-14 13:42:25 -0800139 uint32_t stepUser(size_t stepCount, size_t frameCount, bool isOut);
140 uint32_t framesAvailable(size_t frameCount, bool isOut);
141 uint32_t framesAvailable_l(size_t frameCount, bool isOut);
Glenn Kasten864585d2012-11-06 16:15:41 -0800142 uint32_t framesReady(bool isOut);
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800143};
144
Glenn Kastene3aa6592012-12-04 12:22:46 -0800145// ----------------------------------------------------------------------------
146
147// Proxy for shared memory control block, to isolate callers from needing to know the details.
148// There is exactly one ClientProxy and one ServerProxy per shared memory control block.
149// The proxies are located in normal memory, and are not multi-thread safe within a given side.
150class Proxy {
151protected:
152 Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize)
153 : mCblk(cblk), mBuffers(buffers), mFrameCount(frameCount), mFrameSize(frameSize) { }
154 virtual ~Proxy() { }
155
156public:
157 void* buffer(size_t offset) const {
158 return mCblk->buffer(mBuffers, mFrameSize, offset);
159 }
160
161protected:
162 // These refer to shared memory, and are virtual addresses with respect to the current process.
163 // They may have different virtual addresses within the other process.
164 audio_track_cblk_t* const mCblk; // the control block
165 void* const mBuffers; // starting address of buffers
166
167 const size_t mFrameCount; // not necessarily a power of 2
168 const size_t mFrameSize; // in bytes
169#if 0
170 const size_t mFrameCountP2; // mFrameCount rounded to power of 2, streaming mode
171#endif
172
173};
174
175// ----------------------------------------------------------------------------
176
177// Proxy seen by AudioTrack client and AudioRecord client
178class ClientProxy : public Proxy {
179protected:
180 ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize)
181 : Proxy(cblk, buffers, frameCount, frameSize) { }
182 virtual ~ClientProxy() { }
183};
184
185// ----------------------------------------------------------------------------
186
187// Proxy used by AudioTrack client, which also includes AudioFlinger::PlaybackThread::OutputTrack
188class AudioTrackClientProxy : public ClientProxy {
189public:
190 AudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize)
191 : ClientProxy(cblk, buffers, frameCount, frameSize) { }
192 virtual ~AudioTrackClientProxy() { }
193
194 // No barriers on the following operations, so the ordering of loads/stores
195 // with respect to other parameters is UNPREDICTABLE. That's considered safe.
196
197 // caller must limit to 0.0 <= sendLevel <= 1.0
198 void setSendLevel(float sendLevel) {
199 mCblk->mSendLevel = uint16_t(sendLevel * 0x1000);
200 }
201
202 // caller must limit to 0 <= volumeLR <= 0x10001000
203 void setVolumeLR(uint32_t volumeLR) {
204 mCblk->mVolumeLR = volumeLR;
205 }
206
207 void setSampleRate(uint32_t sampleRate) {
208 mCblk->mSampleRate = sampleRate;
209 }
210
211 // called by:
212 // PlaybackThread::OutputTrack::write
213 // AudioTrack::createTrack_l
214 // AudioTrack::releaseBuffer
215 // AudioTrack::reload
216 // AudioTrack::restoreTrack_l (2 places)
217 size_t stepUser(size_t stepCount) {
218 return mCblk->stepUser(stepCount, mFrameCount, true /*isOut*/);
219 }
220
221 // called by AudioTrack::obtainBuffer and AudioTrack::processBuffer
222 size_t framesAvailable() {
223 return mCblk->framesAvailable(mFrameCount, true /*isOut*/);
224 }
225
226 // called by AudioTrack::obtainBuffer and PlaybackThread::OutputTrack::obtainBuffer
227 // FIXME remove this API since it assumes a lock that should be invisible to caller
228 size_t framesAvailable_l() {
229 return mCblk->framesAvailable_l(mFrameCount, true /*isOut*/);
230 }
231
232};
233
234// ----------------------------------------------------------------------------
235
236// Proxy used by AudioRecord client
237class AudioRecordClientProxy : public ClientProxy {
238public:
239 AudioRecordClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize)
240 : ClientProxy(cblk, buffers, frameCount, frameSize) { }
241 ~AudioRecordClientProxy() { }
242
243 // called by AudioRecord::releaseBuffer
244 size_t stepUser(size_t stepCount) {
245 return mCblk->stepUser(stepCount, mFrameCount, false /*isOut*/);
246 }
247
248 // called by AudioRecord::processBuffer
249 size_t framesAvailable() {
250 return mCblk->framesAvailable(mFrameCount, false /*isOut*/);
251 }
252
253 // called by AudioRecord::obtainBuffer
254 size_t framesReady() {
255 return mCblk->framesReady(false /*isOut*/);
256 }
257
258};
259
260// ----------------------------------------------------------------------------
261
262// Proxy used by AudioFlinger server
263class ServerProxy : public Proxy {
264public:
265 ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut)
266 : Proxy(cblk, buffers, frameCount, frameSize), mIsOut(isOut) { }
267 virtual ~ServerProxy() { }
268
269 // for AudioTrack and AudioRecord
270 bool step(size_t stepCount) { return mCblk->stepServer(stepCount, mFrameCount, mIsOut); }
271
272 // return value of these methods must be validated by the caller
273 uint32_t getSampleRate() const { return mCblk->mSampleRate; }
274 uint16_t getSendLevel_U4_12() const { return mCblk->mSendLevel; }
275 uint32_t getVolumeLR() const { return mCblk->mVolumeLR; }
276
277 // for AudioTrack only
278 size_t framesReady() {
279 ALOG_ASSERT(mIsOut);
280 return mCblk->framesReady(true);
281 }
282
283 // for AudioRecord only, called by RecordThread::RecordTrack::getNextBuffer
284 // FIXME remove this API since it assumes a lock that should be invisible to caller
285 size_t framesAvailableIn_l() {
286 ALOG_ASSERT(!mIsOut);
287 return mCblk->framesAvailable_l(mFrameCount, false);
288 }
289
290private:
291 const bool mIsOut; // true for AudioTrack, false for AudioRecord
292
293};
The Android Open Source Project89fa4ad2009-03-03 19:31:44 -0800294
295// ----------------------------------------------------------------------------
296
297}; // namespace android
298
299#endif // ANDROID_AUDIO_TRACK_SHARED_H