blob: 9ab362a39ddd1d82bded2922e07bd646876b8781 [file] [log] [blame]
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001/* //device/include/server/AudioFlinger/AudioFlinger.h
2**
3** Copyright 2007, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#ifndef ANDROID_AUDIO_FLINGER_H
19#define ANDROID_AUDIO_FLINGER_H
20
21#include <stdint.h>
22#include <sys/types.h>
23
24#include <media/IAudioFlinger.h>
25#include <media/IAudioTrack.h>
26#include <media/IAudioRecord.h>
27#include <media/AudioTrack.h>
28
29#include <utils/Atomic.h>
30#include <utils/Errors.h>
31#include <utils/threads.h>
32#include <utils/MemoryDealer.h>
33#include <utils/KeyedVector.h>
34#include <utils/SortedVector.h>
35
The Android Open Source Project8a7a6752009-01-15 16:12:10 -080036#include <hardware_legacy/AudioHardwareInterface.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070037
38#include "AudioBufferProvider.h"
39
40namespace android {
41
42class audio_track_cblk_t;
43class AudioMixer;
44class AudioBuffer;
45
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -080046
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070047// ----------------------------------------------------------------------------
48
49#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
50#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
51
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -080052
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070053// ----------------------------------------------------------------------------
54
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -080055static const nsecs_t kStandbyTimeInNsecs = seconds(3);
56
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070057class AudioFlinger : public BnAudioFlinger, protected Thread
58{
59public:
60 static void instantiate();
61
62 virtual status_t dump(int fd, const Vector<String16>& args);
63
64 // Thread virtuals
65 virtual bool threadLoop();
66 virtual status_t readyToRun();
67 virtual void onFirstRef();
68
69 // IAudioFlinger interface
70 virtual sp<IAudioTrack> createTrack(
71 pid_t pid,
72 int streamType,
73 uint32_t sampleRate,
74 int format,
75 int channelCount,
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -080076 int frameCount,
77 uint32_t flags,
78 const sp<IMemory>& sharedBuffer,
79 status_t *status);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070080
81 virtual uint32_t sampleRate() const;
82 virtual int channelCount() const;
83 virtual int format() const;
84 virtual size_t frameCount() const;
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -080085 virtual size_t latency() const;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070086
87 virtual status_t setMasterVolume(float value);
88 virtual status_t setMasterMute(bool muted);
89
90 virtual float masterVolume() const;
91 virtual bool masterMute() const;
92
93 virtual status_t setStreamVolume(int stream, float value);
94 virtual status_t setStreamMute(int stream, bool muted);
95
96 virtual float streamVolume(int stream) const;
97 virtual bool streamMute(int stream) const;
98
99 virtual status_t setRouting(int mode, uint32_t routes, uint32_t mask);
100 virtual uint32_t getRouting(int mode) const;
101
102 virtual status_t setMode(int mode);
103 virtual int getMode() const;
104
105 virtual status_t setMicMute(bool state);
106 virtual bool getMicMute() const;
107
108 virtual bool isMusicActive() const;
109
110 virtual status_t setParameter(const char* key, const char* value);
111
112 enum hardware_call_state {
113 AUDIO_HW_IDLE = 0,
114 AUDIO_HW_INIT,
115 AUDIO_HW_OUTPUT_OPEN,
116 AUDIO_HW_OUTPUT_CLOSE,
117 AUDIO_HW_INPUT_OPEN,
118 AUDIO_HW_INPUT_CLOSE,
119 AUDIO_HW_STANDBY,
120 AUDIO_HW_SET_MASTER_VOLUME,
121 AUDIO_HW_GET_ROUTING,
122 AUDIO_HW_SET_ROUTING,
123 AUDIO_HW_GET_MODE,
124 AUDIO_HW_SET_MODE,
125 AUDIO_HW_GET_MIC_MUTE,
126 AUDIO_HW_SET_MIC_MUTE,
127 AUDIO_SET_VOICE_VOLUME,
128 AUDIO_SET_PARAMETER,
129 };
130
131 // record interface
132 virtual sp<IAudioRecord> openRecord(
133 pid_t pid,
134 int streamType,
135 uint32_t sampleRate,
136 int format,
137 int channelCount,
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800138 int frameCount,
139 uint32_t flags,
140 status_t *status);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700141
142 virtual status_t onTransact(
143 uint32_t code,
144 const Parcel& data,
145 Parcel* reply,
146 uint32_t flags);
147
148private:
149 AudioFlinger();
150 virtual ~AudioFlinger();
151
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800152 void setOutput(AudioStreamOut* output);
The Android Open Source Project27629322009-01-09 17:51:23 -0800153 void doSetOutput(AudioStreamOut* output);
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800154 size_t getOutputFrameCount(AudioStreamOut* output);
155
The Android Open Source Projecte41dd752009-01-22 00:13:42 -0800156#ifdef WITH_A2DP
157 static bool streamDisablesA2dp(int streamType);
158 inline bool isA2dpEnabled() const {
159 return (mRequestedOutput == mA2dpOutput ||
160 (mOutput && mOutput == mA2dpOutput));
161 }
162 void setA2dpEnabled(bool enable);
163#endif
164
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700165 // Internal dump utilites.
166 status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
167 status_t dumpClients(int fd, const Vector<String16>& args);
168 status_t dumpTracks(int fd, const Vector<String16>& args);
169 status_t dumpInternals(int fd, const Vector<String16>& args);
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800170
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700171 // --- Client ---
172 class Client : public RefBase {
173 public:
174 Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
175 virtual ~Client();
176 const sp<MemoryDealer>& heap() const;
177 pid_t pid() const { return mPid; }
178 private:
179 Client(const Client&);
180 Client& operator = (const Client&);
181 sp<AudioFlinger> mAudioFlinger;
182 sp<MemoryDealer> mMemoryDealer;
183 pid_t mPid;
184 };
185
186
187 // --- Track ---
188 class TrackHandle;
189 class RecordHandle;
190 class AudioRecordThread;
191
192 // base for record and playback
193 class TrackBase : public AudioBufferProvider, public RefBase {
194
195 public:
196 enum track_state {
197 IDLE,
198 TERMINATED,
199 STOPPED,
200 RESUMING,
201 ACTIVE,
202 PAUSING,
203 PAUSED
204 };
205
206 enum track_flags {
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800207 STEPSERVER_FAILED = 0x01 // StepServer could not acquire cblk->lock mutex
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700208 };
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800209
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700210 TrackBase( const sp<AudioFlinger>& audioFlinger,
211 const sp<Client>& client,
212 int streamType,
213 uint32_t sampleRate,
214 int format,
215 int channelCount,
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800216 int frameCount,
217 const sp<IMemory>& sharedBuffer);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700218 ~TrackBase();
219
220 virtual status_t start() = 0;
221 virtual void stop() = 0;
222 sp<IMemory> getCblk() const;
223
224 protected:
225 friend class AudioFlinger;
226 friend class RecordHandle;
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800227 friend class AudioRecordThread;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700228
229 TrackBase(const TrackBase&);
230 TrackBase& operator = (const TrackBase&);
231
232 virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
233 virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
234
235 audio_track_cblk_t* cblk() const {
236 return mCblk;
237 }
238
239 int type() const {
240 return mStreamType;
241 }
242
243 int format() const {
244 return mFormat;
245 }
246
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800247 int channelCount() const ;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700248
249 int sampleRate() const;
250
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800251 void* getBuffer(uint32_t offset, uint32_t frames) const;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700252
253 int name() const {
254 return mName;
255 }
256
257 bool isStopped() const {
258 return mState == STOPPED;
259 }
260
261 bool isTerminated() const {
262 return mState == TERMINATED;
263 }
264
265 bool step();
266 void reset();
267
268 sp<AudioFlinger> mAudioFlinger;
269 sp<Client> mClient;
270 sp<IMemory> mCblkMemory;
271 audio_track_cblk_t* mCblk;
272 int mStreamType;
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800273 void* mBuffer;
274 void* mBufferEnd;
275 uint32_t mFrameCount;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700276 int mName;
277 // we don't really need a lock for these
278 int mState;
279 int mClientTid;
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800280 uint8_t mFormat;
281 uint8_t mFlags;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700282 };
283
284 // playback track
285 class Track : public TrackBase {
286 public:
287 Track( const sp<AudioFlinger>& audioFlinger,
288 const sp<Client>& client,
289 int streamType,
290 uint32_t sampleRate,
291 int format,
292 int channelCount,
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800293 int frameCount,
294 const sp<IMemory>& sharedBuffer);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700295 ~Track();
296
297 void dump(char* buffer, size_t size);
298 virtual status_t start();
299 virtual void stop();
300 void pause();
301
302 void flush();
303 void destroy();
304 void mute(bool);
305 void setVolume(float left, float right);
306
307 private:
308 friend class AudioFlinger;
309 friend class TrackHandle;
310
311 Track(const Track&);
312 Track& operator = (const Track&);
313
314 virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
315
316 bool isMuted() const {
317 return mMute;
318 }
319
320 bool isPausing() const {
321 return mState == PAUSING;
322 }
323
324 bool isPaused() const {
325 return mState == PAUSED;
326 }
327
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800328 bool isReady() const;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700329
330 void setPaused() { mState = PAUSED; }
331 void reset();
332
333 // we don't really need a lock for these
334 float mVolume[2];
335 volatile bool mMute;
336 // FILLED state is used for suppressing volume ramp at begin of playing
337 enum {FS_FILLING, FS_FILLED, FS_ACTIVE};
338 mutable uint8_t mFillingUpStatus;
339 int8_t mRetryCount;
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800340 sp<IMemory> mSharedBuffer;
341 bool mResetDone;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700342 }; // end of Track
343
344 friend class AudioBuffer;
345
346 class TrackHandle : public android::BnAudioTrack {
347 public:
348 TrackHandle(const sp<Track>& track);
349 virtual ~TrackHandle();
350 virtual status_t start();
351 virtual void stop();
352 virtual void flush();
353 virtual void mute(bool);
354 virtual void pause();
355 virtual void setVolume(float left, float right);
356 virtual sp<IMemory> getCblk() const;
357 virtual status_t onTransact(
358 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
359 private:
360 sp<Track> mTrack;
361 };
362
363 struct stream_type_t {
364 stream_type_t()
365 : volume(1.0f),
366 mute(false)
367 {
368 }
369 float volume;
370 bool mute;
371 };
372
373 friend class Client;
374 friend class Track;
375
376
377 void removeClient(pid_t pid);
378
379 status_t addTrack(const sp<Track>& track);
380 void removeTrack(wp<Track> track, int name);
381 void remove_track_l(wp<Track> track, int name);
382 void destroyTrack(const sp<Track>& track);
The Android Open Source Projecte41dd752009-01-22 00:13:42 -0800383 void addActiveTrack(const wp<Track>& track);
384 void removeActiveTrack(const wp<Track>& track);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700385
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800386 AudioMixer* audioMixer() {
387 return mAudioMixer;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700388 }
389
390 // record track
391 class RecordTrack : public TrackBase {
392 public:
393 RecordTrack( const sp<AudioFlinger>& audioFlinger,
394 const sp<Client>& client,
395 int streamType,
396 uint32_t sampleRate,
397 int format,
398 int channelCount,
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800399 int frameCount);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700400 ~RecordTrack();
401
402 virtual status_t start();
403 virtual void stop();
404
405 bool overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; }
406 bool setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
407
408 private:
409 friend class AudioFlinger;
410 friend class RecordHandle;
411 friend class AudioRecordThread;
412
413 RecordTrack(const Track&);
414 RecordTrack& operator = (const Track&);
415
416 virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
417
418 bool mOverflow;
419 };
420
421 class RecordHandle : public android::BnAudioRecord {
422 public:
423 RecordHandle(const sp<RecordTrack>& recordTrack);
424 virtual ~RecordHandle();
425 virtual status_t start();
426 virtual void stop();
427 virtual sp<IMemory> getCblk() const;
428 virtual status_t onTransact(
429 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
430 private:
431 sp<RecordTrack> mRecordTrack;
432 };
433
434 // record thread
435 class AudioRecordThread : public Thread
436 {
437 public:
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800438 AudioRecordThread(AudioHardwareInterface* audioHardware);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700439 virtual ~AudioRecordThread();
440 virtual bool threadLoop();
441 virtual status_t readyToRun() { return NO_ERROR; }
442 virtual void onFirstRef() {}
443
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800444 status_t start(RecordTrack* recordTrack);
445 void stop(RecordTrack* recordTrack);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700446 void exit();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700447
448 private:
449 AudioRecordThread();
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800450 AudioHardwareInterface *mAudioHardware;
451 sp<RecordTrack> mRecordTrack;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700452 Mutex mLock;
453 Condition mWaitWorkCV;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700454 volatile bool mActive;
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800455 status_t mStartStatus;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700456 };
457
458 friend class AudioRecordThread;
459
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800460 status_t startRecord(RecordTrack* recordTrack);
461 void stopRecord(RecordTrack* recordTrack);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700462
463 mutable Mutex mHardwareLock;
464 mutable Mutex mLock;
465 mutable Condition mWaitWorkCV;
466 DefaultKeyedVector< pid_t, wp<Client> > mClients;
467 SortedVector< wp<Track> > mActiveTracks;
468 SortedVector< sp<Track> > mTracks;
469 float mMasterVolume;
470 uint32_t mMasterRouting;
471 bool mMasterMute;
472 stream_type_t mStreamTypes[AudioTrack::NUM_STREAM_TYPES];
473
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800474 AudioMixer* mHardwareAudioMixer;
475 AudioMixer* mA2dpAudioMixer;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700476 AudioMixer* mAudioMixer;
477 AudioHardwareInterface* mAudioHardware;
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800478 AudioHardwareInterface* mA2dpAudioInterface;
479 AudioStreamOut* mHardwareOutput;
480 AudioStreamOut* mA2dpOutput;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700481 AudioStreamOut* mOutput;
The Android Open Source Project27629322009-01-09 17:51:23 -0800482 AudioStreamOut* mRequestedOutput;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700483 sp<AudioRecordThread> mAudioRecordThread;
484 uint32_t mSampleRate;
485 size_t mFrameCount;
486 int mChannelCount;
487 int mFormat;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700488 int16_t* mMixBuffer;
489 mutable int mHardwareStatus;
490 nsecs_t mLastWriteTime;
491 int mNumWrites;
492 int mNumDelayedWrites;
493 bool mStandby;
494 bool mInWrite;
The Android Open Source Projecte41dd752009-01-22 00:13:42 -0800495 int mA2dpDisableCount;
496 bool mA2dpSuppressed;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700497};
498
499// ----------------------------------------------------------------------------
500
501}; // namespace android
502
503#endif // ANDROID_AUDIO_FLINGER_H