blob: 9ba7f90f956e01db473f5ef77e1040a3fd3f0324 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-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 Project4f68be12009-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 Projectedbf3b62009-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 Project22f8def2009-03-09 11:52:12 -070077static const int kDumpLockRetries = 50;
78static const int kDumpLockSleep = 20000;
79
The Android Open Source Projectedbf3b62009-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 Project22f8def2009-03-09 11:52:12 -0700124 mAudioHardware(0), mA2dpAudioInterface(0), mA2dpEnabled(false), mNotifyA2dpChange(false),
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700125 mForcedSpeakerCount(0), mA2dpDisableCount(0), mA2dpSuppressed(false), mForcedRoute(0),
126 mRouteRestoreTime(0), mMusicMuteSaved(false)
The Android Open Source Projectedbf3b62009-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 Projectbcef13b2009-03-11 12:11:56 -0700173 mAudioRecordThread = new AudioRecordThread(mAudioHardware, this);
The Android Open Source Projectedbf3b62009-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 Project22f8def2009-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 Project4f68be12009-03-18 17:39:46 -0700201{
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700202 SortedVector < sp<MixerThread::Track> > tracks;
203 SortedVector < wp<MixerThread::Track> > activeTracks;
204
The Android Open Source Projectedbf3b62009-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 Project22f8def2009-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 Projectedbf3b62009-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 ||
246 streamType == AudioSystem::NOTIFICATION);
247}
248
249status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
250{
251 const size_t SIZE = 256;
252 char buffer[SIZE];
253 String8 result;
254
255 result.append("Clients:\n");
256 for (size_t i = 0; i < mClients.size(); ++i) {
257 wp<Client> wClient = mClients.valueAt(i);
258 if (wClient != 0) {
259 sp<Client> client = wClient.promote();
260 if (client != 0) {
261 snprintf(buffer, SIZE, " pid: %d\n", client->pid());
262 result.append(buffer);
263 }
264 }
265 }
266 write(fd, result.string(), result.size());
267 return NO_ERROR;
268}
269
270
271status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
272{
273 const size_t SIZE = 256;
274 char buffer[SIZE];
275 String8 result;
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700276 int hardwareStatus = mHardwareStatus;
277
278 if (hardwareStatus == AUDIO_HW_IDLE && mHardwareMixerThread->mStandby) {
279 hardwareStatus = AUDIO_HW_STANDBY;
280 }
281 snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800282 result.append(buffer);
283 write(fd, result.string(), result.size());
284 return NO_ERROR;
285}
286
287status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
288{
289 const size_t SIZE = 256;
290 char buffer[SIZE];
291 String8 result;
292 snprintf(buffer, SIZE, "Permission Denial: "
293 "can't dump AudioFlinger from pid=%d, uid=%d\n",
294 IPCThreadState::self()->getCallingPid(),
295 IPCThreadState::self()->getCallingUid());
296 result.append(buffer);
297 write(fd, result.string(), result.size());
298 return NO_ERROR;
299}
300
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700301static bool tryLock(Mutex& mutex)
302{
303 bool locked = false;
304 for (int i = 0; i < kDumpLockRetries; ++i) {
305 if (mutex.tryLock() == NO_ERROR) {
306 locked = true;
307 break;
308 }
309 usleep(kDumpLockSleep);
310 }
311 return locked;
312}
313
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800314status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
315{
316 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
317 dumpPermissionDenial(fd, args);
318 } else {
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700319 // get state of hardware lock
320 bool hardwareLocked = tryLock(mHardwareLock);
321 if (!hardwareLocked) {
322 String8 result(kHardwareLockedString);
323 write(fd, result.string(), result.size());
324 } else {
325 mHardwareLock.unlock();
326 }
327
328 bool locked = tryLock(mLock);
329
330 // failed to lock - AudioFlinger is probably deadlocked
331 if (!locked) {
332 String8 result(kDeadlockedString);
333 write(fd, result.string(), result.size());
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700334 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800335
336 dumpClients(fd, args);
337 dumpInternals(fd, args);
338 mHardwareMixerThread->dump(fd, args);
339#ifdef WITH_A2DP
340 mA2dpMixerThread->dump(fd, args);
341#endif
342
343 // dump record client
344 if (mAudioRecordThread != 0) mAudioRecordThread->dump(fd, args);
345
346 if (mAudioHardware) {
347 mAudioHardware->dumpState(fd, args);
348 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700349 if (locked) mLock.unlock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800350 }
351 return NO_ERROR;
352}
353
354// IAudioFlinger interface
355
356
357sp<IAudioTrack> AudioFlinger::createTrack(
358 pid_t pid,
359 int streamType,
360 uint32_t sampleRate,
361 int format,
362 int channelCount,
363 int frameCount,
364 uint32_t flags,
365 const sp<IMemory>& sharedBuffer,
366 status_t *status)
367{
368 sp<MixerThread::Track> track;
369 sp<TrackHandle> trackHandle;
370 sp<Client> client;
371 wp<Client> wclient;
372 status_t lStatus;
373
374 if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
375 LOGE("invalid stream type");
376 lStatus = BAD_VALUE;
377 goto Exit;
378 }
379
380 {
381 Mutex::Autolock _l(mLock);
382
383 wclient = mClients.valueFor(pid);
384
385 if (wclient != NULL) {
386 client = wclient.promote();
387 } else {
388 client = new Client(this, pid);
389 mClients.add(pid, client);
390 }
391#ifdef WITH_A2DP
392 if (isA2dpEnabled() && AudioSystem::routedToA2dpOutput(streamType)) {
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700393 track = mA2dpMixerThread->createTrack_l(client, streamType, sampleRate, format,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800394 channelCount, frameCount, sharedBuffer, &lStatus);
395 } else
396#endif
397 {
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700398 track = mHardwareMixerThread->createTrack_l(client, streamType, sampleRate, format,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800399 channelCount, frameCount, sharedBuffer, &lStatus);
400 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700401 }
402 if (lStatus == NO_ERROR) {
403 trackHandle = new TrackHandle(track);
404 } else {
405 track.clear();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800406 }
407
408Exit:
409 if(status) {
410 *status = lStatus;
411 }
412 return trackHandle;
413}
414
415uint32_t AudioFlinger::sampleRate(int output) const
416{
417#ifdef WITH_A2DP
418 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
419 return mA2dpMixerThread->sampleRate();
420 }
421#endif
422 return mHardwareMixerThread->sampleRate();
423}
424
425int AudioFlinger::channelCount(int output) const
426{
427#ifdef WITH_A2DP
428 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
429 return mA2dpMixerThread->channelCount();
430 }
431#endif
432 return mHardwareMixerThread->channelCount();
433}
434
435int AudioFlinger::format(int output) const
436{
437#ifdef WITH_A2DP
438 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
439 return mA2dpMixerThread->format();
440 }
441#endif
442 return mHardwareMixerThread->format();
443}
444
445size_t AudioFlinger::frameCount(int output) const
446{
447#ifdef WITH_A2DP
448 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
449 return mA2dpMixerThread->frameCount();
450 }
451#endif
452 return mHardwareMixerThread->frameCount();
453}
454
455uint32_t AudioFlinger::latency(int output) const
456{
457#ifdef WITH_A2DP
458 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
459 return mA2dpMixerThread->latency();
460 }
461#endif
462 return mHardwareMixerThread->latency();
463}
464
465status_t AudioFlinger::setMasterVolume(float value)
466{
467 // check calling permissions
468 if (!settingsAllowed()) {
469 return PERMISSION_DENIED;
470 }
471
472 // when hw supports master volume, don't scale in sw mixer
473 AutoMutex lock(mHardwareLock);
474 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
475 if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
476 value = 1.0f;
477 }
478 mHardwareStatus = AUDIO_HW_IDLE;
479 mHardwareMixerThread->setMasterVolume(value);
480#ifdef WITH_A2DP
481 mA2dpMixerThread->setMasterVolume(value);
482#endif
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700483
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800484 return NO_ERROR;
485}
486
487status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
488{
489 status_t err = NO_ERROR;
490
491 // check calling permissions
492 if (!settingsAllowed()) {
493 return PERMISSION_DENIED;
494 }
495 if ((mode < AudioSystem::MODE_CURRENT) || (mode >= AudioSystem::NUM_MODES)) {
496 LOGW("Illegal value: setRouting(%d, %u, %u)", mode, routes, mask);
497 return BAD_VALUE;
498 }
499
500#ifdef WITH_A2DP
501 LOGD("setRouting %d %d %d, tid %d, calling tid %d\n", mode, routes, mask, gettid(), IPCThreadState::self()->getCallingPid());
502 if (mode == AudioSystem::MODE_NORMAL &&
503 (mask & AudioSystem::ROUTE_BLUETOOTH_A2DP)) {
504 AutoMutex lock(&mLock);
505
506 bool enableA2dp = false;
507 if (routes & AudioSystem::ROUTE_BLUETOOTH_A2DP) {
508 enableA2dp = true;
509 }
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700510 if (mA2dpDisableCount > 0) {
511 mA2dpSuppressed = enableA2dp;
512 } else {
513 setA2dpEnabled_l(enableA2dp);
514 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800515 LOGV("setOutput done\n");
516 }
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700517 // setRouting() is always called at least for mode == AudioSystem::MODE_IN_CALL when
518 // SCO is enabled, whatever current mode is so we can safely handle A2DP disabling only
519 // in this case to avoid doing it several times.
520 if (mode == AudioSystem::MODE_IN_CALL &&
521 (mask & AudioSystem::ROUTE_BLUETOOTH_SCO)) {
522 AutoMutex lock(&mLock);
523 handleRouteDisablesA2dp_l(routes);
524 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800525#endif
526
527 // do nothing if only A2DP routing is affected
528 mask &= ~AudioSystem::ROUTE_BLUETOOTH_A2DP;
529 if (mask) {
530 AutoMutex lock(mHardwareLock);
531 mHardwareStatus = AUDIO_HW_GET_ROUTING;
532 uint32_t r;
533 err = mAudioHardware->getRouting(mode, &r);
534 if (err == NO_ERROR) {
535 r = (r & ~mask) | (routes & mask);
536 if (mode == AudioSystem::MODE_NORMAL ||
537 (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
538 mSavedRoute = r;
539 r |= mForcedRoute;
540 LOGV("setRouting mSavedRoute %08x mForcedRoute %08x\n", mSavedRoute, mForcedRoute);
541 }
542 mHardwareStatus = AUDIO_HW_SET_ROUTING;
543 err = mAudioHardware->setRouting(mode, r);
544 }
545 mHardwareStatus = AUDIO_HW_IDLE;
546 }
547 return err;
548}
549
550uint32_t AudioFlinger::getRouting(int mode) const
551{
552 uint32_t routes = 0;
553 if ((mode >= AudioSystem::MODE_CURRENT) && (mode < AudioSystem::NUM_MODES)) {
554 if (mode == AudioSystem::MODE_NORMAL ||
555 (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
556 routes = mSavedRoute;
557 } else {
558 mHardwareStatus = AUDIO_HW_GET_ROUTING;
559 mAudioHardware->getRouting(mode, &routes);
560 mHardwareStatus = AUDIO_HW_IDLE;
561 }
562 } else {
563 LOGW("Illegal value: getRouting(%d)", mode);
564 }
565 return routes;
566}
567
568status_t AudioFlinger::setMode(int mode)
569{
570 // check calling permissions
571 if (!settingsAllowed()) {
572 return PERMISSION_DENIED;
573 }
574 if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
575 LOGW("Illegal value: setMode(%d)", mode);
576 return BAD_VALUE;
577 }
578
579 AutoMutex lock(mHardwareLock);
580 mHardwareStatus = AUDIO_HW_SET_MODE;
581 status_t ret = mAudioHardware->setMode(mode);
582 mHardwareStatus = AUDIO_HW_IDLE;
583 return ret;
584}
585
586int AudioFlinger::getMode() const
587{
588 int mode = AudioSystem::MODE_INVALID;
589 mHardwareStatus = AUDIO_HW_SET_MODE;
590 mAudioHardware->getMode(&mode);
591 mHardwareStatus = AUDIO_HW_IDLE;
592 return mode;
593}
594
595status_t AudioFlinger::setMicMute(bool state)
596{
597 // check calling permissions
598 if (!settingsAllowed()) {
599 return PERMISSION_DENIED;
600 }
601
602 AutoMutex lock(mHardwareLock);
603 mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
604 status_t ret = mAudioHardware->setMicMute(state);
605 mHardwareStatus = AUDIO_HW_IDLE;
606 return ret;
607}
608
609bool AudioFlinger::getMicMute() const
610{
611 bool state = AudioSystem::MODE_INVALID;
612 mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
613 mAudioHardware->getMicMute(&state);
614 mHardwareStatus = AUDIO_HW_IDLE;
615 return state;
616}
617
618status_t AudioFlinger::setMasterMute(bool muted)
619{
620 // check calling permissions
621 if (!settingsAllowed()) {
622 return PERMISSION_DENIED;
623 }
624 mHardwareMixerThread->setMasterMute(muted);
625#ifdef WITH_A2DP
626 mA2dpMixerThread->setMasterMute(muted);
627#endif
628 return NO_ERROR;
629}
630
631float AudioFlinger::masterVolume() const
632{
633 return mHardwareMixerThread->masterVolume();
634}
635
636bool AudioFlinger::masterMute() const
637{
638 return mHardwareMixerThread->masterMute();
639}
640
641status_t AudioFlinger::setStreamVolume(int stream, float value)
642{
643 // check calling permissions
644 if (!settingsAllowed()) {
645 return PERMISSION_DENIED;
646 }
647
648 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
649 return BAD_VALUE;
650 }
651
652 mHardwareMixerThread->setStreamVolume(stream, value);
653#ifdef WITH_A2DP
654 mA2dpMixerThread->setStreamVolume(stream, value);
655#endif
656
657 status_t ret = NO_ERROR;
658 if (stream == AudioSystem::VOICE_CALL ||
659 stream == AudioSystem::BLUETOOTH_SCO) {
660
661 if (stream == AudioSystem::VOICE_CALL) {
662 value = (float)AudioSystem::logToLinear(value)/100.0f;
663 } else { // (type == AudioSystem::BLUETOOTH_SCO)
664 value = 1.0f;
665 }
666
667 AutoMutex lock(mHardwareLock);
668 mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
669 ret = mAudioHardware->setVoiceVolume(value);
670 mHardwareStatus = AUDIO_HW_IDLE;
671 }
672
673 return ret;
674}
675
676status_t AudioFlinger::setStreamMute(int stream, bool muted)
677{
678 // check calling permissions
679 if (!settingsAllowed()) {
680 return PERMISSION_DENIED;
681 }
682
683 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
684 return BAD_VALUE;
685 }
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700686
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800687#ifdef WITH_A2DP
688 mA2dpMixerThread->setStreamMute(stream, muted);
689#endif
690 if (stream == AudioSystem::MUSIC)
691 {
692 AutoMutex lock(&mHardwareLock);
693 if (mForcedRoute != 0)
694 mMusicMuteSaved = muted;
695 else
696 mHardwareMixerThread->setStreamMute(stream, muted);
697 } else {
698 mHardwareMixerThread->setStreamMute(stream, muted);
699 }
700
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800701 return NO_ERROR;
702}
703
704float AudioFlinger::streamVolume(int stream) const
705{
706 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
707 return 0.0f;
708 }
709 return mHardwareMixerThread->streamVolume(stream);
710}
711
712bool AudioFlinger::streamMute(int stream) const
713{
714 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
715 return true;
716 }
717
718 if (stream == AudioSystem::MUSIC && mForcedRoute != 0)
719 {
720 return mMusicMuteSaved;
721 }
722 return mHardwareMixerThread->streamMute(stream);
723}
724
725bool AudioFlinger::isMusicActive() const
726{
727 #ifdef WITH_A2DP
728 if (isA2dpEnabled()) {
729 return mA2dpMixerThread->isMusicActive();
730 }
731 #endif
732 return mHardwareMixerThread->isMusicActive();
733}
734
735status_t AudioFlinger::setParameter(const char* key, const char* value)
736{
737 status_t result, result2;
738 AutoMutex lock(mHardwareLock);
739 mHardwareStatus = AUDIO_SET_PARAMETER;
740
741 LOGV("setParameter() key %s, value %s, tid %d, calling tid %d", key, value, gettid(), IPCThreadState::self()->getCallingPid());
742 result = mAudioHardware->setParameter(key, value);
743 if (mA2dpAudioInterface) {
744 result2 = mA2dpAudioInterface->setParameter(key, value);
745 if (result2)
746 result = result2;
747 }
748 mHardwareStatus = AUDIO_HW_IDLE;
749 return result;
750}
751
752size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
753{
754 return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
755}
756
757void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
758{
759
760 LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
761 Mutex::Autolock _l(mLock);
762
763 sp<IBinder> binder = client->asBinder();
764 if (mNotificationClients.indexOf(binder) < 0) {
765 LOGV("Adding notification client %p", binder.get());
766 binder->linkToDeath(this);
767 mNotificationClients.add(binder);
768 client->a2dpEnabledChanged(isA2dpEnabled());
769 }
770}
771
772void AudioFlinger::binderDied(const wp<IBinder>& who) {
773
774 LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
775 Mutex::Autolock _l(mLock);
776
777 IBinder *binder = who.unsafe_get();
778
779 if (binder != NULL) {
780 int index = mNotificationClients.indexOf(binder);
781 if (index >= 0) {
782 LOGV("Removing notification client %p", binder);
783 mNotificationClients.removeAt(index);
784 }
785 }
786}
787
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800788void AudioFlinger::removeClient(pid_t pid)
789{
790 LOGV("removeClient() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
791 Mutex::Autolock _l(mLock);
792 mClients.removeItem(pid);
793}
794
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800795bool AudioFlinger::isA2dpEnabled() const
796{
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700797 return mA2dpEnabled;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800798}
799
800void AudioFlinger::handleForcedSpeakerRoute(int command)
801{
802 switch(command) {
803 case ACTIVE_TRACK_ADDED:
804 {
805 AutoMutex lock(mHardwareLock);
806 if (mForcedSpeakerCount++ == 0) {
807 mRouteRestoreTime = 0;
808 mMusicMuteSaved = mHardwareMixerThread->streamMute(AudioSystem::MUSIC);
809 if (mForcedRoute == 0 && !(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
810 LOGV("Route forced to Speaker ON %08x", mSavedRoute | AudioSystem::ROUTE_SPEAKER);
811 mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, true);
812 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
813 mAudioHardware->setMasterVolume(0);
814 usleep(mHardwareMixerThread->latency()*1000);
815 mHardwareStatus = AUDIO_HW_SET_ROUTING;
816 mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute | AudioSystem::ROUTE_SPEAKER);
817 mHardwareStatus = AUDIO_HW_IDLE;
818 // delay track start so that audio hardware has time to siwtch routes
819 usleep(kStartSleepTime);
820 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
821 mAudioHardware->setMasterVolume(mHardwareMixerThread->masterVolume());
822 mHardwareStatus = AUDIO_HW_IDLE;
823 }
824 mForcedRoute = AudioSystem::ROUTE_SPEAKER;
825 }
826 LOGV("mForcedSpeakerCount incremented to %d", mForcedSpeakerCount);
827 }
828 break;
829 case ACTIVE_TRACK_REMOVED:
830 {
831 AutoMutex lock(mHardwareLock);
832 if (mForcedSpeakerCount > 0){
833 if (--mForcedSpeakerCount == 0) {
834 mRouteRestoreTime = systemTime() + milliseconds(kStopSleepTime/1000);
835 }
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700836 LOGV("mForcedSpeakerCount decremented to %d", mForcedSpeakerCount);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800837 } else {
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700838 LOGE("mForcedSpeakerCount is already zero");
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700839 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800840 }
841 break;
842 case CHECK_ROUTE_RESTORE_TIME:
843 case FORCE_ROUTE_RESTORE:
844 if (mRouteRestoreTime) {
845 AutoMutex lock(mHardwareLock);
846 if (mRouteRestoreTime &&
847 (systemTime() > mRouteRestoreTime || command == FORCE_ROUTE_RESTORE)) {
848 mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, mMusicMuteSaved);
849 mForcedRoute = 0;
850 if (!(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
851 mHardwareStatus = AUDIO_HW_SET_ROUTING;
852 mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute);
853 mHardwareStatus = AUDIO_HW_IDLE;
854 LOGV("Route forced to Speaker OFF %08x", mSavedRoute);
855 }
856 mRouteRestoreTime = 0;
857 }
858 }
859 break;
860 }
861}
862
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700863#ifdef WITH_A2DP
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700864// handleRouteDisablesA2dp_l() must be called with AudioFlinger::mLock held
865void AudioFlinger::handleRouteDisablesA2dp_l(int routes)
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700866{
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700867 if (routes & AudioSystem::ROUTE_BLUETOOTH_SCO) {
868 if (mA2dpDisableCount++ == 0) {
869 if (mA2dpEnabled) {
870 setA2dpEnabled_l(false);
871 mA2dpSuppressed = true;
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700872 }
873 }
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700874 LOGV("mA2dpDisableCount incremented to %d", mA2dpDisableCount);
875 } else {
876 if (mA2dpDisableCount > 0) {
877 if (--mA2dpDisableCount == 0) {
878 if (mA2dpSuppressed) {
879 setA2dpEnabled_l(true);
880 mA2dpSuppressed = false;
881 }
882 }
883 LOGV("mA2dpDisableCount decremented to %d", mA2dpDisableCount);
884 } else {
885 LOGE("mA2dpDisableCount is already zero");
886 }
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700887 }
888}
889#endif
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800890
891// ----------------------------------------------------------------------------
892
893AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType)
894 : Thread(false),
895 mAudioFlinger(audioFlinger), mAudioMixer(0), mOutput(output), mOutputType(outputType),
896 mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
897 mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
898 mInWrite(false)
899{
900 mSampleRate = output->sampleRate();
901 mChannelCount = output->channelCount();
902
903 // FIXME - Current mixer implementation only supports stereo output
904 if (mChannelCount == 1) {
905 LOGE("Invalid audio hardware channel count");
906 }
907
908 mFormat = output->format();
909 mFrameCount = output->bufferSize() / output->channelCount() / sizeof(int16_t);
910 mAudioMixer = new AudioMixer(mFrameCount, output->sampleRate());
911
912 // FIXME - Current mixer implementation only supports stereo output: Always
913 // Allocate a stereo buffer even if HW output is mono.
914 mMixBuffer = new int16_t[mFrameCount * 2];
915 memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
916}
917
918AudioFlinger::MixerThread::~MixerThread()
919{
920 delete [] mMixBuffer;
921 delete mAudioMixer;
922}
923
924status_t AudioFlinger::MixerThread::dump(int fd, const Vector<String16>& args)
925{
926 dumpInternals(fd, args);
927 dumpTracks(fd, args);
928 return NO_ERROR;
929}
930
931status_t AudioFlinger::MixerThread::dumpTracks(int fd, const Vector<String16>& args)
932{
933 const size_t SIZE = 256;
934 char buffer[SIZE];
935 String8 result;
936
937 snprintf(buffer, SIZE, "Output %d mixer thread tracks\n", mOutputType);
938 result.append(buffer);
939 result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
940 for (size_t i = 0; i < mTracks.size(); ++i) {
941 wp<Track> wTrack = mTracks[i];
942 if (wTrack != 0) {
943 sp<Track> track = wTrack.promote();
944 if (track != 0) {
945 track->dump(buffer, SIZE);
946 result.append(buffer);
947 }
948 }
949 }
950
951 snprintf(buffer, SIZE, "Output %d mixer thread active tracks\n", mOutputType);
952 result.append(buffer);
953 result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
954 for (size_t i = 0; i < mActiveTracks.size(); ++i) {
955 wp<Track> wTrack = mTracks[i];
956 if (wTrack != 0) {
957 sp<Track> track = wTrack.promote();
958 if (track != 0) {
959 track->dump(buffer, SIZE);
960 result.append(buffer);
961 }
962 }
963 }
964 write(fd, result.string(), result.size());
965 return NO_ERROR;
966}
967
968status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
969{
970 const size_t SIZE = 256;
971 char buffer[SIZE];
972 String8 result;
973
974 snprintf(buffer, SIZE, "Output %d mixer thread internals\n", mOutputType);
975 result.append(buffer);
976 snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
977 result.append(buffer);
978 snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
979 result.append(buffer);
980 snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
981 result.append(buffer);
982 snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
983 result.append(buffer);
984 snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
985 result.append(buffer);
986 snprintf(buffer, SIZE, "standby: %d\n", mStandby);
987 result.append(buffer);
988 write(fd, result.string(), result.size());
989 return NO_ERROR;
990}
991
992// Thread virtuals
993bool AudioFlinger::MixerThread::threadLoop()
994{
995 unsigned long sleepTime = kBufferRecoveryInUsecs;
996 int16_t* curBuf = mMixBuffer;
997 Vector< sp<Track> > tracksToRemove;
998 size_t enabledTracks = 0;
999 nsecs_t standbyTime = systemTime();
1000 size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
1001 nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;
1002
1003#ifdef WITH_A2DP
1004 bool outputTrackActive = false;
1005#endif
1006
1007 do {
1008 enabledTracks = 0;
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001009 { // scope for the AudioFlinger::mLock
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001010
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001011 Mutex::Autolock _l(mAudioFlinger->mLock);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001012
1013#ifdef WITH_A2DP
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001014 if (mOutputTrack != NULL && !mAudioFlinger->isA2dpEnabled()) {
1015 if (outputTrackActive) {
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001016 mAudioFlinger->mLock.unlock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001017 mOutputTrack->stop();
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001018 mAudioFlinger->mLock.lock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001019 outputTrackActive = false;
1020 }
1021 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001022 mAudioFlinger->checkA2dpEnabledChange_l();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001023#endif
1024
1025 const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
1026
1027 // put audio hardware into standby after short delay
1028 if UNLIKELY(!activeTracks.size() && systemTime() > standbyTime) {
1029 // wait until we have something to do...
1030 LOGV("Audio hardware entering standby, output %d\n", mOutputType);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001031 if (!mStandby) {
1032 mOutput->standby();
1033 mStandby = true;
1034 }
1035
1036#ifdef WITH_A2DP
1037 if (outputTrackActive) {
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001038 mAudioFlinger->mLock.unlock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001039 mOutputTrack->stop();
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001040 mAudioFlinger->mLock.lock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001041 outputTrackActive = false;
1042 }
1043#endif
1044 if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
1045 mAudioFlinger->handleForcedSpeakerRoute(FORCE_ROUTE_RESTORE);
1046 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001047 // we're about to wait, flush the binder command buffer
1048 IPCThreadState::self()->flushCommands();
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001049 mAudioFlinger->mWaitWorkCV.wait(mAudioFlinger->mLock);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001050 LOGV("Audio hardware exiting standby, output %d\n", mOutputType);
1051
1052 if (mMasterMute == false) {
1053 char value[PROPERTY_VALUE_MAX];
1054 property_get("ro.audio.silent", value, "0");
1055 if (atoi(value)) {
1056 LOGD("Silence is golden");
1057 setMasterMute(true);
1058 }
1059 }
1060
1061 standbyTime = systemTime() + kStandbyTimeInNsecs;
1062 continue;
1063 }
1064
1065 // Forced route to speaker is handled by hardware mixer thread
1066 if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
1067 mAudioFlinger->handleForcedSpeakerRoute(CHECK_ROUTE_RESTORE_TIME);
1068 }
1069
1070 // find out which tracks need to be processed
1071 size_t count = activeTracks.size();
1072 for (size_t i=0 ; i<count ; i++) {
1073 sp<Track> t = activeTracks[i].promote();
1074 if (t == 0) continue;
1075
1076 Track* const track = t.get();
1077 audio_track_cblk_t* cblk = track->cblk();
1078
1079 // The first time a track is added we wait
1080 // for all its buffers to be filled before processing it
1081 mAudioMixer->setActiveTrack(track->name());
1082 if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
1083 !track->isPaused())
1084 {
1085 //LOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
1086
1087 // compute volume for this track
1088 int16_t left, right;
1089 if (track->isMuted() || mMasterMute || track->isPausing()) {
1090 left = right = 0;
1091 if (track->isPausing()) {
1092 LOGV("paused(%d)", track->name());
1093 track->setPaused();
1094 }
1095 } else {
1096 float typeVolume = mStreamTypes[track->type()].volume;
1097 float v = mMasterVolume * typeVolume;
1098 float v_clamped = v * cblk->volume[0];
1099 if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
1100 left = int16_t(v_clamped);
1101 v_clamped = v * cblk->volume[1];
1102 if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
1103 right = int16_t(v_clamped);
1104 }
1105
1106 // XXX: these things DON'T need to be done each time
1107 mAudioMixer->setBufferProvider(track);
1108 mAudioMixer->enable(AudioMixer::MIXING);
1109
1110 int param;
1111 if ( track->mFillingUpStatus == Track::FS_FILLED) {
1112 // no ramp for the first volume setting
1113 track->mFillingUpStatus = Track::FS_ACTIVE;
1114 if (track->mState == TrackBase::RESUMING) {
1115 track->mState = TrackBase::ACTIVE;
1116 param = AudioMixer::RAMP_VOLUME;
1117 } else {
1118 param = AudioMixer::VOLUME;
1119 }
1120 } else {
1121 param = AudioMixer::RAMP_VOLUME;
1122 }
1123 mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
1124 mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
1125 mAudioMixer->setParameter(
1126 AudioMixer::TRACK,
1127 AudioMixer::FORMAT, track->format());
1128 mAudioMixer->setParameter(
1129 AudioMixer::TRACK,
1130 AudioMixer::CHANNEL_COUNT, track->channelCount());
1131 mAudioMixer->setParameter(
1132 AudioMixer::RESAMPLE,
1133 AudioMixer::SAMPLE_RATE,
1134 int(cblk->sampleRate));
1135
1136 // reset retry count
1137 track->mRetryCount = kMaxTrackRetries;
1138 enabledTracks++;
1139 } else {
1140 //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
1141 if (track->isStopped()) {
1142 track->reset();
1143 }
1144 if (track->isTerminated() || track->isStopped() || track->isPaused()) {
1145 // We have consumed all the buffers of this track.
1146 // Remove it from the list of active tracks.
1147 LOGV("remove(%d) from active list", track->name());
1148 tracksToRemove.add(track);
1149 } else {
1150 // No buffers for this track. Give it a few chances to
1151 // fill a buffer, then remove it from active list.
1152 if (--(track->mRetryCount) <= 0) {
1153 LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
1154 tracksToRemove.add(track);
1155 }
1156 }
1157 // LOGV("disable(%d)", track->name());
1158 mAudioMixer->disable(AudioMixer::MIXING);
1159 }
1160 }
1161
1162 // remove all the tracks that need to be...
1163 count = tracksToRemove.size();
1164 if (UNLIKELY(count)) {
1165 for (size_t i=0 ; i<count ; i++) {
1166 const sp<Track>& track = tracksToRemove[i];
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001167 removeActiveTrack_l(track);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001168 if (track->isTerminated()) {
1169 mTracks.remove(track);
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001170 deleteTrackName_l(track->mName);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001171 }
1172 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001173 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001174 }
1175
1176 if (LIKELY(enabledTracks)) {
1177 // mix buffers...
1178 mAudioMixer->process(curBuf);
1179
1180#ifdef WITH_A2DP
1181 if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
1182 if (!outputTrackActive) {
1183 LOGV("starting output track in mixer for output %d", mOutputType);
1184 mOutputTrack->start();
1185 outputTrackActive = true;
1186 }
1187 mOutputTrack->write(curBuf, mFrameCount);
1188 }
1189#endif
1190
1191 // output audio to hardware
1192 mLastWriteTime = systemTime();
1193 mInWrite = true;
1194 mOutput->write(curBuf, mixBufferSize);
1195 mNumWrites++;
1196 mInWrite = false;
1197 mStandby = false;
1198 nsecs_t temp = systemTime();
1199 standbyTime = temp + kStandbyTimeInNsecs;
1200 nsecs_t delta = temp - mLastWriteTime;
1201 if (delta > maxPeriod) {
1202 LOGW("write blocked for %llu msecs", ns2ms(delta));
1203 mNumDelayedWrites++;
1204 }
1205 sleepTime = kBufferRecoveryInUsecs;
1206 } else {
1207#ifdef WITH_A2DP
1208 if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
1209 if (outputTrackActive) {
1210 mOutputTrack->write(curBuf, 0);
1211 if (mOutputTrack->bufferQueueEmpty()) {
1212 mOutputTrack->stop();
1213 outputTrackActive = false;
1214 } else {
1215 standbyTime = systemTime() + kStandbyTimeInNsecs;
1216 }
1217 }
1218 }
1219#endif
1220 // There was nothing to mix this round, which means all
1221 // active tracks were late. Sleep a little bit to give
1222 // them another chance. If we're too late, the audio
1223 // hardware will zero-fill for us.
1224 //LOGV("no buffers - usleep(%lu)", sleepTime);
1225 usleep(sleepTime);
1226 if (sleepTime < kMaxBufferRecoveryInUsecs) {
1227 sleepTime += kBufferRecoveryInUsecs;
1228 }
1229 }
1230
1231 // finally let go of all our tracks, without the lock held
1232 // since we can't guarantee the destructors won't acquire that
1233 // same lock.
1234 tracksToRemove.clear();
1235 } while (true);
1236
1237 return false;
1238}
1239
1240status_t AudioFlinger::MixerThread::readyToRun()
1241{
1242 if (mSampleRate == 0) {
1243 LOGE("No working audio driver found.");
1244 return NO_INIT;
1245 }
1246 LOGI("AudioFlinger's thread ready to run for output %d", mOutputType);
1247 return NO_ERROR;
1248}
1249
1250void AudioFlinger::MixerThread::onFirstRef()
1251{
1252 const size_t SIZE = 256;
1253 char buffer[SIZE];
1254
1255 snprintf(buffer, SIZE, "Mixer Thread for output %d", mOutputType);
1256
1257 run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
1258}
1259
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001260// MixerThread::createTrack_l() must be called with AudioFlinger::mLock held
1261sp<AudioFlinger::MixerThread::Track> AudioFlinger::MixerThread::createTrack_l(
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001262 const sp<AudioFlinger::Client>& client,
1263 int streamType,
1264 uint32_t sampleRate,
1265 int format,
1266 int channelCount,
1267 int frameCount,
1268 const sp<IMemory>& sharedBuffer,
1269 status_t *status)
1270{
1271 sp<Track> track;
1272 status_t lStatus;
1273
1274 // Resampler implementation limits input sampling rate to 2 x output sampling rate.
1275 if (sampleRate > MAX_SAMPLE_RATE || sampleRate > mSampleRate*2) {
1276 LOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
1277 lStatus = BAD_VALUE;
1278 goto Exit;
1279 }
1280
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001281
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001282 if (mSampleRate == 0) {
1283 LOGE("Audio driver not initialized.");
1284 lStatus = NO_INIT;
1285 goto Exit;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001286 }
1287
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001288 track = new Track(this, client, streamType, sampleRate, format,
1289 channelCount, frameCount, sharedBuffer);
1290 if (track->getCblk() == NULL) {
1291 lStatus = NO_MEMORY;
1292 goto Exit;
1293 }
1294 mTracks.add(track);
1295 lStatus = NO_ERROR;
1296
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001297Exit:
1298 if(status) {
1299 *status = lStatus;
1300 }
1301 return track;
1302}
1303
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001304// getTracks_l() must be called with AudioFlinger::mLock held
1305void AudioFlinger::MixerThread::getTracks_l(
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001306 SortedVector < sp<Track> >& tracks,
1307 SortedVector < wp<Track> >& activeTracks)
1308{
1309 size_t size = mTracks.size();
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001310 LOGV ("MixerThread::getTracks_l() for output %d, mTracks.size %d, mActiveTracks.size %d", mOutputType, mTracks.size(), mActiveTracks.size());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001311 for (size_t i = 0; i < size; i++) {
1312 sp<Track> t = mTracks[i];
1313 if (AudioSystem::routedToA2dpOutput(t->mStreamType)) {
1314 tracks.add(t);
1315 int j = mActiveTracks.indexOf(t);
1316 if (j >= 0) {
1317 t = mActiveTracks[j].promote();
1318 if (t != NULL) {
1319 activeTracks.add(t);
1320 }
1321 }
1322 }
1323 }
1324
1325 size = activeTracks.size();
1326 for (size_t i = 0; i < size; i++) {
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001327 removeActiveTrack_l(activeTracks[i]);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001328 }
1329
1330 size = tracks.size();
1331 for (size_t i = 0; i < size; i++) {
1332 sp<Track> t = tracks[i];
1333 mTracks.remove(t);
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001334 deleteTrackName_l(t->name());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001335 }
1336}
1337
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001338// putTracks_l() must be called with AudioFlinger::mLock held
1339void AudioFlinger::MixerThread::putTracks_l(
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001340 SortedVector < sp<Track> >& tracks,
1341 SortedVector < wp<Track> >& activeTracks)
1342{
1343
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001344 LOGV ("MixerThread::putTracks_l() for output %d, tracks.size %d, activeTracks.size %d", mOutputType, tracks.size(), activeTracks.size());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001345
1346 size_t size = tracks.size();
1347 for (size_t i = 0; i < size ; i++) {
1348 sp<Track> t = tracks[i];
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001349 int name = getTrackName_l();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001350
1351 if (name < 0) return;
1352
1353 t->mName = name;
1354 t->mMixerThread = this;
1355 mTracks.add(t);
1356
1357 int j = activeTracks.indexOf(t);
1358 if (j >= 0) {
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001359 addActiveTrack_l(t);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001360 }
1361 }
1362}
1363
1364uint32_t AudioFlinger::MixerThread::sampleRate() const
1365{
1366 return mSampleRate;
1367}
1368
1369int AudioFlinger::MixerThread::channelCount() const
1370{
1371 return mChannelCount;
1372}
1373
1374int AudioFlinger::MixerThread::format() const
1375{
1376 return mFormat;
1377}
1378
1379size_t AudioFlinger::MixerThread::frameCount() const
1380{
1381 return mFrameCount;
1382}
1383
1384uint32_t AudioFlinger::MixerThread::latency() const
1385{
1386 if (mOutput) {
1387 return mOutput->latency();
1388 }
1389 else {
1390 return 0;
1391 }
1392}
1393
1394status_t AudioFlinger::MixerThread::setMasterVolume(float value)
1395{
1396 mMasterVolume = value;
1397 return NO_ERROR;
1398}
1399
1400status_t AudioFlinger::MixerThread::setMasterMute(bool muted)
1401{
1402 mMasterMute = muted;
1403 return NO_ERROR;
1404}
1405
1406float AudioFlinger::MixerThread::masterVolume() const
1407{
1408 return mMasterVolume;
1409}
1410
1411bool AudioFlinger::MixerThread::masterMute() const
1412{
1413 return mMasterMute;
1414}
1415
1416status_t AudioFlinger::MixerThread::setStreamVolume(int stream, float value)
1417{
1418 mStreamTypes[stream].volume = value;
1419 return NO_ERROR;
1420}
1421
1422status_t AudioFlinger::MixerThread::setStreamMute(int stream, bool muted)
1423{
1424 mStreamTypes[stream].mute = muted;
1425 return NO_ERROR;
1426}
1427
1428float AudioFlinger::MixerThread::streamVolume(int stream) const
1429{
1430 return mStreamTypes[stream].volume;
1431}
1432
1433bool AudioFlinger::MixerThread::streamMute(int stream) const
1434{
1435 return mStreamTypes[stream].mute;
1436}
1437
1438bool AudioFlinger::MixerThread::isMusicActive() const
1439{
1440 size_t count = mActiveTracks.size();
1441 for (size_t i = 0 ; i < count ; ++i) {
1442 sp<Track> t = mActiveTracks[i].promote();
1443 if (t == 0) continue;
1444 Track* const track = t.get();
1445 if (t->mStreamType == AudioSystem::MUSIC)
1446 return true;
1447 }
1448 return false;
1449}
1450
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001451// addTrack_l() must be called with AudioFlinger::mLock held
1452status_t AudioFlinger::MixerThread::addTrack_l(const sp<Track>& track)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001453{
1454 status_t status = ALREADY_EXISTS;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001455
1456 // here the track could be either new, or restarted
1457 // in both cases "unstop" the track
1458 if (track->isPaused()) {
1459 track->mState = TrackBase::RESUMING;
1460 LOGV("PAUSED => RESUMING (%d)", track->name());
1461 } else {
1462 track->mState = TrackBase::ACTIVE;
1463 LOGV("? => ACTIVE (%d)", track->name());
1464 }
1465 // set retry count for buffer fill
1466 track->mRetryCount = kMaxTrackStartupRetries;
1467 if (mActiveTracks.indexOf(track) < 0) {
1468 // the track is newly added, make sure it fills up all its
1469 // buffers before playing. This is to ensure the client will
1470 // effectively get the latency it requested.
1471 track->mFillingUpStatus = Track::FS_FILLING;
1472 track->mResetDone = false;
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001473 addActiveTrack_l(track);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001474 status = NO_ERROR;
1475 }
1476
1477 LOGV("mWaitWorkCV.broadcast");
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001478 mAudioFlinger->mWaitWorkCV.broadcast();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001479
1480 return status;
1481}
1482
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001483// removeTrack_l() must be called with AudioFlinger::mLock held
1484void AudioFlinger::MixerThread::removeTrack_l(wp<Track> track, int name)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001485{
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001486 sp<Track> t = track.promote();
1487 if (t!=NULL && (t->mState <= TrackBase::STOPPED)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001488 t->reset();
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001489 deleteTrackName_l(name);
1490 removeActiveTrack_l(track);
1491 mAudioFlinger->mWaitWorkCV.broadcast();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001492 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001493}
1494
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001495// destroyTrack_l() must be called with AudioFlinger::mLock held
1496void AudioFlinger::MixerThread::destroyTrack_l(const sp<Track>& track)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001497{
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001498 track->mState = TrackBase::TERMINATED;
1499 if (mActiveTracks.indexOf(track) < 0) {
1500 LOGV("remove track (%d) and delete from mixer", track->name());
1501 mTracks.remove(track);
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001502 deleteTrackName_l(track->name());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001503 }
1504}
1505
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001506// addActiveTrack_l() must be called with AudioFlinger::mLock held
1507void AudioFlinger::MixerThread::addActiveTrack_l(const wp<Track>& t)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001508{
1509 mActiveTracks.add(t);
1510
1511 // Force routing to speaker for certain stream types
1512 // The forced routing to speaker is managed by hardware mixer
1513 if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
1514 sp<Track> track = t.promote();
1515 if (track == NULL) return;
1516
1517 if (streamForcedToSpeaker(track->type())) {
1518 mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_ADDED);
1519 }
1520 }
1521}
1522
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001523// removeActiveTrack_l() must be called with AudioFlinger::mLock held
1524void AudioFlinger::MixerThread::removeActiveTrack_l(const wp<Track>& t)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001525{
1526 mActiveTracks.remove(t);
1527
1528 // Force routing to speaker for certain stream types
1529 // The forced routing to speaker is managed by hardware mixer
1530 if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
1531 sp<Track> track = t.promote();
1532 if (track == NULL) return;
1533
1534 if (streamForcedToSpeaker(track->type())) {
1535 mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_REMOVED);
1536 }
1537 }
1538}
1539
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001540// getTrackName_l() must be called with AudioFlinger::mLock held
1541int AudioFlinger::MixerThread::getTrackName_l()
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001542{
1543 return mAudioMixer->getTrackName();
1544}
1545
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001546// deleteTrackName_l() must be called with AudioFlinger::mLock held
1547void AudioFlinger::MixerThread::deleteTrackName_l(int name)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001548{
1549 mAudioMixer->deleteTrackName(name);
1550}
1551
1552size_t AudioFlinger::MixerThread::getOutputFrameCount()
1553{
1554 return mOutput->bufferSize() / mOutput->channelCount() / sizeof(int16_t);
1555}
1556
1557// ----------------------------------------------------------------------------
1558
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001559// TrackBase constructor must be called with AudioFlinger::mLock held
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001560AudioFlinger::MixerThread::TrackBase::TrackBase(
1561 const sp<MixerThread>& mixerThread,
1562 const sp<Client>& client,
1563 int streamType,
1564 uint32_t sampleRate,
1565 int format,
1566 int channelCount,
1567 int frameCount,
1568 uint32_t flags,
1569 const sp<IMemory>& sharedBuffer)
1570 : RefBase(),
1571 mMixerThread(mixerThread),
1572 mClient(client),
1573 mStreamType(streamType),
1574 mFrameCount(0),
1575 mState(IDLE),
1576 mClientTid(-1),
1577 mFormat(format),
1578 mFlags(flags & ~SYSTEM_FLAGS_MASK)
1579{
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001580 mName = mixerThread->getTrackName_l();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001581 LOGV("TrackBase contructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
1582 if (mName < 0) {
1583 LOGE("no more track names availlable");
1584 return;
1585 }
1586
1587 LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
1588
1589 // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
1590 size_t size = sizeof(audio_track_cblk_t);
1591 size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
1592 if (sharedBuffer == 0) {
1593 size += bufferSize;
1594 }
1595
1596 if (client != NULL) {
1597 mCblkMemory = client->heap()->allocate(size);
1598 if (mCblkMemory != 0) {
1599 mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
1600 if (mCblk) { // construct the shared structure in-place.
1601 new(mCblk) audio_track_cblk_t();
1602 // clear all buffers
1603 mCblk->frameCount = frameCount;
The Android Open Source Project4f68be12009-03-18 17:39:46 -07001604 mCblk->sampleRate = (uint16_t)sampleRate;
1605 mCblk->channels = (uint16_t)channelCount;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001606 if (sharedBuffer == 0) {
1607 mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
1608 memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
1609 // Force underrun condition to avoid false underrun callback until first data is
1610 // written to buffer
1611 mCblk->flowControlFlag = 1;
1612 } else {
1613 mBuffer = sharedBuffer->pointer();
1614 }
1615 mBufferEnd = (uint8_t *)mBuffer + bufferSize;
1616 }
1617 } else {
1618 LOGE("not enough memory for AudioTrack size=%u", size);
1619 client->heap()->dump("AudioTrack");
1620 return;
1621 }
1622 } else {
1623 mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
1624 if (mCblk) { // construct the shared structure in-place.
1625 new(mCblk) audio_track_cblk_t();
1626 // clear all buffers
1627 mCblk->frameCount = frameCount;
The Android Open Source Project4f68be12009-03-18 17:39:46 -07001628 mCblk->sampleRate = (uint16_t)sampleRate;
1629 mCblk->channels = (uint16_t)channelCount;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001630 mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
1631 memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
1632 // Force underrun condition to avoid false underrun callback until first data is
1633 // written to buffer
1634 mCblk->flowControlFlag = 1;
1635 mBufferEnd = (uint8_t *)mBuffer + bufferSize;
1636 }
1637 }
1638}
1639
1640AudioFlinger::MixerThread::TrackBase::~TrackBase()
1641{
1642 if (mCblk) {
1643 mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
1644 }
1645 mCblkMemory.clear(); // and free the shared memory
1646 mClient.clear();
1647}
1648
1649void AudioFlinger::MixerThread::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
1650{
1651 buffer->raw = 0;
1652 mFrameCount = buffer->frameCount;
1653 step();
1654 buffer->frameCount = 0;
1655}
1656
1657bool AudioFlinger::MixerThread::TrackBase::step() {
1658 bool result;
1659 audio_track_cblk_t* cblk = this->cblk();
1660
1661 result = cblk->stepServer(mFrameCount);
1662 if (!result) {
1663 LOGV("stepServer failed acquiring cblk mutex");
1664 mFlags |= STEPSERVER_FAILED;
1665 }
1666 return result;
1667}
1668
1669void AudioFlinger::MixerThread::TrackBase::reset() {
1670 audio_track_cblk_t* cblk = this->cblk();
1671
1672 cblk->user = 0;
1673 cblk->server = 0;
1674 cblk->userBase = 0;
1675 cblk->serverBase = 0;
1676 mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
1677 LOGV("TrackBase::reset");
1678}
1679
1680sp<IMemory> AudioFlinger::MixerThread::TrackBase::getCblk() const
1681{
1682 return mCblkMemory;
1683}
1684
1685int AudioFlinger::MixerThread::TrackBase::sampleRate() const {
The Android Open Source Project4f68be12009-03-18 17:39:46 -07001686 return (int)mCblk->sampleRate;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001687}
1688
1689int AudioFlinger::MixerThread::TrackBase::channelCount() const {
1690 return mCblk->channels;
1691}
1692
1693void* AudioFlinger::MixerThread::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
1694 audio_track_cblk_t* cblk = this->cblk();
1695 int16_t *bufferStart = (int16_t *)mBuffer + (offset-cblk->serverBase)*cblk->channels;
1696 int16_t *bufferEnd = bufferStart + frames * cblk->channels;
1697
1698 // Check validity of returned pointer in case the track control block would have been corrupted.
The Android Open Source Project4f68be12009-03-18 17:39:46 -07001699 if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd ||
1700 cblk->channels == 2 && ((unsigned long)bufferStart & 3) ) {
1701 LOGE("TrackBase::getBuffer buffer out of range:\n start: %p, end %p , mBuffer %p mBufferEnd %p\n \
1702 server %d, serverBase %d, user %d, userBase %d, channels %d",
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001703 bufferStart, bufferEnd, mBuffer, mBufferEnd,
The Android Open Source Project4f68be12009-03-18 17:39:46 -07001704 cblk->server, cblk->serverBase, cblk->user, cblk->userBase, cblk->channels);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001705 return 0;
1706 }
1707
1708 return bufferStart;
1709}
1710
1711// ----------------------------------------------------------------------------
1712
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001713// Track constructor must be called with AudioFlinger::mLock held
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001714AudioFlinger::MixerThread::Track::Track(
1715 const sp<MixerThread>& mixerThread,
1716 const sp<Client>& client,
1717 int streamType,
1718 uint32_t sampleRate,
1719 int format,
1720 int channelCount,
1721 int frameCount,
1722 const sp<IMemory>& sharedBuffer)
1723 : TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, 0, sharedBuffer)
1724{
1725 mVolume[0] = 1.0f;
1726 mVolume[1] = 1.0f;
1727 mMute = false;
1728 mSharedBuffer = sharedBuffer;
1729}
1730
1731AudioFlinger::MixerThread::Track::~Track()
1732{
1733 wp<Track> weak(this); // never create a strong ref from the dtor
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001734 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001735 mState = TERMINATED;
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001736 mMixerThread->removeTrack_l(weak, mName);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001737}
1738
1739void AudioFlinger::MixerThread::Track::destroy()
1740{
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001741 // NOTE: destroyTrack_l() can remove a strong reference to this Track
1742 // by removing it from mTracks vector, so there is a risk that this Tracks's
1743 // desctructor is called. As the destructor needs to lock AudioFlinger::mLock,
1744 // we must acquire a strong reference on this Track before locking AudioFlinger::mLock
1745 // here so that the destructor is called only when exiting this function.
1746 // On the other hand, as long as Track::destroy() is only called by
1747 // TrackHandle destructor, the TrackHandle still holds a strong ref on
1748 // this Track with its member mTrack.
1749 sp<Track> keep(this);
1750 { // scope for AudioFlinger::mLock
1751 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
1752 mMixerThread->destroyTrack_l(this);
1753 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001754}
1755
1756void AudioFlinger::MixerThread::Track::dump(char* buffer, size_t size)
1757{
1758 snprintf(buffer, size, " %5d %5d %3u %3u %3u %3u %1d %1d %1d %5u %5u %5u %04x %04x\n",
1759 mName - AudioMixer::TRACK0,
1760 (mClient == NULL) ? getpid() : mClient->pid(),
1761 mStreamType,
1762 mFormat,
1763 mCblk->channels,
1764 mFrameCount,
1765 mState,
1766 mMute,
1767 mFillingUpStatus,
1768 mCblk->sampleRate,
1769 mCblk->volume[0],
1770 mCblk->volume[1],
1771 mCblk->server,
1772 mCblk->user);
1773}
1774
1775status_t AudioFlinger::MixerThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
1776{
1777 audio_track_cblk_t* cblk = this->cblk();
1778 uint32_t framesReady;
1779 uint32_t framesReq = buffer->frameCount;
1780
1781 // Check if last stepServer failed, try to step now
1782 if (mFlags & TrackBase::STEPSERVER_FAILED) {
1783 if (!step()) goto getNextBuffer_exit;
1784 LOGV("stepServer recovered");
1785 mFlags &= ~TrackBase::STEPSERVER_FAILED;
1786 }
1787
1788 framesReady = cblk->framesReady();
1789
1790 if (LIKELY(framesReady)) {
1791 uint32_t s = cblk->server;
1792 uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
1793
1794 bufferEnd = (cblk->loopEnd < bufferEnd) ? cblk->loopEnd : bufferEnd;
1795 if (framesReq > framesReady) {
1796 framesReq = framesReady;
1797 }
1798 if (s + framesReq > bufferEnd) {
1799 framesReq = bufferEnd - s;
1800 }
1801
1802 buffer->raw = getBuffer(s, framesReq);
1803 if (buffer->raw == 0) goto getNextBuffer_exit;
1804
1805 buffer->frameCount = framesReq;
1806 return NO_ERROR;
1807 }
1808
1809getNextBuffer_exit:
1810 buffer->raw = 0;
1811 buffer->frameCount = 0;
1812 return NOT_ENOUGH_DATA;
1813}
1814
1815bool AudioFlinger::MixerThread::Track::isReady() const {
1816 if (mFillingUpStatus != FS_FILLING) return true;
1817
1818 if (mCblk->framesReady() >= mCblk->frameCount ||
1819 mCblk->forceReady) {
1820 mFillingUpStatus = FS_FILLED;
1821 mCblk->forceReady = 0;
1822 LOGV("Track::isReady() track %d for output %d", mName, mMixerThread->mOutputType);
1823 return true;
1824 }
1825 return false;
1826}
1827
1828status_t AudioFlinger::MixerThread::Track::start()
1829{
1830 LOGV("start(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001831 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
1832 mMixerThread->addTrack_l(this);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001833 return NO_ERROR;
1834}
1835
1836void AudioFlinger::MixerThread::Track::stop()
1837{
1838 LOGV("stop(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001839 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001840 if (mState > STOPPED) {
1841 mState = STOPPED;
1842 // If the track is not active (PAUSED and buffers full), flush buffers
1843 if (mMixerThread->mActiveTracks.indexOf(this) < 0) {
1844 reset();
1845 }
1846 LOGV("(> STOPPED) => STOPPED (%d)", mName);
1847 }
1848}
1849
1850void AudioFlinger::MixerThread::Track::pause()
1851{
1852 LOGV("pause(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001853 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001854 if (mState == ACTIVE || mState == RESUMING) {
1855 mState = PAUSING;
1856 LOGV("ACTIVE/RESUMING => PAUSING (%d)", mName);
1857 }
1858}
1859
1860void AudioFlinger::MixerThread::Track::flush()
1861{
1862 LOGV("flush(%d)", mName);
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001863 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001864 if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
1865 return;
1866 }
1867 // No point remaining in PAUSED state after a flush => go to
1868 // STOPPED state
1869 mState = STOPPED;
1870
The Android Open Source Project4f68be12009-03-18 17:39:46 -07001871 mCblk->lock.lock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001872 // NOTE: reset() will reset cblk->user and cblk->server with
1873 // the risk that at the same time, the AudioMixer is trying to read
1874 // data. In this case, getNextBuffer() would return a NULL pointer
1875 // as audio buffer => the AudioMixer code MUST always test that pointer
1876 // returned by getNextBuffer() is not NULL!
1877 reset();
The Android Open Source Project4f68be12009-03-18 17:39:46 -07001878 mCblk->lock.unlock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001879}
1880
1881void AudioFlinger::MixerThread::Track::reset()
1882{
1883 // Do not reset twice to avoid discarding data written just after a flush and before
1884 // the audioflinger thread detects the track is stopped.
1885 if (!mResetDone) {
1886 TrackBase::reset();
1887 // Force underrun condition to avoid false underrun callback until first data is
1888 // written to buffer
1889 mCblk->flowControlFlag = 1;
1890 mCblk->forceReady = 0;
1891 mFillingUpStatus = FS_FILLING;
1892 mResetDone = true;
1893 }
1894}
1895
1896void AudioFlinger::MixerThread::Track::mute(bool muted)
1897{
1898 mMute = muted;
1899}
1900
1901void AudioFlinger::MixerThread::Track::setVolume(float left, float right)
1902{
1903 mVolume[0] = left;
1904 mVolume[1] = right;
1905}
1906
1907// ----------------------------------------------------------------------------
1908
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001909// RecordTrack constructor must be called with AudioFlinger::mLock held
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001910AudioFlinger::MixerThread::RecordTrack::RecordTrack(
1911 const sp<MixerThread>& mixerThread,
1912 const sp<Client>& client,
1913 int streamType,
1914 uint32_t sampleRate,
1915 int format,
1916 int channelCount,
1917 int frameCount,
1918 uint32_t flags)
1919 : TrackBase(mixerThread, client, streamType, sampleRate, format,
1920 channelCount, frameCount, flags, 0),
1921 mOverflow(false)
1922{
1923}
1924
1925AudioFlinger::MixerThread::RecordTrack::~RecordTrack()
1926{
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001927 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
1928 mMixerThread->deleteTrackName_l(mName);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001929}
1930
1931status_t AudioFlinger::MixerThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
1932{
1933 audio_track_cblk_t* cblk = this->cblk();
1934 uint32_t framesAvail;
1935 uint32_t framesReq = buffer->frameCount;
1936
1937 // Check if last stepServer failed, try to step now
1938 if (mFlags & TrackBase::STEPSERVER_FAILED) {
1939 if (!step()) goto getNextBuffer_exit;
1940 LOGV("stepServer recovered");
1941 mFlags &= ~TrackBase::STEPSERVER_FAILED;
1942 }
1943
1944 framesAvail = cblk->framesAvailable_l();
1945
1946 if (LIKELY(framesAvail)) {
1947 uint32_t s = cblk->server;
1948 uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
1949
1950 if (framesReq > framesAvail) {
1951 framesReq = framesAvail;
1952 }
1953 if (s + framesReq > bufferEnd) {
1954 framesReq = bufferEnd - s;
1955 }
1956
1957 buffer->raw = getBuffer(s, framesReq);
1958 if (buffer->raw == 0) goto getNextBuffer_exit;
1959
1960 buffer->frameCount = framesReq;
1961 return NO_ERROR;
1962 }
1963
1964getNextBuffer_exit:
1965 buffer->raw = 0;
1966 buffer->frameCount = 0;
1967 return NOT_ENOUGH_DATA;
1968}
1969
1970status_t AudioFlinger::MixerThread::RecordTrack::start()
1971{
1972 return mMixerThread->mAudioFlinger->startRecord(this);
1973}
1974
1975void AudioFlinger::MixerThread::RecordTrack::stop()
1976{
1977 mMixerThread->mAudioFlinger->stopRecord(this);
1978 TrackBase::reset();
1979 // Force overerrun condition to avoid false overrun callback until first data is
1980 // read from buffer
1981 mCblk->flowControlFlag = 1;
1982}
1983
1984
1985// ----------------------------------------------------------------------------
1986
1987AudioFlinger::MixerThread::OutputTrack::OutputTrack(
1988 const sp<MixerThread>& mixerThread,
1989 uint32_t sampleRate,
1990 int format,
1991 int channelCount,
1992 int frameCount)
1993 : Track(mixerThread, NULL, AudioSystem::SYSTEM, sampleRate, format, channelCount, frameCount, NULL),
1994 mOutputMixerThread(mixerThread)
1995{
1996
1997 mCblk->out = 1;
1998 mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
1999 mCblk->volume[0] = mCblk->volume[1] = 0x1000;
2000 mOutBuffer.frameCount = 0;
2001 mCblk->bufferTimeoutMs = 10;
2002
2003 LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p",
2004 mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd);
2005
2006}
2007
2008AudioFlinger::MixerThread::OutputTrack::~OutputTrack()
2009{
2010 stop();
2011}
2012
2013status_t AudioFlinger::MixerThread::OutputTrack::start()
2014{
2015 status_t status = Track::start();
2016
2017 mRetryCount = 127;
2018 return status;
2019}
2020
2021void AudioFlinger::MixerThread::OutputTrack::stop()
2022{
2023 Track::stop();
2024 clearBufferQueue();
2025 mOutBuffer.frameCount = 0;
2026}
2027
2028void AudioFlinger::MixerThread::OutputTrack::write(int16_t* data, uint32_t frames)
2029{
2030 Buffer *pInBuffer;
2031 Buffer inBuffer;
2032 uint32_t channels = mCblk->channels;
2033
2034 inBuffer.frameCount = frames;
2035 inBuffer.i16 = data;
2036
2037 if (mCblk->user == 0) {
2038 if (mOutputMixerThread->isMusicActive()) {
2039 mCblk->forceReady = 1;
2040 LOGV("OutputTrack::start() force ready");
2041 } else if (mCblk->frameCount > frames){
2042 if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
2043 uint32_t startFrames = (mCblk->frameCount - frames);
2044 LOGV("OutputTrack::start() write %d frames", startFrames);
2045 pInBuffer = new Buffer;
2046 pInBuffer->mBuffer = new int16_t[startFrames * channels];
2047 pInBuffer->frameCount = startFrames;
2048 pInBuffer->i16 = pInBuffer->mBuffer;
2049 memset(pInBuffer->raw, 0, startFrames * channels * sizeof(int16_t));
2050 mBufferQueue.add(pInBuffer);
2051 } else {
2052 LOGW ("OutputTrack::write() no more buffers");
2053 }
2054 }
2055 }
2056
2057 while (1) {
2058 // First write pending buffers, then new data
2059 if (mBufferQueue.size()) {
2060 pInBuffer = mBufferQueue.itemAt(0);
2061 } else {
2062 pInBuffer = &inBuffer;
2063 }
2064
2065 if (pInBuffer->frameCount == 0) {
2066 break;
2067 }
2068
2069 if (mOutBuffer.frameCount == 0) {
2070 mOutBuffer.frameCount = pInBuffer->frameCount;
2071 if (obtainBuffer(&mOutBuffer) == (status_t)AudioTrack::NO_MORE_BUFFERS) {
2072 break;
2073 }
2074 }
2075
2076 uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : pInBuffer->frameCount;
2077 memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channels * sizeof(int16_t));
2078 mCblk->stepUser(outFrames);
2079 pInBuffer->frameCount -= outFrames;
2080 pInBuffer->i16 += outFrames * channels;
2081 mOutBuffer.frameCount -= outFrames;
2082 mOutBuffer.i16 += outFrames * channels;
2083
2084 if (pInBuffer->frameCount == 0) {
2085 if (mBufferQueue.size()) {
2086 mBufferQueue.removeAt(0);
2087 delete [] pInBuffer->mBuffer;
2088 delete pInBuffer;
2089 } else {
2090 break;
2091 }
2092 }
2093 }
2094
2095 // If we could not write all frames, allocate a buffer and queue it for next time.
2096 if (inBuffer.frameCount) {
2097 if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
2098 pInBuffer = new Buffer;
2099 pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channels];
2100 pInBuffer->frameCount = inBuffer.frameCount;
2101 pInBuffer->i16 = pInBuffer->mBuffer;
2102 memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channels * sizeof(int16_t));
2103 mBufferQueue.add(pInBuffer);
2104 } else {
2105 LOGW("OutputTrack::write() no more buffers");
2106 }
2107 }
2108
2109 // Calling write() with a 0 length buffer, means that no more data will be written:
2110 // If no more buffers are pending, fill output track buffer to make sure it is started
2111 // by output mixer.
2112 if (frames == 0 && mBufferQueue.size() == 0 && mCblk->user < mCblk->frameCount) {
2113 frames = mCblk->frameCount - mCblk->user;
2114 pInBuffer = new Buffer;
2115 pInBuffer->mBuffer = new int16_t[frames * channels];
2116 pInBuffer->frameCount = frames;
2117 pInBuffer->i16 = pInBuffer->mBuffer;
2118 memset(pInBuffer->raw, 0, frames * channels * sizeof(int16_t));
2119 mBufferQueue.add(pInBuffer);
2120 }
2121
2122}
2123
2124status_t AudioFlinger::MixerThread::OutputTrack::obtainBuffer(AudioBufferProvider::Buffer* buffer)
2125{
2126 int active;
2127 int timeout = 0;
2128 status_t result;
2129 audio_track_cblk_t* cblk = mCblk;
2130 uint32_t framesReq = buffer->frameCount;
2131
2132 LOGV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
2133 buffer->frameCount = 0;
2134
2135 uint32_t framesAvail = cblk->framesAvailable();
2136
2137 if (framesAvail == 0) {
2138 return AudioTrack::NO_MORE_BUFFERS;
2139 }
2140
2141 if (framesReq > framesAvail) {
2142 framesReq = framesAvail;
2143 }
2144
2145 uint32_t u = cblk->user;
2146 uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
2147
2148 if (u + framesReq > bufferEnd) {
2149 framesReq = bufferEnd - u;
2150 }
2151
2152 buffer->frameCount = framesReq;
2153 buffer->raw = (void *)cblk->buffer(u);
2154 return NO_ERROR;
2155}
2156
2157
2158void AudioFlinger::MixerThread::OutputTrack::clearBufferQueue()
2159{
2160 size_t size = mBufferQueue.size();
2161 Buffer *pBuffer;
2162
2163 for (size_t i = 0; i < size; i++) {
2164 pBuffer = mBufferQueue.itemAt(i);
2165 delete [] pBuffer->mBuffer;
2166 delete pBuffer;
2167 }
2168 mBufferQueue.clear();
2169}
2170
2171// ----------------------------------------------------------------------------
2172
2173AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
2174 : RefBase(),
2175 mAudioFlinger(audioFlinger),
2176 mMemoryDealer(new MemoryDealer(1024*1024)),
2177 mPid(pid)
2178{
2179 // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
2180}
2181
2182AudioFlinger::Client::~Client()
2183{
2184 mAudioFlinger->removeClient(mPid);
2185}
2186
2187const sp<MemoryDealer>& AudioFlinger::Client::heap() const
2188{
2189 return mMemoryDealer;
2190}
2191
2192// ----------------------------------------------------------------------------
2193
2194AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::MixerThread::Track>& track)
2195 : BnAudioTrack(),
2196 mTrack(track)
2197{
2198}
2199
2200AudioFlinger::TrackHandle::~TrackHandle() {
2201 // just stop the track on deletion, associated resources
2202 // will be freed from the main thread once all pending buffers have
2203 // been played. Unless it's not in the active track list, in which
2204 // case we free everything now...
2205 mTrack->destroy();
2206}
2207
2208status_t AudioFlinger::TrackHandle::start() {
2209 return mTrack->start();
2210}
2211
2212void AudioFlinger::TrackHandle::stop() {
2213 mTrack->stop();
2214}
2215
2216void AudioFlinger::TrackHandle::flush() {
2217 mTrack->flush();
2218}
2219
2220void AudioFlinger::TrackHandle::mute(bool e) {
2221 mTrack->mute(e);
2222}
2223
2224void AudioFlinger::TrackHandle::pause() {
2225 mTrack->pause();
2226}
2227
2228void AudioFlinger::TrackHandle::setVolume(float left, float right) {
2229 mTrack->setVolume(left, right);
2230}
2231
2232sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
2233 return mTrack->getCblk();
2234}
2235
2236status_t AudioFlinger::TrackHandle::onTransact(
2237 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2238{
2239 return BnAudioTrack::onTransact(code, data, reply, flags);
2240}
2241
2242// ----------------------------------------------------------------------------
2243
2244sp<IAudioRecord> AudioFlinger::openRecord(
2245 pid_t pid,
2246 int streamType,
2247 uint32_t sampleRate,
2248 int format,
2249 int channelCount,
2250 int frameCount,
2251 uint32_t flags,
2252 status_t *status)
2253{
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002254 sp<MixerThread::RecordTrack> recordTrack;
2255 sp<RecordHandle> recordHandle;
2256 sp<Client> client;
2257 wp<Client> wclient;
2258 AudioStreamIn* input = 0;
2259 int inFrameCount;
2260 size_t inputBufferSize;
2261 status_t lStatus;
2262
2263 // check calling permissions
2264 if (!recordingAllowed()) {
2265 lStatus = PERMISSION_DENIED;
2266 goto Exit;
2267 }
2268
2269 if (uint32_t(streamType) >= AudioRecord::NUM_STREAM_TYPES) {
2270 LOGE("invalid stream type");
2271 lStatus = BAD_VALUE;
2272 goto Exit;
2273 }
2274
2275 if (sampleRate > MAX_SAMPLE_RATE) {
2276 LOGE("Sample rate out of range");
2277 lStatus = BAD_VALUE;
2278 goto Exit;
2279 }
2280
2281 if (mAudioRecordThread == 0) {
2282 LOGE("Audio record thread not started");
2283 lStatus = NO_INIT;
2284 goto Exit;
2285 }
2286
2287
2288 // Check that audio input stream accepts requested audio parameters
2289 inputBufferSize = mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
2290 if (inputBufferSize == 0) {
2291 lStatus = BAD_VALUE;
2292 LOGE("Bad audio input parameters: sampling rate %u, format %d, channels %d", sampleRate, format, channelCount);
2293 goto Exit;
2294 }
2295
2296 // add client to list
The Android Open Source Project22f8def2009-03-09 11:52:12 -07002297 { // scope for mLock
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002298 Mutex::Autolock _l(mLock);
2299 wclient = mClients.valueFor(pid);
2300 if (wclient != NULL) {
2301 client = wclient.promote();
2302 } else {
2303 client = new Client(this, pid);
2304 mClients.add(pid, client);
2305 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -07002306
2307 // frameCount must be a multiple of input buffer size
2308 inFrameCount = inputBufferSize/channelCount/sizeof(short);
2309 frameCount = ((frameCount - 1)/inFrameCount + 1) * inFrameCount;
2310
2311 // create new record track. The record track uses one track in mHardwareMixerThread by convention.
2312 recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, streamType, sampleRate,
2313 format, channelCount, frameCount, flags);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002314 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002315 if (recordTrack->getCblk() == NULL) {
2316 recordTrack.clear();
2317 lStatus = NO_MEMORY;
2318 goto Exit;
2319 }
2320
2321 // return to handle to client
2322 recordHandle = new RecordHandle(recordTrack);
2323 lStatus = NO_ERROR;
2324
2325Exit:
2326 if (status) {
2327 *status = lStatus;
2328 }
2329 return recordHandle;
2330}
2331
2332status_t AudioFlinger::startRecord(MixerThread::RecordTrack* recordTrack) {
2333 if (mAudioRecordThread != 0) {
2334 return mAudioRecordThread->start(recordTrack);
2335 }
2336 return NO_INIT;
2337}
2338
2339void AudioFlinger::stopRecord(MixerThread::RecordTrack* recordTrack) {
2340 if (mAudioRecordThread != 0) {
2341 mAudioRecordThread->stop(recordTrack);
2342 }
2343}
2344
2345// ----------------------------------------------------------------------------
2346
2347AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::MixerThread::RecordTrack>& recordTrack)
2348 : BnAudioRecord(),
2349 mRecordTrack(recordTrack)
2350{
2351}
2352
2353AudioFlinger::RecordHandle::~RecordHandle() {
2354 stop();
2355}
2356
2357status_t AudioFlinger::RecordHandle::start() {
2358 LOGV("RecordHandle::start()");
2359 return mRecordTrack->start();
2360}
2361
2362void AudioFlinger::RecordHandle::stop() {
2363 LOGV("RecordHandle::stop()");
2364 mRecordTrack->stop();
2365}
2366
2367sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
2368 return mRecordTrack->getCblk();
2369}
2370
2371status_t AudioFlinger::RecordHandle::onTransact(
2372 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2373{
2374 return BnAudioRecord::onTransact(code, data, reply, flags);
2375}
2376
2377// ----------------------------------------------------------------------------
2378
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -07002379AudioFlinger::AudioRecordThread::AudioRecordThread(AudioHardwareInterface* audioHardware,
2380 const sp<AudioFlinger>& audioFlinger) :
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002381 mAudioHardware(audioHardware),
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -07002382 mAudioFlinger(audioFlinger),
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002383 mActive(false)
2384{
2385}
2386
2387AudioFlinger::AudioRecordThread::~AudioRecordThread()
2388{
2389}
2390
2391bool AudioFlinger::AudioRecordThread::threadLoop()
2392{
2393 LOGV("AudioRecordThread: start record loop");
2394 AudioBufferProvider::Buffer buffer;
2395 int inBufferSize = 0;
2396 int inFrameCount = 0;
2397 AudioStreamIn* input = 0;
2398
2399 mActive = 0;
2400
2401 // start recording
2402 while (!exitPending()) {
2403 if (!mActive) {
2404 mLock.lock();
2405 if (!mActive && !exitPending()) {
2406 LOGV("AudioRecordThread: loop stopping");
2407 if (input) {
2408 delete input;
2409 input = 0;
2410 }
2411 mRecordTrack.clear();
2412 mStopped.signal();
2413
2414 mWaitWorkCV.wait(mLock);
2415
2416 LOGV("AudioRecordThread: loop starting");
2417 if (mRecordTrack != 0) {
2418 input = mAudioHardware->openInputStream(mRecordTrack->format(),
2419 mRecordTrack->channelCount(),
2420 mRecordTrack->sampleRate(),
2421 &mStartStatus,
2422 (AudioSystem::audio_in_acoustics)(mRecordTrack->mFlags >> 16));
2423 if (input != 0) {
2424 inBufferSize = input->bufferSize();
2425 inFrameCount = inBufferSize/input->frameSize();
2426 }
2427 } else {
2428 mStartStatus = NO_INIT;
2429 }
2430 if (mStartStatus !=NO_ERROR) {
2431 LOGW("record start failed, status %d", mStartStatus);
2432 mActive = false;
2433 mRecordTrack.clear();
2434 }
2435 mWaitWorkCV.signal();
2436 }
2437 mLock.unlock();
2438 } else if (mRecordTrack != 0) {
2439
2440 buffer.frameCount = inFrameCount;
The Android Open Source Project22f8def2009-03-09 11:52:12 -07002441 if (LIKELY(mRecordTrack->getNextBuffer(&buffer) == NO_ERROR &&
2442 (int)buffer.frameCount == inFrameCount)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002443 LOGV("AudioRecordThread read: %d frames", buffer.frameCount);
2444 ssize_t bytesRead = input->read(buffer.raw, inBufferSize);
2445 if (bytesRead < 0) {
2446 LOGE("Error reading audio input");
2447 sleep(1);
2448 }
2449 mRecordTrack->releaseBuffer(&buffer);
2450 mRecordTrack->overflow();
2451 }
2452
2453 // client isn't retrieving buffers fast enough
2454 else {
2455 if (!mRecordTrack->setOverflow())
2456 LOGW("AudioRecordThread: buffer overflow");
2457 // Release the processor for a while before asking for a new buffer.
2458 // This will give the application more chance to read from the buffer and
2459 // clear the overflow.
2460 usleep(5000);
2461 }
2462 }
2463 }
2464
2465
2466 if (input) {
2467 delete input;
2468 }
2469 mRecordTrack.clear();
2470
2471 return false;
2472}
2473
2474status_t AudioFlinger::AudioRecordThread::start(MixerThread::RecordTrack* recordTrack)
2475{
2476 LOGV("AudioRecordThread::start");
2477 AutoMutex lock(&mLock);
2478 mActive = true;
2479 // If starting the active track, just reset mActive in case a stop
2480 // was pending and exit
2481 if (recordTrack == mRecordTrack.get()) return NO_ERROR;
2482
2483 if (mRecordTrack != 0) return -EBUSY;
2484
2485 mRecordTrack = recordTrack;
2486
2487 // signal thread to start
2488 LOGV("Signal record thread");
2489 mWaitWorkCV.signal();
2490 mWaitWorkCV.wait(mLock);
2491 LOGV("Record started, status %d", mStartStatus);
2492 return mStartStatus;
2493}
2494
2495void AudioFlinger::AudioRecordThread::stop(MixerThread::RecordTrack* recordTrack) {
2496 LOGV("AudioRecordThread::stop");
2497 AutoMutex lock(&mLock);
2498 if (mActive && (recordTrack == mRecordTrack.get())) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002499 mActive = false;
2500 mStopped.wait(mLock);
2501 }
2502}
2503
2504void AudioFlinger::AudioRecordThread::exit()
2505{
2506 LOGV("AudioRecordThread::exit");
2507 {
2508 AutoMutex lock(&mLock);
2509 requestExit();
2510 mWaitWorkCV.signal();
2511 }
2512 requestExitAndWait();
2513}
2514
2515status_t AudioFlinger::AudioRecordThread::dump(int fd, const Vector<String16>& args)
2516{
2517 const size_t SIZE = 256;
2518 char buffer[SIZE];
2519 String8 result;
2520 pid_t pid = 0;
2521
2522 if (mRecordTrack != 0 && mRecordTrack->mClient != 0) {
2523 snprintf(buffer, SIZE, "Record client pid: %d\n", mRecordTrack->mClient->pid());
2524 result.append(buffer);
2525 } else {
2526 result.append("No record client\n");
2527 }
2528 write(fd, result.string(), result.size());
2529 return NO_ERROR;
2530}
2531
2532status_t AudioFlinger::onTransact(
2533 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2534{
2535 return BnAudioFlinger::onTransact(code, data, reply, flags);
2536}
2537
2538// ----------------------------------------------------------------------------
2539void AudioFlinger::instantiate() {
2540 defaultServiceManager()->addService(
2541 String16("media.audio_flinger"), new AudioFlinger());
2542}
2543
2544}; // namespace android