blob: b9ecdd8e41fb281fb56ca212ef18d97887a6e1fd [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/* //device/include/server/AudioFlinger/AudioFlinger.cpp
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
19#define LOG_TAG "AudioFlinger"
20//#define LOG_NDEBUG 0
21
22#include <math.h>
23#include <signal.h>
24#include <sys/time.h>
25#include <sys/resource.h>
26
27#include <utils/IServiceManager.h>
28#include <utils/Log.h>
29#include <utils/Parcel.h>
30#include <utils/IPCThreadState.h>
31#include <utils/String16.h>
32#include <utils/threads.h>
33
34#include <cutils/properties.h>
35
36#include <media/AudioTrack.h>
37#include <media/AudioRecord.h>
38
39#include <private/media/AudioTrackShared.h>
40
41#include <hardware_legacy/AudioHardwareInterface.h>
42
43#include "AudioMixer.h"
44#include "AudioFlinger.h"
45
46#ifdef WITH_A2DP
47#include "A2dpAudioInterface.h"
48#endif
49
50// ----------------------------------------------------------------------------
51// the sim build doesn't have gettid
52
53#ifndef HAVE_GETTID
54# define gettid getpid
55#endif
56
57// ----------------------------------------------------------------------------
58
59namespace android {
60
The Android Open Source Project10592532009-03-18 17:39:46 -070061static const char* kDeadlockedString = "AudioFlinger may be deadlocked\n";
62static const char* kHardwareLockedString = "Hardware lock is taken\n";
63
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
65static const unsigned long kBufferRecoveryInUsecs = 2000;
66static const unsigned long kMaxBufferRecoveryInUsecs = 20000;
67static const float MAX_GAIN = 4096.0f;
68
69// retry counts for buffer fill timeout
70// 50 * ~20msecs = 1 second
71static const int8_t kMaxTrackRetries = 50;
72static const int8_t kMaxTrackStartupRetries = 50;
73
74static const int kStartSleepTime = 30000;
75static const int kStopSleepTime = 30000;
76
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -070077static const int kDumpLockRetries = 50;
78static const int kDumpLockSleep = 20000;
79
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080// Maximum number of pending buffers allocated by OutputTrack::write()
81static const uint8_t kMaxOutputTrackBuffers = 5;
82
83
84#define AUDIOFLINGER_SECURITY_ENABLED 1
85
86// ----------------------------------------------------------------------------
87
88static bool recordingAllowed() {
89#ifndef HAVE_ANDROID_OS
90 return true;
91#endif
92#if AUDIOFLINGER_SECURITY_ENABLED
93 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
94 bool ok = checkCallingPermission(String16("android.permission.RECORD_AUDIO"));
95 if (!ok) LOGE("Request requires android.permission.RECORD_AUDIO");
96 return ok;
97#else
98 if (!checkCallingPermission(String16("android.permission.RECORD_AUDIO")))
99 LOGW("WARNING: Need to add android.permission.RECORD_AUDIO to manifest");
100 return true;
101#endif
102}
103
104static bool settingsAllowed() {
105#ifndef HAVE_ANDROID_OS
106 return true;
107#endif
108#if AUDIOFLINGER_SECURITY_ENABLED
109 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
110 bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
111 if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
112 return ok;
113#else
114 if (!checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")))
115 LOGW("WARNING: Need to add android.permission.MODIFY_AUDIO_SETTINGS to manifest");
116 return true;
117#endif
118}
119
120// ----------------------------------------------------------------------------
121
122AudioFlinger::AudioFlinger()
123 : BnAudioFlinger(),
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700124 mAudioHardware(0), mA2dpAudioInterface(0), mA2dpEnabled(false), mNotifyA2dpChange(false),
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700125 mForcedSpeakerCount(0), mA2dpDisableCount(0), mA2dpSuppressed(false), mForcedRoute(0),
126 mRouteRestoreTime(0), mMusicMuteSaved(false)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127{
128 mHardwareStatus = AUDIO_HW_IDLE;
129 mAudioHardware = AudioHardwareInterface::create();
130 mHardwareStatus = AUDIO_HW_INIT;
131 if (mAudioHardware->initCheck() == NO_ERROR) {
132 // open 16-bit output stream for s/w mixer
133 mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
134 status_t status;
135 AudioStreamOut *hwOutput = mAudioHardware->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
136 mHardwareStatus = AUDIO_HW_IDLE;
137 if (hwOutput) {
138 mHardwareMixerThread = new MixerThread(this, hwOutput, AudioSystem::AUDIO_OUTPUT_HARDWARE);
139 } else {
140 LOGE("Failed to initialize hardware output stream, status: %d", status);
141 }
142
143#ifdef WITH_A2DP
144 // Create A2DP interface
145 mA2dpAudioInterface = new A2dpAudioInterface();
146 AudioStreamOut *a2dpOutput = mA2dpAudioInterface->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
147 if (a2dpOutput) {
148 mA2dpMixerThread = new MixerThread(this, a2dpOutput, AudioSystem::AUDIO_OUTPUT_A2DP);
149 if (hwOutput) {
150 uint32_t frameCount = ((a2dpOutput->bufferSize()/a2dpOutput->frameSize()) * hwOutput->sampleRate()) / a2dpOutput->sampleRate();
151 MixerThread::OutputTrack *a2dpOutTrack = new MixerThread::OutputTrack(mA2dpMixerThread,
152 hwOutput->sampleRate(),
153 AudioSystem::PCM_16_BIT,
154 hwOutput->channelCount(),
155 frameCount);
156 mHardwareMixerThread->setOuputTrack(a2dpOutTrack);
157 }
158 } else {
159 LOGE("Failed to initialize A2DP output stream, status: %d", status);
160 }
161#endif
162
163 // FIXME - this should come from settings
164 setRouting(AudioSystem::MODE_NORMAL, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
165 setRouting(AudioSystem::MODE_RINGTONE, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
166 setRouting(AudioSystem::MODE_IN_CALL, AudioSystem::ROUTE_EARPIECE, AudioSystem::ROUTE_ALL);
167 setMode(AudioSystem::MODE_NORMAL);
168
169 setMasterVolume(1.0f);
170 setMasterMute(false);
171
172 // Start record thread
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700173 mAudioRecordThread = new AudioRecordThread(mAudioHardware, this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 if (mAudioRecordThread != 0) {
175 mAudioRecordThread->run("AudioRecordThread", PRIORITY_URGENT_AUDIO);
176 }
177 } else {
178 LOGE("Couldn't even initialize the stubbed audio hardware!");
179 }
180}
181
182AudioFlinger::~AudioFlinger()
183{
184 if (mAudioRecordThread != 0) {
185 mAudioRecordThread->exit();
186 mAudioRecordThread.clear();
187 }
188 mHardwareMixerThread.clear();
189 delete mAudioHardware;
190 // deleting mA2dpAudioInterface also deletes mA2dpOutput;
191#ifdef WITH_A2DP
192 mA2dpMixerThread.clear();
193 delete mA2dpAudioInterface;
194#endif
195}
196
197
198#ifdef WITH_A2DP
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700199// setA2dpEnabled_l() must be called with AudioFlinger::mLock held
200void AudioFlinger::setA2dpEnabled_l(bool enable)
The Android Open Source Project10592532009-03-18 17:39:46 -0700201{
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700202 SortedVector < sp<MixerThread::Track> > tracks;
203 SortedVector < wp<MixerThread::Track> > activeTracks;
204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 LOGV_IF(enable, "set output to A2DP\n");
206 LOGV_IF(!enable, "set output to hardware audio\n");
207
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700208 // Transfer tracks playing on MUSIC stream from one mixer to the other
209 if (enable) {
210 mHardwareMixerThread->getTracks_l(tracks, activeTracks);
211 mA2dpMixerThread->putTracks_l(tracks, activeTracks);
212 } else {
213 mA2dpMixerThread->getTracks_l(tracks, activeTracks);
214 mHardwareMixerThread->putTracks_l(tracks, activeTracks);
215 }
216 mA2dpEnabled = enable;
217 mNotifyA2dpChange = true;
218 mWaitWorkCV.broadcast();
219}
220
221// checkA2dpEnabledChange_l() must be called with AudioFlinger::mLock held
222void AudioFlinger::checkA2dpEnabledChange_l()
223{
224 if (mNotifyA2dpChange) {
225 // Notify AudioSystem of the A2DP activation/deactivation
226 size_t size = mNotificationClients.size();
227 for (size_t i = 0; i < size; i++) {
228 sp<IBinder> binder = mNotificationClients.itemAt(i).promote();
229 if (binder != NULL) {
230 LOGV("Notifying output change to client %p", binder.get());
231 sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
232 client->a2dpEnabledChanged(mA2dpEnabled);
233 }
234 }
235 mNotifyA2dpChange = false;
236 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237}
238#endif // WITH_A2DP
239
240bool AudioFlinger::streamForcedToSpeaker(int streamType)
241{
242 // NOTE that streams listed here must not be routed to A2DP by default:
243 // AudioSystem::routedToA2dpOutput(streamType) == false
244 return (streamType == AudioSystem::RING ||
245 streamType == AudioSystem::ALARM ||
Eric Laurenteeea9222009-03-26 01:57:59 -0700246 streamType == AudioSystem::NOTIFICATION ||
247 streamType == AudioSystem::ENFORCED_AUDIBLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248}
249
250status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
251{
252 const size_t SIZE = 256;
253 char buffer[SIZE];
254 String8 result;
255
256 result.append("Clients:\n");
257 for (size_t i = 0; i < mClients.size(); ++i) {
258 wp<Client> wClient = mClients.valueAt(i);
259 if (wClient != 0) {
260 sp<Client> client = wClient.promote();
261 if (client != 0) {
262 snprintf(buffer, SIZE, " pid: %d\n", client->pid());
263 result.append(buffer);
264 }
265 }
266 }
267 write(fd, result.string(), result.size());
268 return NO_ERROR;
269}
270
271
272status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
273{
274 const size_t SIZE = 256;
275 char buffer[SIZE];
276 String8 result;
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700277 int hardwareStatus = mHardwareStatus;
278
279 if (hardwareStatus == AUDIO_HW_IDLE && mHardwareMixerThread->mStandby) {
280 hardwareStatus = AUDIO_HW_STANDBY;
281 }
282 snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 result.append(buffer);
284 write(fd, result.string(), result.size());
285 return NO_ERROR;
286}
287
288status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
289{
290 const size_t SIZE = 256;
291 char buffer[SIZE];
292 String8 result;
293 snprintf(buffer, SIZE, "Permission Denial: "
294 "can't dump AudioFlinger from pid=%d, uid=%d\n",
295 IPCThreadState::self()->getCallingPid(),
296 IPCThreadState::self()->getCallingUid());
297 result.append(buffer);
298 write(fd, result.string(), result.size());
299 return NO_ERROR;
300}
301
The Android Open Source Project10592532009-03-18 17:39:46 -0700302static bool tryLock(Mutex& mutex)
303{
304 bool locked = false;
305 for (int i = 0; i < kDumpLockRetries; ++i) {
306 if (mutex.tryLock() == NO_ERROR) {
307 locked = true;
308 break;
309 }
310 usleep(kDumpLockSleep);
311 }
312 return locked;
313}
314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
316{
317 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
318 dumpPermissionDenial(fd, args);
319 } else {
The Android Open Source Project10592532009-03-18 17:39:46 -0700320 // get state of hardware lock
321 bool hardwareLocked = tryLock(mHardwareLock);
322 if (!hardwareLocked) {
323 String8 result(kHardwareLockedString);
324 write(fd, result.string(), result.size());
325 } else {
326 mHardwareLock.unlock();
327 }
328
329 bool locked = tryLock(mLock);
330
331 // failed to lock - AudioFlinger is probably deadlocked
332 if (!locked) {
333 String8 result(kDeadlockedString);
334 write(fd, result.string(), result.size());
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700335 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336
337 dumpClients(fd, args);
338 dumpInternals(fd, args);
339 mHardwareMixerThread->dump(fd, args);
340#ifdef WITH_A2DP
341 mA2dpMixerThread->dump(fd, args);
342#endif
343
344 // dump record client
345 if (mAudioRecordThread != 0) mAudioRecordThread->dump(fd, args);
346
347 if (mAudioHardware) {
348 mAudioHardware->dumpState(fd, args);
349 }
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700350 if (locked) mLock.unlock();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 }
352 return NO_ERROR;
353}
354
355// IAudioFlinger interface
356
357
358sp<IAudioTrack> AudioFlinger::createTrack(
359 pid_t pid,
360 int streamType,
361 uint32_t sampleRate,
362 int format,
363 int channelCount,
364 int frameCount,
365 uint32_t flags,
366 const sp<IMemory>& sharedBuffer,
367 status_t *status)
368{
369 sp<MixerThread::Track> track;
370 sp<TrackHandle> trackHandle;
371 sp<Client> client;
372 wp<Client> wclient;
373 status_t lStatus;
374
375 if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
376 LOGE("invalid stream type");
377 lStatus = BAD_VALUE;
378 goto Exit;
379 }
380
381 {
382 Mutex::Autolock _l(mLock);
383
384 wclient = mClients.valueFor(pid);
385
386 if (wclient != NULL) {
387 client = wclient.promote();
388 } else {
389 client = new Client(this, pid);
390 mClients.add(pid, client);
391 }
392#ifdef WITH_A2DP
393 if (isA2dpEnabled() && AudioSystem::routedToA2dpOutput(streamType)) {
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700394 track = mA2dpMixerThread->createTrack_l(client, streamType, sampleRate, format,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 channelCount, frameCount, sharedBuffer, &lStatus);
396 } else
397#endif
398 {
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700399 track = mHardwareMixerThread->createTrack_l(client, streamType, sampleRate, format,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 channelCount, frameCount, sharedBuffer, &lStatus);
401 }
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700402 }
403 if (lStatus == NO_ERROR) {
404 trackHandle = new TrackHandle(track);
405 } else {
406 track.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 }
408
409Exit:
410 if(status) {
411 *status = lStatus;
412 }
413 return trackHandle;
414}
415
416uint32_t AudioFlinger::sampleRate(int output) const
417{
418#ifdef WITH_A2DP
419 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
420 return mA2dpMixerThread->sampleRate();
421 }
422#endif
423 return mHardwareMixerThread->sampleRate();
424}
425
426int AudioFlinger::channelCount(int output) const
427{
428#ifdef WITH_A2DP
429 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
430 return mA2dpMixerThread->channelCount();
431 }
432#endif
433 return mHardwareMixerThread->channelCount();
434}
435
436int AudioFlinger::format(int output) const
437{
438#ifdef WITH_A2DP
439 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
440 return mA2dpMixerThread->format();
441 }
442#endif
443 return mHardwareMixerThread->format();
444}
445
446size_t AudioFlinger::frameCount(int output) const
447{
448#ifdef WITH_A2DP
449 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
450 return mA2dpMixerThread->frameCount();
451 }
452#endif
453 return mHardwareMixerThread->frameCount();
454}
455
456uint32_t AudioFlinger::latency(int output) const
457{
458#ifdef WITH_A2DP
459 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
460 return mA2dpMixerThread->latency();
461 }
462#endif
463 return mHardwareMixerThread->latency();
464}
465
466status_t AudioFlinger::setMasterVolume(float value)
467{
468 // check calling permissions
469 if (!settingsAllowed()) {
470 return PERMISSION_DENIED;
471 }
472
473 // when hw supports master volume, don't scale in sw mixer
474 AutoMutex lock(mHardwareLock);
475 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
476 if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
477 value = 1.0f;
478 }
479 mHardwareStatus = AUDIO_HW_IDLE;
480 mHardwareMixerThread->setMasterVolume(value);
481#ifdef WITH_A2DP
482 mA2dpMixerThread->setMasterVolume(value);
483#endif
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 return NO_ERROR;
486}
487
488status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
489{
490 status_t err = NO_ERROR;
491
492 // check calling permissions
493 if (!settingsAllowed()) {
494 return PERMISSION_DENIED;
495 }
496 if ((mode < AudioSystem::MODE_CURRENT) || (mode >= AudioSystem::NUM_MODES)) {
497 LOGW("Illegal value: setRouting(%d, %u, %u)", mode, routes, mask);
498 return BAD_VALUE;
499 }
500
501#ifdef WITH_A2DP
502 LOGD("setRouting %d %d %d, tid %d, calling tid %d\n", mode, routes, mask, gettid(), IPCThreadState::self()->getCallingPid());
503 if (mode == AudioSystem::MODE_NORMAL &&
504 (mask & AudioSystem::ROUTE_BLUETOOTH_A2DP)) {
505 AutoMutex lock(&mLock);
506
507 bool enableA2dp = false;
508 if (routes & AudioSystem::ROUTE_BLUETOOTH_A2DP) {
509 enableA2dp = true;
510 }
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700511 if (mA2dpDisableCount > 0) {
512 mA2dpSuppressed = enableA2dp;
513 } else {
514 setA2dpEnabled_l(enableA2dp);
515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 LOGV("setOutput done\n");
517 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700518 // setRouting() is always called at least for mode == AudioSystem::MODE_IN_CALL when
519 // SCO is enabled, whatever current mode is so we can safely handle A2DP disabling only
520 // in this case to avoid doing it several times.
521 if (mode == AudioSystem::MODE_IN_CALL &&
522 (mask & AudioSystem::ROUTE_BLUETOOTH_SCO)) {
523 AutoMutex lock(&mLock);
524 handleRouteDisablesA2dp_l(routes);
525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526#endif
527
528 // do nothing if only A2DP routing is affected
529 mask &= ~AudioSystem::ROUTE_BLUETOOTH_A2DP;
530 if (mask) {
531 AutoMutex lock(mHardwareLock);
532 mHardwareStatus = AUDIO_HW_GET_ROUTING;
533 uint32_t r;
534 err = mAudioHardware->getRouting(mode, &r);
535 if (err == NO_ERROR) {
536 r = (r & ~mask) | (routes & mask);
537 if (mode == AudioSystem::MODE_NORMAL ||
538 (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
539 mSavedRoute = r;
540 r |= mForcedRoute;
541 LOGV("setRouting mSavedRoute %08x mForcedRoute %08x\n", mSavedRoute, mForcedRoute);
542 }
543 mHardwareStatus = AUDIO_HW_SET_ROUTING;
544 err = mAudioHardware->setRouting(mode, r);
545 }
546 mHardwareStatus = AUDIO_HW_IDLE;
547 }
548 return err;
549}
550
551uint32_t AudioFlinger::getRouting(int mode) const
552{
553 uint32_t routes = 0;
554 if ((mode >= AudioSystem::MODE_CURRENT) && (mode < AudioSystem::NUM_MODES)) {
555 if (mode == AudioSystem::MODE_NORMAL ||
556 (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
557 routes = mSavedRoute;
558 } else {
559 mHardwareStatus = AUDIO_HW_GET_ROUTING;
560 mAudioHardware->getRouting(mode, &routes);
561 mHardwareStatus = AUDIO_HW_IDLE;
562 }
563 } else {
564 LOGW("Illegal value: getRouting(%d)", mode);
565 }
566 return routes;
567}
568
569status_t AudioFlinger::setMode(int mode)
570{
571 // check calling permissions
572 if (!settingsAllowed()) {
573 return PERMISSION_DENIED;
574 }
575 if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
576 LOGW("Illegal value: setMode(%d)", mode);
577 return BAD_VALUE;
578 }
579
580 AutoMutex lock(mHardwareLock);
581 mHardwareStatus = AUDIO_HW_SET_MODE;
582 status_t ret = mAudioHardware->setMode(mode);
583 mHardwareStatus = AUDIO_HW_IDLE;
584 return ret;
585}
586
587int AudioFlinger::getMode() const
588{
589 int mode = AudioSystem::MODE_INVALID;
590 mHardwareStatus = AUDIO_HW_SET_MODE;
591 mAudioHardware->getMode(&mode);
592 mHardwareStatus = AUDIO_HW_IDLE;
593 return mode;
594}
595
596status_t AudioFlinger::setMicMute(bool state)
597{
598 // check calling permissions
599 if (!settingsAllowed()) {
600 return PERMISSION_DENIED;
601 }
602
603 AutoMutex lock(mHardwareLock);
604 mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
605 status_t ret = mAudioHardware->setMicMute(state);
606 mHardwareStatus = AUDIO_HW_IDLE;
607 return ret;
608}
609
610bool AudioFlinger::getMicMute() const
611{
612 bool state = AudioSystem::MODE_INVALID;
613 mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
614 mAudioHardware->getMicMute(&state);
615 mHardwareStatus = AUDIO_HW_IDLE;
616 return state;
617}
618
619status_t AudioFlinger::setMasterMute(bool muted)
620{
621 // check calling permissions
622 if (!settingsAllowed()) {
623 return PERMISSION_DENIED;
624 }
625 mHardwareMixerThread->setMasterMute(muted);
626#ifdef WITH_A2DP
627 mA2dpMixerThread->setMasterMute(muted);
628#endif
629 return NO_ERROR;
630}
631
632float AudioFlinger::masterVolume() const
633{
634 return mHardwareMixerThread->masterVolume();
635}
636
637bool AudioFlinger::masterMute() const
638{
639 return mHardwareMixerThread->masterMute();
640}
641
642status_t AudioFlinger::setStreamVolume(int stream, float value)
643{
644 // check calling permissions
645 if (!settingsAllowed()) {
646 return PERMISSION_DENIED;
647 }
648
Eric Laurenteeea9222009-03-26 01:57:59 -0700649 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES ||
650 uint32_t(stream) == AudioSystem::ENFORCED_AUDIBLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 return BAD_VALUE;
652 }
653
654 mHardwareMixerThread->setStreamVolume(stream, value);
655#ifdef WITH_A2DP
656 mA2dpMixerThread->setStreamVolume(stream, value);
657#endif
658
659 status_t ret = NO_ERROR;
660 if (stream == AudioSystem::VOICE_CALL ||
661 stream == AudioSystem::BLUETOOTH_SCO) {
662
663 if (stream == AudioSystem::VOICE_CALL) {
664 value = (float)AudioSystem::logToLinear(value)/100.0f;
665 } else { // (type == AudioSystem::BLUETOOTH_SCO)
666 value = 1.0f;
667 }
668
669 AutoMutex lock(mHardwareLock);
670 mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
671 ret = mAudioHardware->setVoiceVolume(value);
672 mHardwareStatus = AUDIO_HW_IDLE;
673 }
674
675 return ret;
676}
677
678status_t AudioFlinger::setStreamMute(int stream, bool muted)
679{
680 // check calling permissions
681 if (!settingsAllowed()) {
682 return PERMISSION_DENIED;
683 }
684
Eric Laurenteeea9222009-03-26 01:57:59 -0700685 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES ||
686 uint32_t(stream) == AudioSystem::ENFORCED_AUDIBLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800687 return BAD_VALUE;
688 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690#ifdef WITH_A2DP
691 mA2dpMixerThread->setStreamMute(stream, muted);
692#endif
693 if (stream == AudioSystem::MUSIC)
694 {
695 AutoMutex lock(&mHardwareLock);
696 if (mForcedRoute != 0)
697 mMusicMuteSaved = muted;
698 else
699 mHardwareMixerThread->setStreamMute(stream, muted);
700 } else {
701 mHardwareMixerThread->setStreamMute(stream, muted);
702 }
703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 return NO_ERROR;
705}
706
707float AudioFlinger::streamVolume(int stream) const
708{
709 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
710 return 0.0f;
711 }
712 return mHardwareMixerThread->streamVolume(stream);
713}
714
715bool AudioFlinger::streamMute(int stream) const
716{
717 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
718 return true;
719 }
720
721 if (stream == AudioSystem::MUSIC && mForcedRoute != 0)
722 {
723 return mMusicMuteSaved;
724 }
725 return mHardwareMixerThread->streamMute(stream);
726}
727
728bool AudioFlinger::isMusicActive() const
729{
730 #ifdef WITH_A2DP
731 if (isA2dpEnabled()) {
732 return mA2dpMixerThread->isMusicActive();
733 }
734 #endif
735 return mHardwareMixerThread->isMusicActive();
736}
737
738status_t AudioFlinger::setParameter(const char* key, const char* value)
739{
740 status_t result, result2;
741 AutoMutex lock(mHardwareLock);
742 mHardwareStatus = AUDIO_SET_PARAMETER;
743
744 LOGV("setParameter() key %s, value %s, tid %d, calling tid %d", key, value, gettid(), IPCThreadState::self()->getCallingPid());
745 result = mAudioHardware->setParameter(key, value);
746 if (mA2dpAudioInterface) {
747 result2 = mA2dpAudioInterface->setParameter(key, value);
748 if (result2)
749 result = result2;
750 }
751 mHardwareStatus = AUDIO_HW_IDLE;
752 return result;
753}
754
755size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
756{
757 return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
758}
759
760void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
761{
762
763 LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
764 Mutex::Autolock _l(mLock);
765
766 sp<IBinder> binder = client->asBinder();
767 if (mNotificationClients.indexOf(binder) < 0) {
768 LOGV("Adding notification client %p", binder.get());
769 binder->linkToDeath(this);
770 mNotificationClients.add(binder);
771 client->a2dpEnabledChanged(isA2dpEnabled());
772 }
773}
774
775void AudioFlinger::binderDied(const wp<IBinder>& who) {
776
777 LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
778 Mutex::Autolock _l(mLock);
779
780 IBinder *binder = who.unsafe_get();
781
782 if (binder != NULL) {
783 int index = mNotificationClients.indexOf(binder);
784 if (index >= 0) {
785 LOGV("Removing notification client %p", binder);
786 mNotificationClients.removeAt(index);
787 }
788 }
789}
790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791void AudioFlinger::removeClient(pid_t pid)
792{
793 LOGV("removeClient() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
794 Mutex::Autolock _l(mLock);
795 mClients.removeItem(pid);
796}
797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798bool AudioFlinger::isA2dpEnabled() const
799{
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700800 return mA2dpEnabled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801}
802
803void AudioFlinger::handleForcedSpeakerRoute(int command)
804{
805 switch(command) {
806 case ACTIVE_TRACK_ADDED:
807 {
808 AutoMutex lock(mHardwareLock);
809 if (mForcedSpeakerCount++ == 0) {
810 mRouteRestoreTime = 0;
811 mMusicMuteSaved = mHardwareMixerThread->streamMute(AudioSystem::MUSIC);
812 if (mForcedRoute == 0 && !(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
813 LOGV("Route forced to Speaker ON %08x", mSavedRoute | AudioSystem::ROUTE_SPEAKER);
814 mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, true);
815 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
816 mAudioHardware->setMasterVolume(0);
817 usleep(mHardwareMixerThread->latency()*1000);
818 mHardwareStatus = AUDIO_HW_SET_ROUTING;
819 mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute | AudioSystem::ROUTE_SPEAKER);
820 mHardwareStatus = AUDIO_HW_IDLE;
821 // delay track start so that audio hardware has time to siwtch routes
822 usleep(kStartSleepTime);
823 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
824 mAudioHardware->setMasterVolume(mHardwareMixerThread->masterVolume());
825 mHardwareStatus = AUDIO_HW_IDLE;
826 }
827 mForcedRoute = AudioSystem::ROUTE_SPEAKER;
828 }
829 LOGV("mForcedSpeakerCount incremented to %d", mForcedSpeakerCount);
830 }
831 break;
832 case ACTIVE_TRACK_REMOVED:
833 {
834 AutoMutex lock(mHardwareLock);
835 if (mForcedSpeakerCount > 0){
836 if (--mForcedSpeakerCount == 0) {
837 mRouteRestoreTime = systemTime() + milliseconds(kStopSleepTime/1000);
838 }
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700839 LOGV("mForcedSpeakerCount decremented to %d", mForcedSpeakerCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840 } else {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700841 LOGE("mForcedSpeakerCount is already zero");
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -0700842 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 }
844 break;
845 case CHECK_ROUTE_RESTORE_TIME:
846 case FORCE_ROUTE_RESTORE:
847 if (mRouteRestoreTime) {
848 AutoMutex lock(mHardwareLock);
849 if (mRouteRestoreTime &&
850 (systemTime() > mRouteRestoreTime || command == FORCE_ROUTE_RESTORE)) {
851 mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, mMusicMuteSaved);
852 mForcedRoute = 0;
853 if (!(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
854 mHardwareStatus = AUDIO_HW_SET_ROUTING;
855 mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute);
856 mHardwareStatus = AUDIO_HW_IDLE;
857 LOGV("Route forced to Speaker OFF %08x", mSavedRoute);
858 }
859 mRouteRestoreTime = 0;
860 }
861 }
862 break;
863 }
864}
865
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700866#ifdef WITH_A2DP
The Android Open Source Project10592532009-03-18 17:39:46 -0700867// handleRouteDisablesA2dp_l() must be called with AudioFlinger::mLock held
868void AudioFlinger::handleRouteDisablesA2dp_l(int routes)
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700869{
The Android Open Source Project10592532009-03-18 17:39:46 -0700870 if (routes & AudioSystem::ROUTE_BLUETOOTH_SCO) {
871 if (mA2dpDisableCount++ == 0) {
872 if (mA2dpEnabled) {
873 setA2dpEnabled_l(false);
874 mA2dpSuppressed = true;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700875 }
876 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700877 LOGV("mA2dpDisableCount incremented to %d", mA2dpDisableCount);
878 } else {
879 if (mA2dpDisableCount > 0) {
880 if (--mA2dpDisableCount == 0) {
881 if (mA2dpSuppressed) {
882 setA2dpEnabled_l(true);
883 mA2dpSuppressed = false;
884 }
885 }
886 LOGV("mA2dpDisableCount decremented to %d", mA2dpDisableCount);
887 } else {
888 LOGE("mA2dpDisableCount is already zero");
889 }
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700890 }
891}
892#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893
894// ----------------------------------------------------------------------------
895
896AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType)
897 : Thread(false),
898 mAudioFlinger(audioFlinger), mAudioMixer(0), mOutput(output), mOutputType(outputType),
899 mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
900 mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
901 mInWrite(false)
902{
903 mSampleRate = output->sampleRate();
904 mChannelCount = output->channelCount();
905
906 // FIXME - Current mixer implementation only supports stereo output
907 if (mChannelCount == 1) {
908 LOGE("Invalid audio hardware channel count");
909 }
910
911 mFormat = output->format();
912 mFrameCount = output->bufferSize() / output->channelCount() / sizeof(int16_t);
913 mAudioMixer = new AudioMixer(mFrameCount, output->sampleRate());
914
915 // FIXME - Current mixer implementation only supports stereo output: Always
916 // Allocate a stereo buffer even if HW output is mono.
917 mMixBuffer = new int16_t[mFrameCount * 2];
918 memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
919}
920
921AudioFlinger::MixerThread::~MixerThread()
922{
923 delete [] mMixBuffer;
924 delete mAudioMixer;
925}
926
927status_t AudioFlinger::MixerThread::dump(int fd, const Vector<String16>& args)
928{
929 dumpInternals(fd, args);
930 dumpTracks(fd, args);
931 return NO_ERROR;
932}
933
934status_t AudioFlinger::MixerThread::dumpTracks(int fd, const Vector<String16>& args)
935{
936 const size_t SIZE = 256;
937 char buffer[SIZE];
938 String8 result;
939
940 snprintf(buffer, SIZE, "Output %d mixer thread tracks\n", mOutputType);
941 result.append(buffer);
942 result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
943 for (size_t i = 0; i < mTracks.size(); ++i) {
944 wp<Track> wTrack = mTracks[i];
945 if (wTrack != 0) {
946 sp<Track> track = wTrack.promote();
947 if (track != 0) {
948 track->dump(buffer, SIZE);
949 result.append(buffer);
950 }
951 }
952 }
953
954 snprintf(buffer, SIZE, "Output %d mixer thread active tracks\n", mOutputType);
955 result.append(buffer);
956 result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
957 for (size_t i = 0; i < mActiveTracks.size(); ++i) {
958 wp<Track> wTrack = mTracks[i];
959 if (wTrack != 0) {
960 sp<Track> track = wTrack.promote();
961 if (track != 0) {
962 track->dump(buffer, SIZE);
963 result.append(buffer);
964 }
965 }
966 }
967 write(fd, result.string(), result.size());
968 return NO_ERROR;
969}
970
971status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
972{
973 const size_t SIZE = 256;
974 char buffer[SIZE];
975 String8 result;
976
977 snprintf(buffer, SIZE, "Output %d mixer thread internals\n", mOutputType);
978 result.append(buffer);
979 snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
980 result.append(buffer);
981 snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
982 result.append(buffer);
983 snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
984 result.append(buffer);
985 snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
986 result.append(buffer);
987 snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
988 result.append(buffer);
989 snprintf(buffer, SIZE, "standby: %d\n", mStandby);
990 result.append(buffer);
991 write(fd, result.string(), result.size());
992 return NO_ERROR;
993}
994
995// Thread virtuals
996bool AudioFlinger::MixerThread::threadLoop()
997{
998 unsigned long sleepTime = kBufferRecoveryInUsecs;
999 int16_t* curBuf = mMixBuffer;
1000 Vector< sp<Track> > tracksToRemove;
1001 size_t enabledTracks = 0;
1002 nsecs_t standbyTime = systemTime();
1003 size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
1004 nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;
1005
1006#ifdef WITH_A2DP
1007 bool outputTrackActive = false;
1008#endif
1009
1010 do {
1011 enabledTracks = 0;
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001012 { // scope for the AudioFlinger::mLock
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001013
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001014 Mutex::Autolock _l(mAudioFlinger->mLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001015
1016#ifdef WITH_A2DP
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 if (mOutputTrack != NULL && !mAudioFlinger->isA2dpEnabled()) {
1018 if (outputTrackActive) {
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001019 mAudioFlinger->mLock.unlock();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 mOutputTrack->stop();
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001021 mAudioFlinger->mLock.lock();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022 outputTrackActive = false;
1023 }
1024 }
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001025 mAudioFlinger->checkA2dpEnabledChange_l();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001026#endif
1027
1028 const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
1029
1030 // put audio hardware into standby after short delay
1031 if UNLIKELY(!activeTracks.size() && systemTime() > standbyTime) {
1032 // wait until we have something to do...
1033 LOGV("Audio hardware entering standby, output %d\n", mOutputType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001034 if (!mStandby) {
1035 mOutput->standby();
1036 mStandby = true;
1037 }
1038
1039#ifdef WITH_A2DP
1040 if (outputTrackActive) {
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001041 mAudioFlinger->mLock.unlock();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001042 mOutputTrack->stop();
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001043 mAudioFlinger->mLock.lock();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 outputTrackActive = false;
1045 }
1046#endif
1047 if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
1048 mAudioFlinger->handleForcedSpeakerRoute(FORCE_ROUTE_RESTORE);
1049 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001050 // we're about to wait, flush the binder command buffer
1051 IPCThreadState::self()->flushCommands();
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001052 mAudioFlinger->mWaitWorkCV.wait(mAudioFlinger->mLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 LOGV("Audio hardware exiting standby, output %d\n", mOutputType);
1054
1055 if (mMasterMute == false) {
1056 char value[PROPERTY_VALUE_MAX];
1057 property_get("ro.audio.silent", value, "0");
1058 if (atoi(value)) {
1059 LOGD("Silence is golden");
1060 setMasterMute(true);
1061 }
1062 }
1063
1064 standbyTime = systemTime() + kStandbyTimeInNsecs;
1065 continue;
1066 }
1067
1068 // Forced route to speaker is handled by hardware mixer thread
1069 if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
1070 mAudioFlinger->handleForcedSpeakerRoute(CHECK_ROUTE_RESTORE_TIME);
1071 }
1072
1073 // find out which tracks need to be processed
1074 size_t count = activeTracks.size();
1075 for (size_t i=0 ; i<count ; i++) {
1076 sp<Track> t = activeTracks[i].promote();
1077 if (t == 0) continue;
1078
1079 Track* const track = t.get();
1080 audio_track_cblk_t* cblk = track->cblk();
1081
1082 // The first time a track is added we wait
1083 // for all its buffers to be filled before processing it
1084 mAudioMixer->setActiveTrack(track->name());
1085 if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
1086 !track->isPaused())
1087 {
1088 //LOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
1089
1090 // compute volume for this track
1091 int16_t left, right;
1092 if (track->isMuted() || mMasterMute || track->isPausing()) {
1093 left = right = 0;
1094 if (track->isPausing()) {
1095 LOGV("paused(%d)", track->name());
1096 track->setPaused();
1097 }
1098 } else {
1099 float typeVolume = mStreamTypes[track->type()].volume;
1100 float v = mMasterVolume * typeVolume;
1101 float v_clamped = v * cblk->volume[0];
1102 if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
1103 left = int16_t(v_clamped);
1104 v_clamped = v * cblk->volume[1];
1105 if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
1106 right = int16_t(v_clamped);
1107 }
1108
1109 // XXX: these things DON'T need to be done each time
1110 mAudioMixer->setBufferProvider(track);
1111 mAudioMixer->enable(AudioMixer::MIXING);
1112
1113 int param;
1114 if ( track->mFillingUpStatus == Track::FS_FILLED) {
1115 // no ramp for the first volume setting
1116 track->mFillingUpStatus = Track::FS_ACTIVE;
1117 if (track->mState == TrackBase::RESUMING) {
1118 track->mState = TrackBase::ACTIVE;
1119 param = AudioMixer::RAMP_VOLUME;
1120 } else {
1121 param = AudioMixer::VOLUME;
1122 }
1123 } else {
1124 param = AudioMixer::RAMP_VOLUME;
1125 }
1126 mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
1127 mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
1128 mAudioMixer->setParameter(
1129 AudioMixer::TRACK,
1130 AudioMixer::FORMAT, track->format());
1131 mAudioMixer->setParameter(
1132 AudioMixer::TRACK,
1133 AudioMixer::CHANNEL_COUNT, track->channelCount());
1134 mAudioMixer->setParameter(
1135 AudioMixer::RESAMPLE,
1136 AudioMixer::SAMPLE_RATE,
1137 int(cblk->sampleRate));
1138
1139 // reset retry count
1140 track->mRetryCount = kMaxTrackRetries;
1141 enabledTracks++;
1142 } else {
1143 //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
1144 if (track->isStopped()) {
1145 track->reset();
1146 }
1147 if (track->isTerminated() || track->isStopped() || track->isPaused()) {
1148 // We have consumed all the buffers of this track.
1149 // Remove it from the list of active tracks.
1150 LOGV("remove(%d) from active list", track->name());
1151 tracksToRemove.add(track);
1152 } else {
1153 // No buffers for this track. Give it a few chances to
1154 // fill a buffer, then remove it from active list.
1155 if (--(track->mRetryCount) <= 0) {
1156 LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
1157 tracksToRemove.add(track);
1158 }
1159 }
1160 // LOGV("disable(%d)", track->name());
1161 mAudioMixer->disable(AudioMixer::MIXING);
1162 }
1163 }
1164
1165 // remove all the tracks that need to be...
1166 count = tracksToRemove.size();
1167 if (UNLIKELY(count)) {
1168 for (size_t i=0 ; i<count ; i++) {
1169 const sp<Track>& track = tracksToRemove[i];
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001170 removeActiveTrack_l(track);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 if (track->isTerminated()) {
1172 mTracks.remove(track);
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001173 deleteTrackName_l(track->mName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001174 }
1175 }
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001176 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 }
1178
1179 if (LIKELY(enabledTracks)) {
1180 // mix buffers...
1181 mAudioMixer->process(curBuf);
1182
1183#ifdef WITH_A2DP
1184 if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
1185 if (!outputTrackActive) {
1186 LOGV("starting output track in mixer for output %d", mOutputType);
1187 mOutputTrack->start();
1188 outputTrackActive = true;
1189 }
1190 mOutputTrack->write(curBuf, mFrameCount);
1191 }
1192#endif
1193
1194 // output audio to hardware
1195 mLastWriteTime = systemTime();
1196 mInWrite = true;
1197 mOutput->write(curBuf, mixBufferSize);
1198 mNumWrites++;
1199 mInWrite = false;
1200 mStandby = false;
1201 nsecs_t temp = systemTime();
1202 standbyTime = temp + kStandbyTimeInNsecs;
1203 nsecs_t delta = temp - mLastWriteTime;
1204 if (delta > maxPeriod) {
1205 LOGW("write blocked for %llu msecs", ns2ms(delta));
1206 mNumDelayedWrites++;
1207 }
1208 sleepTime = kBufferRecoveryInUsecs;
1209 } else {
1210#ifdef WITH_A2DP
1211 if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
1212 if (outputTrackActive) {
1213 mOutputTrack->write(curBuf, 0);
1214 if (mOutputTrack->bufferQueueEmpty()) {
1215 mOutputTrack->stop();
1216 outputTrackActive = false;
1217 } else {
1218 standbyTime = systemTime() + kStandbyTimeInNsecs;
1219 }
1220 }
1221 }
1222#endif
1223 // There was nothing to mix this round, which means all
1224 // active tracks were late. Sleep a little bit to give
1225 // them another chance. If we're too late, the audio
1226 // hardware will zero-fill for us.
1227 //LOGV("no buffers - usleep(%lu)", sleepTime);
1228 usleep(sleepTime);
1229 if (sleepTime < kMaxBufferRecoveryInUsecs) {
1230 sleepTime += kBufferRecoveryInUsecs;
1231 }
1232 }
1233
1234 // finally let go of all our tracks, without the lock held
1235 // since we can't guarantee the destructors won't acquire that
1236 // same lock.
1237 tracksToRemove.clear();
1238 } while (true);
1239
1240 return false;
1241}
1242
1243status_t AudioFlinger::MixerThread::readyToRun()
1244{
1245 if (mSampleRate == 0) {
1246 LOGE("No working audio driver found.");
1247 return NO_INIT;
1248 }
1249 LOGI("AudioFlinger's thread ready to run for output %d", mOutputType);
1250 return NO_ERROR;
1251}
1252
1253void AudioFlinger::MixerThread::onFirstRef()
1254{
1255 const size_t SIZE = 256;
1256 char buffer[SIZE];
1257
1258 snprintf(buffer, SIZE, "Mixer Thread for output %d", mOutputType);
1259
1260 run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
1261}
1262
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001263// MixerThread::createTrack_l() must be called with AudioFlinger::mLock held
1264sp<AudioFlinger::MixerThread::Track> AudioFlinger::MixerThread::createTrack_l(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001265 const sp<AudioFlinger::Client>& client,
1266 int streamType,
1267 uint32_t sampleRate,
1268 int format,
1269 int channelCount,
1270 int frameCount,
1271 const sp<IMemory>& sharedBuffer,
1272 status_t *status)
1273{
1274 sp<Track> track;
1275 status_t lStatus;
1276
1277 // Resampler implementation limits input sampling rate to 2 x output sampling rate.
1278 if (sampleRate > MAX_SAMPLE_RATE || sampleRate > mSampleRate*2) {
1279 LOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
1280 lStatus = BAD_VALUE;
1281 goto Exit;
1282 }
1283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001285 if (mSampleRate == 0) {
1286 LOGE("Audio driver not initialized.");
1287 lStatus = NO_INIT;
1288 goto Exit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 }
1290
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001291 track = new Track(this, client, streamType, sampleRate, format,
1292 channelCount, frameCount, sharedBuffer);
1293 if (track->getCblk() == NULL) {
1294 lStatus = NO_MEMORY;
1295 goto Exit;
1296 }
1297 mTracks.add(track);
1298 lStatus = NO_ERROR;
1299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300Exit:
1301 if(status) {
1302 *status = lStatus;
1303 }
1304 return track;
1305}
1306
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001307// getTracks_l() must be called with AudioFlinger::mLock held
1308void AudioFlinger::MixerThread::getTracks_l(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 SortedVector < sp<Track> >& tracks,
1310 SortedVector < wp<Track> >& activeTracks)
1311{
1312 size_t size = mTracks.size();
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001313 LOGV ("MixerThread::getTracks_l() for output %d, mTracks.size %d, mActiveTracks.size %d", mOutputType, mTracks.size(), mActiveTracks.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 for (size_t i = 0; i < size; i++) {
1315 sp<Track> t = mTracks[i];
1316 if (AudioSystem::routedToA2dpOutput(t->mStreamType)) {
1317 tracks.add(t);
1318 int j = mActiveTracks.indexOf(t);
1319 if (j >= 0) {
1320 t = mActiveTracks[j].promote();
1321 if (t != NULL) {
1322 activeTracks.add(t);
1323 }
1324 }
1325 }
1326 }
1327
1328 size = activeTracks.size();
1329 for (size_t i = 0; i < size; i++) {
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001330 removeActiveTrack_l(activeTracks[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331 }
1332
1333 size = tracks.size();
1334 for (size_t i = 0; i < size; i++) {
1335 sp<Track> t = tracks[i];
1336 mTracks.remove(t);
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001337 deleteTrackName_l(t->name());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338 }
1339}
1340
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001341// putTracks_l() must be called with AudioFlinger::mLock held
1342void AudioFlinger::MixerThread::putTracks_l(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 SortedVector < sp<Track> >& tracks,
1344 SortedVector < wp<Track> >& activeTracks)
1345{
1346
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001347 LOGV ("MixerThread::putTracks_l() for output %d, tracks.size %d, activeTracks.size %d", mOutputType, tracks.size(), activeTracks.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348
1349 size_t size = tracks.size();
1350 for (size_t i = 0; i < size ; i++) {
1351 sp<Track> t = tracks[i];
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001352 int name = getTrackName_l();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353
1354 if (name < 0) return;
1355
1356 t->mName = name;
1357 t->mMixerThread = this;
1358 mTracks.add(t);
1359
1360 int j = activeTracks.indexOf(t);
1361 if (j >= 0) {
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001362 addActiveTrack_l(t);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001363 }
1364 }
1365}
1366
1367uint32_t AudioFlinger::MixerThread::sampleRate() const
1368{
1369 return mSampleRate;
1370}
1371
1372int AudioFlinger::MixerThread::channelCount() const
1373{
1374 return mChannelCount;
1375}
1376
1377int AudioFlinger::MixerThread::format() const
1378{
1379 return mFormat;
1380}
1381
1382size_t AudioFlinger::MixerThread::frameCount() const
1383{
1384 return mFrameCount;
1385}
1386
1387uint32_t AudioFlinger::MixerThread::latency() const
1388{
1389 if (mOutput) {
1390 return mOutput->latency();
1391 }
1392 else {
1393 return 0;
1394 }
1395}
1396
1397status_t AudioFlinger::MixerThread::setMasterVolume(float value)
1398{
1399 mMasterVolume = value;
1400 return NO_ERROR;
1401}
1402
1403status_t AudioFlinger::MixerThread::setMasterMute(bool muted)
1404{
1405 mMasterMute = muted;
1406 return NO_ERROR;
1407}
1408
1409float AudioFlinger::MixerThread::masterVolume() const
1410{
1411 return mMasterVolume;
1412}
1413
1414bool AudioFlinger::MixerThread::masterMute() const
1415{
1416 return mMasterMute;
1417}
1418
1419status_t AudioFlinger::MixerThread::setStreamVolume(int stream, float value)
1420{
1421 mStreamTypes[stream].volume = value;
1422 return NO_ERROR;
1423}
1424
1425status_t AudioFlinger::MixerThread::setStreamMute(int stream, bool muted)
1426{
1427 mStreamTypes[stream].mute = muted;
1428 return NO_ERROR;
1429}
1430
1431float AudioFlinger::MixerThread::streamVolume(int stream) const
1432{
1433 return mStreamTypes[stream].volume;
1434}
1435
1436bool AudioFlinger::MixerThread::streamMute(int stream) const
1437{
1438 return mStreamTypes[stream].mute;
1439}
1440
1441bool AudioFlinger::MixerThread::isMusicActive() const
1442{
1443 size_t count = mActiveTracks.size();
1444 for (size_t i = 0 ; i < count ; ++i) {
1445 sp<Track> t = mActiveTracks[i].promote();
1446 if (t == 0) continue;
1447 Track* const track = t.get();
1448 if (t->mStreamType == AudioSystem::MUSIC)
1449 return true;
1450 }
1451 return false;
1452}
1453
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001454// addTrack_l() must be called with AudioFlinger::mLock held
1455status_t AudioFlinger::MixerThread::addTrack_l(const sp<Track>& track)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456{
1457 status_t status = ALREADY_EXISTS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001458
1459 // here the track could be either new, or restarted
1460 // in both cases "unstop" the track
1461 if (track->isPaused()) {
1462 track->mState = TrackBase::RESUMING;
1463 LOGV("PAUSED => RESUMING (%d)", track->name());
1464 } else {
1465 track->mState = TrackBase::ACTIVE;
1466 LOGV("? => ACTIVE (%d)", track->name());
1467 }
1468 // set retry count for buffer fill
1469 track->mRetryCount = kMaxTrackStartupRetries;
1470 if (mActiveTracks.indexOf(track) < 0) {
1471 // the track is newly added, make sure it fills up all its
1472 // buffers before playing. This is to ensure the client will
1473 // effectively get the latency it requested.
1474 track->mFillingUpStatus = Track::FS_FILLING;
1475 track->mResetDone = false;
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001476 addActiveTrack_l(track);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477 status = NO_ERROR;
1478 }
1479
1480 LOGV("mWaitWorkCV.broadcast");
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001481 mAudioFlinger->mWaitWorkCV.broadcast();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482
1483 return status;
1484}
1485
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001486// removeTrack_l() must be called with AudioFlinger::mLock held
1487void AudioFlinger::MixerThread::removeTrack_l(wp<Track> track, int name)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001489 sp<Track> t = track.promote();
1490 if (t!=NULL && (t->mState <= TrackBase::STOPPED)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 t->reset();
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001492 deleteTrackName_l(name);
1493 removeActiveTrack_l(track);
1494 mAudioFlinger->mWaitWorkCV.broadcast();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496}
1497
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001498// destroyTrack_l() must be called with AudioFlinger::mLock held
1499void AudioFlinger::MixerThread::destroyTrack_l(const sp<Track>& track)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 track->mState = TrackBase::TERMINATED;
1502 if (mActiveTracks.indexOf(track) < 0) {
1503 LOGV("remove track (%d) and delete from mixer", track->name());
1504 mTracks.remove(track);
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001505 deleteTrackName_l(track->name());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 }
1507}
1508
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001509// addActiveTrack_l() must be called with AudioFlinger::mLock held
1510void AudioFlinger::MixerThread::addActiveTrack_l(const wp<Track>& t)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511{
1512 mActiveTracks.add(t);
1513
1514 // Force routing to speaker for certain stream types
1515 // The forced routing to speaker is managed by hardware mixer
1516 if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
1517 sp<Track> track = t.promote();
1518 if (track == NULL) return;
1519
1520 if (streamForcedToSpeaker(track->type())) {
1521 mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_ADDED);
1522 }
1523 }
1524}
1525
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001526// removeActiveTrack_l() must be called with AudioFlinger::mLock held
1527void AudioFlinger::MixerThread::removeActiveTrack_l(const wp<Track>& t)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528{
1529 mActiveTracks.remove(t);
1530
1531 // Force routing to speaker for certain stream types
1532 // The forced routing to speaker is managed by hardware mixer
1533 if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
1534 sp<Track> track = t.promote();
1535 if (track == NULL) return;
1536
1537 if (streamForcedToSpeaker(track->type())) {
1538 mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_REMOVED);
1539 }
1540 }
1541}
1542
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001543// getTrackName_l() must be called with AudioFlinger::mLock held
1544int AudioFlinger::MixerThread::getTrackName_l()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545{
1546 return mAudioMixer->getTrackName();
1547}
1548
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001549// deleteTrackName_l() must be called with AudioFlinger::mLock held
1550void AudioFlinger::MixerThread::deleteTrackName_l(int name)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551{
1552 mAudioMixer->deleteTrackName(name);
1553}
1554
1555size_t AudioFlinger::MixerThread::getOutputFrameCount()
1556{
1557 return mOutput->bufferSize() / mOutput->channelCount() / sizeof(int16_t);
1558}
1559
1560// ----------------------------------------------------------------------------
1561
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001562// TrackBase constructor must be called with AudioFlinger::mLock held
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563AudioFlinger::MixerThread::TrackBase::TrackBase(
1564 const sp<MixerThread>& mixerThread,
1565 const sp<Client>& client,
1566 int streamType,
1567 uint32_t sampleRate,
1568 int format,
1569 int channelCount,
1570 int frameCount,
1571 uint32_t flags,
1572 const sp<IMemory>& sharedBuffer)
1573 : RefBase(),
1574 mMixerThread(mixerThread),
1575 mClient(client),
1576 mStreamType(streamType),
1577 mFrameCount(0),
1578 mState(IDLE),
1579 mClientTid(-1),
1580 mFormat(format),
1581 mFlags(flags & ~SYSTEM_FLAGS_MASK)
1582{
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001583 mName = mixerThread->getTrackName_l();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001584 LOGV("TrackBase contructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
1585 if (mName < 0) {
1586 LOGE("no more track names availlable");
1587 return;
1588 }
1589
1590 LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
1591
1592 // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
1593 size_t size = sizeof(audio_track_cblk_t);
1594 size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
1595 if (sharedBuffer == 0) {
1596 size += bufferSize;
1597 }
1598
1599 if (client != NULL) {
1600 mCblkMemory = client->heap()->allocate(size);
1601 if (mCblkMemory != 0) {
1602 mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
1603 if (mCblk) { // construct the shared structure in-place.
1604 new(mCblk) audio_track_cblk_t();
1605 // clear all buffers
1606 mCblk->frameCount = frameCount;
The Android Open Source Project10592532009-03-18 17:39:46 -07001607 mCblk->sampleRate = (uint16_t)sampleRate;
1608 mCblk->channels = (uint16_t)channelCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001609 if (sharedBuffer == 0) {
1610 mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
1611 memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
1612 // Force underrun condition to avoid false underrun callback until first data is
1613 // written to buffer
1614 mCblk->flowControlFlag = 1;
1615 } else {
1616 mBuffer = sharedBuffer->pointer();
1617 }
1618 mBufferEnd = (uint8_t *)mBuffer + bufferSize;
1619 }
1620 } else {
1621 LOGE("not enough memory for AudioTrack size=%u", size);
1622 client->heap()->dump("AudioTrack");
1623 return;
1624 }
1625 } else {
1626 mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
1627 if (mCblk) { // construct the shared structure in-place.
1628 new(mCblk) audio_track_cblk_t();
1629 // clear all buffers
1630 mCblk->frameCount = frameCount;
The Android Open Source Project10592532009-03-18 17:39:46 -07001631 mCblk->sampleRate = (uint16_t)sampleRate;
1632 mCblk->channels = (uint16_t)channelCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001633 mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
1634 memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
1635 // Force underrun condition to avoid false underrun callback until first data is
1636 // written to buffer
1637 mCblk->flowControlFlag = 1;
1638 mBufferEnd = (uint8_t *)mBuffer + bufferSize;
1639 }
1640 }
1641}
1642
1643AudioFlinger::MixerThread::TrackBase::~TrackBase()
1644{
1645 if (mCblk) {
1646 mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
1647 }
1648 mCblkMemory.clear(); // and free the shared memory
1649 mClient.clear();
1650}
1651
1652void AudioFlinger::MixerThread::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
1653{
1654 buffer->raw = 0;
1655 mFrameCount = buffer->frameCount;
1656 step();
1657 buffer->frameCount = 0;
1658}
1659
1660bool AudioFlinger::MixerThread::TrackBase::step() {
1661 bool result;
1662 audio_track_cblk_t* cblk = this->cblk();
1663
1664 result = cblk->stepServer(mFrameCount);
1665 if (!result) {
1666 LOGV("stepServer failed acquiring cblk mutex");
1667 mFlags |= STEPSERVER_FAILED;
1668 }
1669 return result;
1670}
1671
1672void AudioFlinger::MixerThread::TrackBase::reset() {
1673 audio_track_cblk_t* cblk = this->cblk();
1674
1675 cblk->user = 0;
1676 cblk->server = 0;
1677 cblk->userBase = 0;
1678 cblk->serverBase = 0;
1679 mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
1680 LOGV("TrackBase::reset");
1681}
1682
1683sp<IMemory> AudioFlinger::MixerThread::TrackBase::getCblk() const
1684{
1685 return mCblkMemory;
1686}
1687
1688int AudioFlinger::MixerThread::TrackBase::sampleRate() const {
The Android Open Source Project10592532009-03-18 17:39:46 -07001689 return (int)mCblk->sampleRate;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001690}
1691
1692int AudioFlinger::MixerThread::TrackBase::channelCount() const {
1693 return mCblk->channels;
1694}
1695
1696void* AudioFlinger::MixerThread::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
1697 audio_track_cblk_t* cblk = this->cblk();
1698 int16_t *bufferStart = (int16_t *)mBuffer + (offset-cblk->serverBase)*cblk->channels;
1699 int16_t *bufferEnd = bufferStart + frames * cblk->channels;
1700
1701 // Check validity of returned pointer in case the track control block would have been corrupted.
The Android Open Source Project10592532009-03-18 17:39:46 -07001702 if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd ||
1703 cblk->channels == 2 && ((unsigned long)bufferStart & 3) ) {
1704 LOGE("TrackBase::getBuffer buffer out of range:\n start: %p, end %p , mBuffer %p mBufferEnd %p\n \
1705 server %d, serverBase %d, user %d, userBase %d, channels %d",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001706 bufferStart, bufferEnd, mBuffer, mBufferEnd,
The Android Open Source Project10592532009-03-18 17:39:46 -07001707 cblk->server, cblk->serverBase, cblk->user, cblk->userBase, cblk->channels);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001708 return 0;
1709 }
1710
1711 return bufferStart;
1712}
1713
1714// ----------------------------------------------------------------------------
1715
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001716// Track constructor must be called with AudioFlinger::mLock held
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001717AudioFlinger::MixerThread::Track::Track(
1718 const sp<MixerThread>& mixerThread,
1719 const sp<Client>& client,
1720 int streamType,
1721 uint32_t sampleRate,
1722 int format,
1723 int channelCount,
1724 int frameCount,
1725 const sp<IMemory>& sharedBuffer)
1726 : TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, 0, sharedBuffer)
1727{
1728 mVolume[0] = 1.0f;
1729 mVolume[1] = 1.0f;
1730 mMute = false;
1731 mSharedBuffer = sharedBuffer;
1732}
1733
1734AudioFlinger::MixerThread::Track::~Track()
1735{
1736 wp<Track> weak(this); // never create a strong ref from the dtor
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001737 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001738 mState = TERMINATED;
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001739 mMixerThread->removeTrack_l(weak, mName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001740}
1741
1742void AudioFlinger::MixerThread::Track::destroy()
1743{
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001744 // NOTE: destroyTrack_l() can remove a strong reference to this Track
1745 // by removing it from mTracks vector, so there is a risk that this Tracks's
1746 // desctructor is called. As the destructor needs to lock AudioFlinger::mLock,
1747 // we must acquire a strong reference on this Track before locking AudioFlinger::mLock
1748 // here so that the destructor is called only when exiting this function.
1749 // On the other hand, as long as Track::destroy() is only called by
1750 // TrackHandle destructor, the TrackHandle still holds a strong ref on
1751 // this Track with its member mTrack.
1752 sp<Track> keep(this);
1753 { // scope for AudioFlinger::mLock
1754 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
1755 mMixerThread->destroyTrack_l(this);
1756 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001757}
1758
1759void AudioFlinger::MixerThread::Track::dump(char* buffer, size_t size)
1760{
1761 snprintf(buffer, size, " %5d %5d %3u %3u %3u %3u %1d %1d %1d %5u %5u %5u %04x %04x\n",
1762 mName - AudioMixer::TRACK0,
1763 (mClient == NULL) ? getpid() : mClient->pid(),
1764 mStreamType,
1765 mFormat,
1766 mCblk->channels,
1767 mFrameCount,
1768 mState,
1769 mMute,
1770 mFillingUpStatus,
1771 mCblk->sampleRate,
1772 mCblk->volume[0],
1773 mCblk->volume[1],
1774 mCblk->server,
1775 mCblk->user);
1776}
1777
1778status_t AudioFlinger::MixerThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
1779{
1780 audio_track_cblk_t* cblk = this->cblk();
1781 uint32_t framesReady;
1782 uint32_t framesReq = buffer->frameCount;
1783
1784 // Check if last stepServer failed, try to step now
1785 if (mFlags & TrackBase::STEPSERVER_FAILED) {
1786 if (!step()) goto getNextBuffer_exit;
1787 LOGV("stepServer recovered");
1788 mFlags &= ~TrackBase::STEPSERVER_FAILED;
1789 }
1790
1791 framesReady = cblk->framesReady();
1792
1793 if (LIKELY(framesReady)) {
1794 uint32_t s = cblk->server;
1795 uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
1796
1797 bufferEnd = (cblk->loopEnd < bufferEnd) ? cblk->loopEnd : bufferEnd;
1798 if (framesReq > framesReady) {
1799 framesReq = framesReady;
1800 }
1801 if (s + framesReq > bufferEnd) {
1802 framesReq = bufferEnd - s;
1803 }
1804
1805 buffer->raw = getBuffer(s, framesReq);
1806 if (buffer->raw == 0) goto getNextBuffer_exit;
1807
1808 buffer->frameCount = framesReq;
1809 return NO_ERROR;
1810 }
1811
1812getNextBuffer_exit:
1813 buffer->raw = 0;
1814 buffer->frameCount = 0;
1815 return NOT_ENOUGH_DATA;
1816}
1817
1818bool AudioFlinger::MixerThread::Track::isReady() const {
1819 if (mFillingUpStatus != FS_FILLING) return true;
1820
1821 if (mCblk->framesReady() >= mCblk->frameCount ||
1822 mCblk->forceReady) {
1823 mFillingUpStatus = FS_FILLED;
1824 mCblk->forceReady = 0;
1825 LOGV("Track::isReady() track %d for output %d", mName, mMixerThread->mOutputType);
1826 return true;
1827 }
1828 return false;
1829}
1830
1831status_t AudioFlinger::MixerThread::Track::start()
1832{
1833 LOGV("start(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001834 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
1835 mMixerThread->addTrack_l(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001836 return NO_ERROR;
1837}
1838
1839void AudioFlinger::MixerThread::Track::stop()
1840{
1841 LOGV("stop(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001842 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001843 if (mState > STOPPED) {
1844 mState = STOPPED;
1845 // If the track is not active (PAUSED and buffers full), flush buffers
1846 if (mMixerThread->mActiveTracks.indexOf(this) < 0) {
1847 reset();
1848 }
1849 LOGV("(> STOPPED) => STOPPED (%d)", mName);
1850 }
1851}
1852
1853void AudioFlinger::MixerThread::Track::pause()
1854{
1855 LOGV("pause(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001856 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001857 if (mState == ACTIVE || mState == RESUMING) {
1858 mState = PAUSING;
1859 LOGV("ACTIVE/RESUMING => PAUSING (%d)", mName);
1860 }
1861}
1862
1863void AudioFlinger::MixerThread::Track::flush()
1864{
1865 LOGV("flush(%d)", mName);
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001866 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001867 if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
1868 return;
1869 }
1870 // No point remaining in PAUSED state after a flush => go to
1871 // STOPPED state
1872 mState = STOPPED;
1873
The Android Open Source Project10592532009-03-18 17:39:46 -07001874 mCblk->lock.lock();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001875 // NOTE: reset() will reset cblk->user and cblk->server with
1876 // the risk that at the same time, the AudioMixer is trying to read
1877 // data. In this case, getNextBuffer() would return a NULL pointer
1878 // as audio buffer => the AudioMixer code MUST always test that pointer
1879 // returned by getNextBuffer() is not NULL!
1880 reset();
The Android Open Source Project10592532009-03-18 17:39:46 -07001881 mCblk->lock.unlock();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001882}
1883
1884void AudioFlinger::MixerThread::Track::reset()
1885{
1886 // Do not reset twice to avoid discarding data written just after a flush and before
1887 // the audioflinger thread detects the track is stopped.
1888 if (!mResetDone) {
1889 TrackBase::reset();
1890 // Force underrun condition to avoid false underrun callback until first data is
1891 // written to buffer
1892 mCblk->flowControlFlag = 1;
1893 mCblk->forceReady = 0;
1894 mFillingUpStatus = FS_FILLING;
1895 mResetDone = true;
1896 }
1897}
1898
1899void AudioFlinger::MixerThread::Track::mute(bool muted)
1900{
1901 mMute = muted;
1902}
1903
1904void AudioFlinger::MixerThread::Track::setVolume(float left, float right)
1905{
1906 mVolume[0] = left;
1907 mVolume[1] = right;
1908}
1909
1910// ----------------------------------------------------------------------------
1911
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001912// RecordTrack constructor must be called with AudioFlinger::mLock held
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001913AudioFlinger::MixerThread::RecordTrack::RecordTrack(
1914 const sp<MixerThread>& mixerThread,
1915 const sp<Client>& client,
1916 int streamType,
1917 uint32_t sampleRate,
1918 int format,
1919 int channelCount,
1920 int frameCount,
1921 uint32_t flags)
1922 : TrackBase(mixerThread, client, streamType, sampleRate, format,
1923 channelCount, frameCount, flags, 0),
1924 mOverflow(false)
1925{
1926}
1927
1928AudioFlinger::MixerThread::RecordTrack::~RecordTrack()
1929{
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07001930 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
1931 mMixerThread->deleteTrackName_l(mName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001932}
1933
1934status_t AudioFlinger::MixerThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
1935{
1936 audio_track_cblk_t* cblk = this->cblk();
1937 uint32_t framesAvail;
1938 uint32_t framesReq = buffer->frameCount;
1939
1940 // Check if last stepServer failed, try to step now
1941 if (mFlags & TrackBase::STEPSERVER_FAILED) {
1942 if (!step()) goto getNextBuffer_exit;
1943 LOGV("stepServer recovered");
1944 mFlags &= ~TrackBase::STEPSERVER_FAILED;
1945 }
1946
1947 framesAvail = cblk->framesAvailable_l();
1948
1949 if (LIKELY(framesAvail)) {
1950 uint32_t s = cblk->server;
1951 uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
1952
1953 if (framesReq > framesAvail) {
1954 framesReq = framesAvail;
1955 }
1956 if (s + framesReq > bufferEnd) {
1957 framesReq = bufferEnd - s;
1958 }
1959
1960 buffer->raw = getBuffer(s, framesReq);
1961 if (buffer->raw == 0) goto getNextBuffer_exit;
1962
1963 buffer->frameCount = framesReq;
1964 return NO_ERROR;
1965 }
1966
1967getNextBuffer_exit:
1968 buffer->raw = 0;
1969 buffer->frameCount = 0;
1970 return NOT_ENOUGH_DATA;
1971}
1972
1973status_t AudioFlinger::MixerThread::RecordTrack::start()
1974{
1975 return mMixerThread->mAudioFlinger->startRecord(this);
1976}
1977
1978void AudioFlinger::MixerThread::RecordTrack::stop()
1979{
1980 mMixerThread->mAudioFlinger->stopRecord(this);
1981 TrackBase::reset();
1982 // Force overerrun condition to avoid false overrun callback until first data is
1983 // read from buffer
1984 mCblk->flowControlFlag = 1;
1985}
1986
1987
1988// ----------------------------------------------------------------------------
1989
1990AudioFlinger::MixerThread::OutputTrack::OutputTrack(
1991 const sp<MixerThread>& mixerThread,
1992 uint32_t sampleRate,
1993 int format,
1994 int channelCount,
1995 int frameCount)
1996 : Track(mixerThread, NULL, AudioSystem::SYSTEM, sampleRate, format, channelCount, frameCount, NULL),
1997 mOutputMixerThread(mixerThread)
1998{
1999
2000 mCblk->out = 1;
2001 mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
2002 mCblk->volume[0] = mCblk->volume[1] = 0x1000;
2003 mOutBuffer.frameCount = 0;
2004 mCblk->bufferTimeoutMs = 10;
2005
2006 LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p",
2007 mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd);
2008
2009}
2010
2011AudioFlinger::MixerThread::OutputTrack::~OutputTrack()
2012{
2013 stop();
2014}
2015
2016status_t AudioFlinger::MixerThread::OutputTrack::start()
2017{
2018 status_t status = Track::start();
2019
2020 mRetryCount = 127;
2021 return status;
2022}
2023
2024void AudioFlinger::MixerThread::OutputTrack::stop()
2025{
2026 Track::stop();
2027 clearBufferQueue();
2028 mOutBuffer.frameCount = 0;
2029}
2030
2031void AudioFlinger::MixerThread::OutputTrack::write(int16_t* data, uint32_t frames)
2032{
2033 Buffer *pInBuffer;
2034 Buffer inBuffer;
2035 uint32_t channels = mCblk->channels;
2036
2037 inBuffer.frameCount = frames;
2038 inBuffer.i16 = data;
2039
2040 if (mCblk->user == 0) {
2041 if (mOutputMixerThread->isMusicActive()) {
2042 mCblk->forceReady = 1;
2043 LOGV("OutputTrack::start() force ready");
2044 } else if (mCblk->frameCount > frames){
2045 if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
2046 uint32_t startFrames = (mCblk->frameCount - frames);
2047 LOGV("OutputTrack::start() write %d frames", startFrames);
2048 pInBuffer = new Buffer;
2049 pInBuffer->mBuffer = new int16_t[startFrames * channels];
2050 pInBuffer->frameCount = startFrames;
2051 pInBuffer->i16 = pInBuffer->mBuffer;
2052 memset(pInBuffer->raw, 0, startFrames * channels * sizeof(int16_t));
2053 mBufferQueue.add(pInBuffer);
2054 } else {
2055 LOGW ("OutputTrack::write() no more buffers");
2056 }
2057 }
2058 }
2059
2060 while (1) {
2061 // First write pending buffers, then new data
2062 if (mBufferQueue.size()) {
2063 pInBuffer = mBufferQueue.itemAt(0);
2064 } else {
2065 pInBuffer = &inBuffer;
2066 }
2067
2068 if (pInBuffer->frameCount == 0) {
2069 break;
2070 }
2071
2072 if (mOutBuffer.frameCount == 0) {
2073 mOutBuffer.frameCount = pInBuffer->frameCount;
2074 if (obtainBuffer(&mOutBuffer) == (status_t)AudioTrack::NO_MORE_BUFFERS) {
2075 break;
2076 }
2077 }
2078
2079 uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : pInBuffer->frameCount;
2080 memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channels * sizeof(int16_t));
2081 mCblk->stepUser(outFrames);
2082 pInBuffer->frameCount -= outFrames;
2083 pInBuffer->i16 += outFrames * channels;
2084 mOutBuffer.frameCount -= outFrames;
2085 mOutBuffer.i16 += outFrames * channels;
2086
2087 if (pInBuffer->frameCount == 0) {
2088 if (mBufferQueue.size()) {
2089 mBufferQueue.removeAt(0);
2090 delete [] pInBuffer->mBuffer;
2091 delete pInBuffer;
2092 } else {
2093 break;
2094 }
2095 }
2096 }
2097
2098 // If we could not write all frames, allocate a buffer and queue it for next time.
2099 if (inBuffer.frameCount) {
2100 if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
2101 pInBuffer = new Buffer;
2102 pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channels];
2103 pInBuffer->frameCount = inBuffer.frameCount;
2104 pInBuffer->i16 = pInBuffer->mBuffer;
2105 memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channels * sizeof(int16_t));
2106 mBufferQueue.add(pInBuffer);
2107 } else {
2108 LOGW("OutputTrack::write() no more buffers");
2109 }
2110 }
2111
2112 // Calling write() with a 0 length buffer, means that no more data will be written:
2113 // If no more buffers are pending, fill output track buffer to make sure it is started
2114 // by output mixer.
2115 if (frames == 0 && mBufferQueue.size() == 0 && mCblk->user < mCblk->frameCount) {
2116 frames = mCblk->frameCount - mCblk->user;
2117 pInBuffer = new Buffer;
2118 pInBuffer->mBuffer = new int16_t[frames * channels];
2119 pInBuffer->frameCount = frames;
2120 pInBuffer->i16 = pInBuffer->mBuffer;
2121 memset(pInBuffer->raw, 0, frames * channels * sizeof(int16_t));
2122 mBufferQueue.add(pInBuffer);
2123 }
2124
2125}
2126
2127status_t AudioFlinger::MixerThread::OutputTrack::obtainBuffer(AudioBufferProvider::Buffer* buffer)
2128{
2129 int active;
2130 int timeout = 0;
2131 status_t result;
2132 audio_track_cblk_t* cblk = mCblk;
2133 uint32_t framesReq = buffer->frameCount;
2134
2135 LOGV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
2136 buffer->frameCount = 0;
2137
2138 uint32_t framesAvail = cblk->framesAvailable();
2139
2140 if (framesAvail == 0) {
2141 return AudioTrack::NO_MORE_BUFFERS;
2142 }
2143
2144 if (framesReq > framesAvail) {
2145 framesReq = framesAvail;
2146 }
2147
2148 uint32_t u = cblk->user;
2149 uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
2150
2151 if (u + framesReq > bufferEnd) {
2152 framesReq = bufferEnd - u;
2153 }
2154
2155 buffer->frameCount = framesReq;
2156 buffer->raw = (void *)cblk->buffer(u);
2157 return NO_ERROR;
2158}
2159
2160
2161void AudioFlinger::MixerThread::OutputTrack::clearBufferQueue()
2162{
2163 size_t size = mBufferQueue.size();
2164 Buffer *pBuffer;
2165
2166 for (size_t i = 0; i < size; i++) {
2167 pBuffer = mBufferQueue.itemAt(i);
2168 delete [] pBuffer->mBuffer;
2169 delete pBuffer;
2170 }
2171 mBufferQueue.clear();
2172}
2173
2174// ----------------------------------------------------------------------------
2175
2176AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
2177 : RefBase(),
2178 mAudioFlinger(audioFlinger),
2179 mMemoryDealer(new MemoryDealer(1024*1024)),
2180 mPid(pid)
2181{
2182 // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
2183}
2184
2185AudioFlinger::Client::~Client()
2186{
2187 mAudioFlinger->removeClient(mPid);
2188}
2189
2190const sp<MemoryDealer>& AudioFlinger::Client::heap() const
2191{
2192 return mMemoryDealer;
2193}
2194
2195// ----------------------------------------------------------------------------
2196
2197AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::MixerThread::Track>& track)
2198 : BnAudioTrack(),
2199 mTrack(track)
2200{
2201}
2202
2203AudioFlinger::TrackHandle::~TrackHandle() {
2204 // just stop the track on deletion, associated resources
2205 // will be freed from the main thread once all pending buffers have
2206 // been played. Unless it's not in the active track list, in which
2207 // case we free everything now...
2208 mTrack->destroy();
2209}
2210
2211status_t AudioFlinger::TrackHandle::start() {
2212 return mTrack->start();
2213}
2214
2215void AudioFlinger::TrackHandle::stop() {
2216 mTrack->stop();
2217}
2218
2219void AudioFlinger::TrackHandle::flush() {
2220 mTrack->flush();
2221}
2222
2223void AudioFlinger::TrackHandle::mute(bool e) {
2224 mTrack->mute(e);
2225}
2226
2227void AudioFlinger::TrackHandle::pause() {
2228 mTrack->pause();
2229}
2230
2231void AudioFlinger::TrackHandle::setVolume(float left, float right) {
2232 mTrack->setVolume(left, right);
2233}
2234
2235sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
2236 return mTrack->getCblk();
2237}
2238
2239status_t AudioFlinger::TrackHandle::onTransact(
2240 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2241{
2242 return BnAudioTrack::onTransact(code, data, reply, flags);
2243}
2244
2245// ----------------------------------------------------------------------------
2246
2247sp<IAudioRecord> AudioFlinger::openRecord(
2248 pid_t pid,
2249 int streamType,
2250 uint32_t sampleRate,
2251 int format,
2252 int channelCount,
2253 int frameCount,
2254 uint32_t flags,
2255 status_t *status)
2256{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002257 sp<MixerThread::RecordTrack> recordTrack;
2258 sp<RecordHandle> recordHandle;
2259 sp<Client> client;
2260 wp<Client> wclient;
2261 AudioStreamIn* input = 0;
2262 int inFrameCount;
2263 size_t inputBufferSize;
2264 status_t lStatus;
2265
2266 // check calling permissions
2267 if (!recordingAllowed()) {
2268 lStatus = PERMISSION_DENIED;
2269 goto Exit;
2270 }
2271
2272 if (uint32_t(streamType) >= AudioRecord::NUM_STREAM_TYPES) {
2273 LOGE("invalid stream type");
2274 lStatus = BAD_VALUE;
2275 goto Exit;
2276 }
2277
2278 if (sampleRate > MAX_SAMPLE_RATE) {
2279 LOGE("Sample rate out of range");
2280 lStatus = BAD_VALUE;
2281 goto Exit;
2282 }
2283
2284 if (mAudioRecordThread == 0) {
2285 LOGE("Audio record thread not started");
2286 lStatus = NO_INIT;
2287 goto Exit;
2288 }
2289
2290
2291 // Check that audio input stream accepts requested audio parameters
2292 inputBufferSize = mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
2293 if (inputBufferSize == 0) {
2294 lStatus = BAD_VALUE;
2295 LOGE("Bad audio input parameters: sampling rate %u, format %d, channels %d", sampleRate, format, channelCount);
2296 goto Exit;
2297 }
2298
2299 // add client to list
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07002300 { // scope for mLock
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002301 Mutex::Autolock _l(mLock);
2302 wclient = mClients.valueFor(pid);
2303 if (wclient != NULL) {
2304 client = wclient.promote();
2305 } else {
2306 client = new Client(this, pid);
2307 mClients.add(pid, client);
2308 }
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07002309
2310 // frameCount must be a multiple of input buffer size
2311 inFrameCount = inputBufferSize/channelCount/sizeof(short);
2312 frameCount = ((frameCount - 1)/inFrameCount + 1) * inFrameCount;
2313
2314 // create new record track. The record track uses one track in mHardwareMixerThread by convention.
2315 recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, streamType, sampleRate,
2316 format, channelCount, frameCount, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002318 if (recordTrack->getCblk() == NULL) {
2319 recordTrack.clear();
2320 lStatus = NO_MEMORY;
2321 goto Exit;
2322 }
2323
2324 // return to handle to client
2325 recordHandle = new RecordHandle(recordTrack);
2326 lStatus = NO_ERROR;
2327
2328Exit:
2329 if (status) {
2330 *status = lStatus;
2331 }
2332 return recordHandle;
2333}
2334
2335status_t AudioFlinger::startRecord(MixerThread::RecordTrack* recordTrack) {
2336 if (mAudioRecordThread != 0) {
2337 return mAudioRecordThread->start(recordTrack);
2338 }
2339 return NO_INIT;
2340}
2341
2342void AudioFlinger::stopRecord(MixerThread::RecordTrack* recordTrack) {
2343 if (mAudioRecordThread != 0) {
2344 mAudioRecordThread->stop(recordTrack);
2345 }
2346}
2347
2348// ----------------------------------------------------------------------------
2349
2350AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::MixerThread::RecordTrack>& recordTrack)
2351 : BnAudioRecord(),
2352 mRecordTrack(recordTrack)
2353{
2354}
2355
2356AudioFlinger::RecordHandle::~RecordHandle() {
2357 stop();
2358}
2359
2360status_t AudioFlinger::RecordHandle::start() {
2361 LOGV("RecordHandle::start()");
2362 return mRecordTrack->start();
2363}
2364
2365void AudioFlinger::RecordHandle::stop() {
2366 LOGV("RecordHandle::stop()");
2367 mRecordTrack->stop();
2368}
2369
2370sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
2371 return mRecordTrack->getCblk();
2372}
2373
2374status_t AudioFlinger::RecordHandle::onTransact(
2375 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2376{
2377 return BnAudioRecord::onTransact(code, data, reply, flags);
2378}
2379
2380// ----------------------------------------------------------------------------
2381
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002382AudioFlinger::AudioRecordThread::AudioRecordThread(AudioHardwareInterface* audioHardware,
2383 const sp<AudioFlinger>& audioFlinger) :
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 mAudioHardware(audioHardware),
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002385 mAudioFlinger(audioFlinger),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 mActive(false)
2387{
2388}
2389
2390AudioFlinger::AudioRecordThread::~AudioRecordThread()
2391{
2392}
2393
2394bool AudioFlinger::AudioRecordThread::threadLoop()
2395{
2396 LOGV("AudioRecordThread: start record loop");
2397 AudioBufferProvider::Buffer buffer;
2398 int inBufferSize = 0;
2399 int inFrameCount = 0;
2400 AudioStreamIn* input = 0;
2401
2402 mActive = 0;
2403
2404 // start recording
2405 while (!exitPending()) {
2406 if (!mActive) {
2407 mLock.lock();
2408 if (!mActive && !exitPending()) {
2409 LOGV("AudioRecordThread: loop stopping");
2410 if (input) {
2411 delete input;
2412 input = 0;
2413 }
2414 mRecordTrack.clear();
2415 mStopped.signal();
2416
2417 mWaitWorkCV.wait(mLock);
2418
2419 LOGV("AudioRecordThread: loop starting");
2420 if (mRecordTrack != 0) {
2421 input = mAudioHardware->openInputStream(mRecordTrack->format(),
2422 mRecordTrack->channelCount(),
2423 mRecordTrack->sampleRate(),
2424 &mStartStatus,
2425 (AudioSystem::audio_in_acoustics)(mRecordTrack->mFlags >> 16));
2426 if (input != 0) {
2427 inBufferSize = input->bufferSize();
2428 inFrameCount = inBufferSize/input->frameSize();
2429 }
2430 } else {
2431 mStartStatus = NO_INIT;
2432 }
2433 if (mStartStatus !=NO_ERROR) {
2434 LOGW("record start failed, status %d", mStartStatus);
2435 mActive = false;
2436 mRecordTrack.clear();
2437 }
2438 mWaitWorkCV.signal();
2439 }
2440 mLock.unlock();
2441 } else if (mRecordTrack != 0) {
2442
2443 buffer.frameCount = inFrameCount;
The Android Open Source Projectb2a3dd82009-03-09 11:52:12 -07002444 if (LIKELY(mRecordTrack->getNextBuffer(&buffer) == NO_ERROR &&
2445 (int)buffer.frameCount == inFrameCount)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002446 LOGV("AudioRecordThread read: %d frames", buffer.frameCount);
2447 ssize_t bytesRead = input->read(buffer.raw, inBufferSize);
2448 if (bytesRead < 0) {
2449 LOGE("Error reading audio input");
2450 sleep(1);
2451 }
2452 mRecordTrack->releaseBuffer(&buffer);
2453 mRecordTrack->overflow();
2454 }
2455
2456 // client isn't retrieving buffers fast enough
2457 else {
2458 if (!mRecordTrack->setOverflow())
2459 LOGW("AudioRecordThread: buffer overflow");
2460 // Release the processor for a while before asking for a new buffer.
2461 // This will give the application more chance to read from the buffer and
2462 // clear the overflow.
2463 usleep(5000);
2464 }
2465 }
2466 }
2467
2468
2469 if (input) {
2470 delete input;
2471 }
2472 mRecordTrack.clear();
2473
2474 return false;
2475}
2476
2477status_t AudioFlinger::AudioRecordThread::start(MixerThread::RecordTrack* recordTrack)
2478{
2479 LOGV("AudioRecordThread::start");
2480 AutoMutex lock(&mLock);
2481 mActive = true;
2482 // If starting the active track, just reset mActive in case a stop
2483 // was pending and exit
2484 if (recordTrack == mRecordTrack.get()) return NO_ERROR;
2485
2486 if (mRecordTrack != 0) return -EBUSY;
2487
2488 mRecordTrack = recordTrack;
2489
2490 // signal thread to start
2491 LOGV("Signal record thread");
2492 mWaitWorkCV.signal();
2493 mWaitWorkCV.wait(mLock);
2494 LOGV("Record started, status %d", mStartStatus);
2495 return mStartStatus;
2496}
2497
2498void AudioFlinger::AudioRecordThread::stop(MixerThread::RecordTrack* recordTrack) {
2499 LOGV("AudioRecordThread::stop");
2500 AutoMutex lock(&mLock);
2501 if (mActive && (recordTrack == mRecordTrack.get())) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002502 mActive = false;
2503 mStopped.wait(mLock);
2504 }
2505}
2506
2507void AudioFlinger::AudioRecordThread::exit()
2508{
2509 LOGV("AudioRecordThread::exit");
2510 {
2511 AutoMutex lock(&mLock);
2512 requestExit();
2513 mWaitWorkCV.signal();
2514 }
2515 requestExitAndWait();
2516}
2517
2518status_t AudioFlinger::AudioRecordThread::dump(int fd, const Vector<String16>& args)
2519{
2520 const size_t SIZE = 256;
2521 char buffer[SIZE];
2522 String8 result;
2523 pid_t pid = 0;
2524
2525 if (mRecordTrack != 0 && mRecordTrack->mClient != 0) {
2526 snprintf(buffer, SIZE, "Record client pid: %d\n", mRecordTrack->mClient->pid());
2527 result.append(buffer);
2528 } else {
2529 result.append("No record client\n");
2530 }
2531 write(fd, result.string(), result.size());
2532 return NO_ERROR;
2533}
2534
2535status_t AudioFlinger::onTransact(
2536 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2537{
2538 return BnAudioFlinger::onTransact(code, data, reply, flags);
2539}
2540
2541// ----------------------------------------------------------------------------
2542void AudioFlinger::instantiate() {
2543 defaultServiceManager()->addService(
2544 String16("media.audio_flinger"), new AudioFlinger());
2545}
2546
2547}; // namespace android