blob: 440778ddc27ba0725ae71adb9907ef2564452252 [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
61//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
62static const unsigned long kBufferRecoveryInUsecs = 2000;
63static const unsigned long kMaxBufferRecoveryInUsecs = 20000;
64static const float MAX_GAIN = 4096.0f;
65
66// retry counts for buffer fill timeout
67// 50 * ~20msecs = 1 second
68static const int8_t kMaxTrackRetries = 50;
69static const int8_t kMaxTrackStartupRetries = 50;
70
71static const int kStartSleepTime = 30000;
72static const int kStopSleepTime = 30000;
73
The Android Open Source Project22f8def2009-03-09 11:52:12 -070074static const int kDumpLockRetries = 50;
75static const int kDumpLockSleep = 20000;
76
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080077// Maximum number of pending buffers allocated by OutputTrack::write()
78static const uint8_t kMaxOutputTrackBuffers = 5;
79
80
81#define AUDIOFLINGER_SECURITY_ENABLED 1
82
83// ----------------------------------------------------------------------------
84
85static bool recordingAllowed() {
86#ifndef HAVE_ANDROID_OS
87 return true;
88#endif
89#if AUDIOFLINGER_SECURITY_ENABLED
90 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
91 bool ok = checkCallingPermission(String16("android.permission.RECORD_AUDIO"));
92 if (!ok) LOGE("Request requires android.permission.RECORD_AUDIO");
93 return ok;
94#else
95 if (!checkCallingPermission(String16("android.permission.RECORD_AUDIO")))
96 LOGW("WARNING: Need to add android.permission.RECORD_AUDIO to manifest");
97 return true;
98#endif
99}
100
101static bool settingsAllowed() {
102#ifndef HAVE_ANDROID_OS
103 return true;
104#endif
105#if AUDIOFLINGER_SECURITY_ENABLED
106 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
107 bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
108 if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
109 return ok;
110#else
111 if (!checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")))
112 LOGW("WARNING: Need to add android.permission.MODIFY_AUDIO_SETTINGS to manifest");
113 return true;
114#endif
115}
116
117// ----------------------------------------------------------------------------
118
119AudioFlinger::AudioFlinger()
120 : BnAudioFlinger(),
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700121 mAudioHardware(0), mA2dpAudioInterface(0), mA2dpEnabled(false), mNotifyA2dpChange(false),
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800122 mForcedSpeakerCount(0), mForcedRoute(0), mRouteRestoreTime(0), mMusicMuteSaved(false)
123{
124 mHardwareStatus = AUDIO_HW_IDLE;
125 mAudioHardware = AudioHardwareInterface::create();
126 mHardwareStatus = AUDIO_HW_INIT;
127 if (mAudioHardware->initCheck() == NO_ERROR) {
128 // open 16-bit output stream for s/w mixer
129 mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
130 status_t status;
131 AudioStreamOut *hwOutput = mAudioHardware->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
132 mHardwareStatus = AUDIO_HW_IDLE;
133 if (hwOutput) {
134 mHardwareMixerThread = new MixerThread(this, hwOutput, AudioSystem::AUDIO_OUTPUT_HARDWARE);
135 } else {
136 LOGE("Failed to initialize hardware output stream, status: %d", status);
137 }
138
139#ifdef WITH_A2DP
140 // Create A2DP interface
141 mA2dpAudioInterface = new A2dpAudioInterface();
142 AudioStreamOut *a2dpOutput = mA2dpAudioInterface->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
143 if (a2dpOutput) {
144 mA2dpMixerThread = new MixerThread(this, a2dpOutput, AudioSystem::AUDIO_OUTPUT_A2DP);
145 if (hwOutput) {
146 uint32_t frameCount = ((a2dpOutput->bufferSize()/a2dpOutput->frameSize()) * hwOutput->sampleRate()) / a2dpOutput->sampleRate();
147 MixerThread::OutputTrack *a2dpOutTrack = new MixerThread::OutputTrack(mA2dpMixerThread,
148 hwOutput->sampleRate(),
149 AudioSystem::PCM_16_BIT,
150 hwOutput->channelCount(),
151 frameCount);
152 mHardwareMixerThread->setOuputTrack(a2dpOutTrack);
153 }
154 } else {
155 LOGE("Failed to initialize A2DP output stream, status: %d", status);
156 }
157#endif
158
159 // FIXME - this should come from settings
160 setRouting(AudioSystem::MODE_NORMAL, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
161 setRouting(AudioSystem::MODE_RINGTONE, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
162 setRouting(AudioSystem::MODE_IN_CALL, AudioSystem::ROUTE_EARPIECE, AudioSystem::ROUTE_ALL);
163 setMode(AudioSystem::MODE_NORMAL);
164
165 setMasterVolume(1.0f);
166 setMasterMute(false);
167
168 // Start record thread
169 mAudioRecordThread = new AudioRecordThread(mAudioHardware);
170 if (mAudioRecordThread != 0) {
171 mAudioRecordThread->run("AudioRecordThread", PRIORITY_URGENT_AUDIO);
172 }
173 } else {
174 LOGE("Couldn't even initialize the stubbed audio hardware!");
175 }
176}
177
178AudioFlinger::~AudioFlinger()
179{
180 if (mAudioRecordThread != 0) {
181 mAudioRecordThread->exit();
182 mAudioRecordThread.clear();
183 }
184 mHardwareMixerThread.clear();
185 delete mAudioHardware;
186 // deleting mA2dpAudioInterface also deletes mA2dpOutput;
187#ifdef WITH_A2DP
188 mA2dpMixerThread.clear();
189 delete mA2dpAudioInterface;
190#endif
191}
192
193
194#ifdef WITH_A2DP
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700195// setA2dpEnabled_l() must be called with AudioFlinger::mLock held
196void AudioFlinger::setA2dpEnabled_l(bool enable)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800197{
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700198 SortedVector < sp<MixerThread::Track> > tracks;
199 SortedVector < wp<MixerThread::Track> > activeTracks;
200
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800201 LOGV_IF(enable, "set output to A2DP\n");
202 LOGV_IF(!enable, "set output to hardware audio\n");
203
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700204 // Transfer tracks playing on MUSIC stream from one mixer to the other
205 if (enable) {
206 mHardwareMixerThread->getTracks_l(tracks, activeTracks);
207 mA2dpMixerThread->putTracks_l(tracks, activeTracks);
208 } else {
209 mA2dpMixerThread->getTracks_l(tracks, activeTracks);
210 mHardwareMixerThread->putTracks_l(tracks, activeTracks);
211 }
212 mA2dpEnabled = enable;
213 mNotifyA2dpChange = true;
214 mWaitWorkCV.broadcast();
215}
216
217// checkA2dpEnabledChange_l() must be called with AudioFlinger::mLock held
218void AudioFlinger::checkA2dpEnabledChange_l()
219{
220 if (mNotifyA2dpChange) {
221 // Notify AudioSystem of the A2DP activation/deactivation
222 size_t size = mNotificationClients.size();
223 for (size_t i = 0; i < size; i++) {
224 sp<IBinder> binder = mNotificationClients.itemAt(i).promote();
225 if (binder != NULL) {
226 LOGV("Notifying output change to client %p", binder.get());
227 sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
228 client->a2dpEnabledChanged(mA2dpEnabled);
229 }
230 }
231 mNotifyA2dpChange = false;
232 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800233}
234#endif // WITH_A2DP
235
236bool AudioFlinger::streamForcedToSpeaker(int streamType)
237{
238 // NOTE that streams listed here must not be routed to A2DP by default:
239 // AudioSystem::routedToA2dpOutput(streamType) == false
240 return (streamType == AudioSystem::RING ||
241 streamType == AudioSystem::ALARM ||
242 streamType == AudioSystem::NOTIFICATION);
243}
244
245status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
246{
247 const size_t SIZE = 256;
248 char buffer[SIZE];
249 String8 result;
250
251 result.append("Clients:\n");
252 for (size_t i = 0; i < mClients.size(); ++i) {
253 wp<Client> wClient = mClients.valueAt(i);
254 if (wClient != 0) {
255 sp<Client> client = wClient.promote();
256 if (client != 0) {
257 snprintf(buffer, SIZE, " pid: %d\n", client->pid());
258 result.append(buffer);
259 }
260 }
261 }
262 write(fd, result.string(), result.size());
263 return NO_ERROR;
264}
265
266
267status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
268{
269 const size_t SIZE = 256;
270 char buffer[SIZE];
271 String8 result;
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700272 int hardwareStatus = mHardwareStatus;
273
274 if (hardwareStatus == AUDIO_HW_IDLE && mHardwareMixerThread->mStandby) {
275 hardwareStatus = AUDIO_HW_STANDBY;
276 }
277 snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800278 result.append(buffer);
279 write(fd, result.string(), result.size());
280 return NO_ERROR;
281}
282
283status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
284{
285 const size_t SIZE = 256;
286 char buffer[SIZE];
287 String8 result;
288 snprintf(buffer, SIZE, "Permission Denial: "
289 "can't dump AudioFlinger from pid=%d, uid=%d\n",
290 IPCThreadState::self()->getCallingPid(),
291 IPCThreadState::self()->getCallingUid());
292 result.append(buffer);
293 write(fd, result.string(), result.size());
294 return NO_ERROR;
295}
296
297status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
298{
299 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
300 dumpPermissionDenial(fd, args);
301 } else {
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700302 bool locked = false;
303 for (int i = 0; i < kDumpLockRetries; ++i) {
304 if (mLock.tryLock() == NO_ERROR) {
305 locked = true;
306 break;
307 }
308 usleep(kDumpLockSleep);
309 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800310
311 dumpClients(fd, args);
312 dumpInternals(fd, args);
313 mHardwareMixerThread->dump(fd, args);
314#ifdef WITH_A2DP
315 mA2dpMixerThread->dump(fd, args);
316#endif
317
318 // dump record client
319 if (mAudioRecordThread != 0) mAudioRecordThread->dump(fd, args);
320
321 if (mAudioHardware) {
322 mAudioHardware->dumpState(fd, args);
323 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700324 if (locked) mLock.unlock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800325 }
326 return NO_ERROR;
327}
328
329// IAudioFlinger interface
330
331
332sp<IAudioTrack> AudioFlinger::createTrack(
333 pid_t pid,
334 int streamType,
335 uint32_t sampleRate,
336 int format,
337 int channelCount,
338 int frameCount,
339 uint32_t flags,
340 const sp<IMemory>& sharedBuffer,
341 status_t *status)
342{
343 sp<MixerThread::Track> track;
344 sp<TrackHandle> trackHandle;
345 sp<Client> client;
346 wp<Client> wclient;
347 status_t lStatus;
348
349 if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
350 LOGE("invalid stream type");
351 lStatus = BAD_VALUE;
352 goto Exit;
353 }
354
355 {
356 Mutex::Autolock _l(mLock);
357
358 wclient = mClients.valueFor(pid);
359
360 if (wclient != NULL) {
361 client = wclient.promote();
362 } else {
363 client = new Client(this, pid);
364 mClients.add(pid, client);
365 }
366#ifdef WITH_A2DP
367 if (isA2dpEnabled() && AudioSystem::routedToA2dpOutput(streamType)) {
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700368 track = mA2dpMixerThread->createTrack_l(client, streamType, sampleRate, format,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800369 channelCount, frameCount, sharedBuffer, &lStatus);
370 } else
371#endif
372 {
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700373 track = mHardwareMixerThread->createTrack_l(client, streamType, sampleRate, format,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800374 channelCount, frameCount, sharedBuffer, &lStatus);
375 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700376 }
377 if (lStatus == NO_ERROR) {
378 trackHandle = new TrackHandle(track);
379 } else {
380 track.clear();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800381 }
382
383Exit:
384 if(status) {
385 *status = lStatus;
386 }
387 return trackHandle;
388}
389
390uint32_t AudioFlinger::sampleRate(int output) const
391{
392#ifdef WITH_A2DP
393 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
394 return mA2dpMixerThread->sampleRate();
395 }
396#endif
397 return mHardwareMixerThread->sampleRate();
398}
399
400int AudioFlinger::channelCount(int output) const
401{
402#ifdef WITH_A2DP
403 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
404 return mA2dpMixerThread->channelCount();
405 }
406#endif
407 return mHardwareMixerThread->channelCount();
408}
409
410int AudioFlinger::format(int output) const
411{
412#ifdef WITH_A2DP
413 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
414 return mA2dpMixerThread->format();
415 }
416#endif
417 return mHardwareMixerThread->format();
418}
419
420size_t AudioFlinger::frameCount(int output) const
421{
422#ifdef WITH_A2DP
423 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
424 return mA2dpMixerThread->frameCount();
425 }
426#endif
427 return mHardwareMixerThread->frameCount();
428}
429
430uint32_t AudioFlinger::latency(int output) const
431{
432#ifdef WITH_A2DP
433 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
434 return mA2dpMixerThread->latency();
435 }
436#endif
437 return mHardwareMixerThread->latency();
438}
439
440status_t AudioFlinger::setMasterVolume(float value)
441{
442 // check calling permissions
443 if (!settingsAllowed()) {
444 return PERMISSION_DENIED;
445 }
446
447 // when hw supports master volume, don't scale in sw mixer
448 AutoMutex lock(mHardwareLock);
449 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
450 if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
451 value = 1.0f;
452 }
453 mHardwareStatus = AUDIO_HW_IDLE;
454 mHardwareMixerThread->setMasterVolume(value);
455#ifdef WITH_A2DP
456 mA2dpMixerThread->setMasterVolume(value);
457#endif
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700458
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800459 return NO_ERROR;
460}
461
462status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
463{
464 status_t err = NO_ERROR;
465
466 // check calling permissions
467 if (!settingsAllowed()) {
468 return PERMISSION_DENIED;
469 }
470 if ((mode < AudioSystem::MODE_CURRENT) || (mode >= AudioSystem::NUM_MODES)) {
471 LOGW("Illegal value: setRouting(%d, %u, %u)", mode, routes, mask);
472 return BAD_VALUE;
473 }
474
475#ifdef WITH_A2DP
476 LOGD("setRouting %d %d %d, tid %d, calling tid %d\n", mode, routes, mask, gettid(), IPCThreadState::self()->getCallingPid());
477 if (mode == AudioSystem::MODE_NORMAL &&
478 (mask & AudioSystem::ROUTE_BLUETOOTH_A2DP)) {
479 AutoMutex lock(&mLock);
480
481 bool enableA2dp = false;
482 if (routes & AudioSystem::ROUTE_BLUETOOTH_A2DP) {
483 enableA2dp = true;
484 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700485 setA2dpEnabled_l(enableA2dp);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800486 LOGV("setOutput done\n");
487 }
488#endif
489
490 // do nothing if only A2DP routing is affected
491 mask &= ~AudioSystem::ROUTE_BLUETOOTH_A2DP;
492 if (mask) {
493 AutoMutex lock(mHardwareLock);
494 mHardwareStatus = AUDIO_HW_GET_ROUTING;
495 uint32_t r;
496 err = mAudioHardware->getRouting(mode, &r);
497 if (err == NO_ERROR) {
498 r = (r & ~mask) | (routes & mask);
499 if (mode == AudioSystem::MODE_NORMAL ||
500 (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
501 mSavedRoute = r;
502 r |= mForcedRoute;
503 LOGV("setRouting mSavedRoute %08x mForcedRoute %08x\n", mSavedRoute, mForcedRoute);
504 }
505 mHardwareStatus = AUDIO_HW_SET_ROUTING;
506 err = mAudioHardware->setRouting(mode, r);
507 }
508 mHardwareStatus = AUDIO_HW_IDLE;
509 }
510 return err;
511}
512
513uint32_t AudioFlinger::getRouting(int mode) const
514{
515 uint32_t routes = 0;
516 if ((mode >= AudioSystem::MODE_CURRENT) && (mode < AudioSystem::NUM_MODES)) {
517 if (mode == AudioSystem::MODE_NORMAL ||
518 (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
519 routes = mSavedRoute;
520 } else {
521 mHardwareStatus = AUDIO_HW_GET_ROUTING;
522 mAudioHardware->getRouting(mode, &routes);
523 mHardwareStatus = AUDIO_HW_IDLE;
524 }
525 } else {
526 LOGW("Illegal value: getRouting(%d)", mode);
527 }
528 return routes;
529}
530
531status_t AudioFlinger::setMode(int mode)
532{
533 // check calling permissions
534 if (!settingsAllowed()) {
535 return PERMISSION_DENIED;
536 }
537 if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
538 LOGW("Illegal value: setMode(%d)", mode);
539 return BAD_VALUE;
540 }
541
542 AutoMutex lock(mHardwareLock);
543 mHardwareStatus = AUDIO_HW_SET_MODE;
544 status_t ret = mAudioHardware->setMode(mode);
545 mHardwareStatus = AUDIO_HW_IDLE;
546 return ret;
547}
548
549int AudioFlinger::getMode() const
550{
551 int mode = AudioSystem::MODE_INVALID;
552 mHardwareStatus = AUDIO_HW_SET_MODE;
553 mAudioHardware->getMode(&mode);
554 mHardwareStatus = AUDIO_HW_IDLE;
555 return mode;
556}
557
558status_t AudioFlinger::setMicMute(bool state)
559{
560 // check calling permissions
561 if (!settingsAllowed()) {
562 return PERMISSION_DENIED;
563 }
564
565 AutoMutex lock(mHardwareLock);
566 mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
567 status_t ret = mAudioHardware->setMicMute(state);
568 mHardwareStatus = AUDIO_HW_IDLE;
569 return ret;
570}
571
572bool AudioFlinger::getMicMute() const
573{
574 bool state = AudioSystem::MODE_INVALID;
575 mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
576 mAudioHardware->getMicMute(&state);
577 mHardwareStatus = AUDIO_HW_IDLE;
578 return state;
579}
580
581status_t AudioFlinger::setMasterMute(bool muted)
582{
583 // check calling permissions
584 if (!settingsAllowed()) {
585 return PERMISSION_DENIED;
586 }
587 mHardwareMixerThread->setMasterMute(muted);
588#ifdef WITH_A2DP
589 mA2dpMixerThread->setMasterMute(muted);
590#endif
591 return NO_ERROR;
592}
593
594float AudioFlinger::masterVolume() const
595{
596 return mHardwareMixerThread->masterVolume();
597}
598
599bool AudioFlinger::masterMute() const
600{
601 return mHardwareMixerThread->masterMute();
602}
603
604status_t AudioFlinger::setStreamVolume(int stream, float value)
605{
606 // check calling permissions
607 if (!settingsAllowed()) {
608 return PERMISSION_DENIED;
609 }
610
611 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
612 return BAD_VALUE;
613 }
614
615 mHardwareMixerThread->setStreamVolume(stream, value);
616#ifdef WITH_A2DP
617 mA2dpMixerThread->setStreamVolume(stream, value);
618#endif
619
620 status_t ret = NO_ERROR;
621 if (stream == AudioSystem::VOICE_CALL ||
622 stream == AudioSystem::BLUETOOTH_SCO) {
623
624 if (stream == AudioSystem::VOICE_CALL) {
625 value = (float)AudioSystem::logToLinear(value)/100.0f;
626 } else { // (type == AudioSystem::BLUETOOTH_SCO)
627 value = 1.0f;
628 }
629
630 AutoMutex lock(mHardwareLock);
631 mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
632 ret = mAudioHardware->setVoiceVolume(value);
633 mHardwareStatus = AUDIO_HW_IDLE;
634 }
635
636 return ret;
637}
638
639status_t AudioFlinger::setStreamMute(int stream, bool muted)
640{
641 // check calling permissions
642 if (!settingsAllowed()) {
643 return PERMISSION_DENIED;
644 }
645
646 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
647 return BAD_VALUE;
648 }
649
650#ifdef WITH_A2DP
651 mA2dpMixerThread->setStreamMute(stream, muted);
652#endif
653 if (stream == AudioSystem::MUSIC)
654 {
655 AutoMutex lock(&mHardwareLock);
656 if (mForcedRoute != 0)
657 mMusicMuteSaved = muted;
658 else
659 mHardwareMixerThread->setStreamMute(stream, muted);
660 } else {
661 mHardwareMixerThread->setStreamMute(stream, muted);
662 }
663
664
665
666 return NO_ERROR;
667}
668
669float AudioFlinger::streamVolume(int stream) const
670{
671 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
672 return 0.0f;
673 }
674 return mHardwareMixerThread->streamVolume(stream);
675}
676
677bool AudioFlinger::streamMute(int stream) const
678{
679 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
680 return true;
681 }
682
683 if (stream == AudioSystem::MUSIC && mForcedRoute != 0)
684 {
685 return mMusicMuteSaved;
686 }
687 return mHardwareMixerThread->streamMute(stream);
688}
689
690bool AudioFlinger::isMusicActive() const
691{
692 #ifdef WITH_A2DP
693 if (isA2dpEnabled()) {
694 return mA2dpMixerThread->isMusicActive();
695 }
696 #endif
697 return mHardwareMixerThread->isMusicActive();
698}
699
700status_t AudioFlinger::setParameter(const char* key, const char* value)
701{
702 status_t result, result2;
703 AutoMutex lock(mHardwareLock);
704 mHardwareStatus = AUDIO_SET_PARAMETER;
705
706 LOGV("setParameter() key %s, value %s, tid %d, calling tid %d", key, value, gettid(), IPCThreadState::self()->getCallingPid());
707 result = mAudioHardware->setParameter(key, value);
708 if (mA2dpAudioInterface) {
709 result2 = mA2dpAudioInterface->setParameter(key, value);
710 if (result2)
711 result = result2;
712 }
713 mHardwareStatus = AUDIO_HW_IDLE;
714 return result;
715}
716
717size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
718{
719 return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
720}
721
722void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
723{
724
725 LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
726 Mutex::Autolock _l(mLock);
727
728 sp<IBinder> binder = client->asBinder();
729 if (mNotificationClients.indexOf(binder) < 0) {
730 LOGV("Adding notification client %p", binder.get());
731 binder->linkToDeath(this);
732 mNotificationClients.add(binder);
733 client->a2dpEnabledChanged(isA2dpEnabled());
734 }
735}
736
737void AudioFlinger::binderDied(const wp<IBinder>& who) {
738
739 LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
740 Mutex::Autolock _l(mLock);
741
742 IBinder *binder = who.unsafe_get();
743
744 if (binder != NULL) {
745 int index = mNotificationClients.indexOf(binder);
746 if (index >= 0) {
747 LOGV("Removing notification client %p", binder);
748 mNotificationClients.removeAt(index);
749 }
750 }
751}
752
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800753void AudioFlinger::removeClient(pid_t pid)
754{
755 LOGV("removeClient() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
756 Mutex::Autolock _l(mLock);
757 mClients.removeItem(pid);
758}
759
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800760bool AudioFlinger::isA2dpEnabled() const
761{
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700762 return mA2dpEnabled;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800763}
764
765void AudioFlinger::handleForcedSpeakerRoute(int command)
766{
767 switch(command) {
768 case ACTIVE_TRACK_ADDED:
769 {
770 AutoMutex lock(mHardwareLock);
771 if (mForcedSpeakerCount++ == 0) {
772 mRouteRestoreTime = 0;
773 mMusicMuteSaved = mHardwareMixerThread->streamMute(AudioSystem::MUSIC);
774 if (mForcedRoute == 0 && !(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
775 LOGV("Route forced to Speaker ON %08x", mSavedRoute | AudioSystem::ROUTE_SPEAKER);
776 mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, true);
777 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
778 mAudioHardware->setMasterVolume(0);
779 usleep(mHardwareMixerThread->latency()*1000);
780 mHardwareStatus = AUDIO_HW_SET_ROUTING;
781 mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute | AudioSystem::ROUTE_SPEAKER);
782 mHardwareStatus = AUDIO_HW_IDLE;
783 // delay track start so that audio hardware has time to siwtch routes
784 usleep(kStartSleepTime);
785 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
786 mAudioHardware->setMasterVolume(mHardwareMixerThread->masterVolume());
787 mHardwareStatus = AUDIO_HW_IDLE;
788 }
789 mForcedRoute = AudioSystem::ROUTE_SPEAKER;
790 }
791 LOGV("mForcedSpeakerCount incremented to %d", mForcedSpeakerCount);
792 }
793 break;
794 case ACTIVE_TRACK_REMOVED:
795 {
796 AutoMutex lock(mHardwareLock);
797 if (mForcedSpeakerCount > 0){
798 if (--mForcedSpeakerCount == 0) {
799 mRouteRestoreTime = systemTime() + milliseconds(kStopSleepTime/1000);
800 }
801 LOGV("mForcedSpeakerCount decremented to %d", mForcedSpeakerCount);
802 } else {
803 LOGE("mForcedSpeakerCount is already zero");
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700804 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800805 }
806 break;
807 case CHECK_ROUTE_RESTORE_TIME:
808 case FORCE_ROUTE_RESTORE:
809 if (mRouteRestoreTime) {
810 AutoMutex lock(mHardwareLock);
811 if (mRouteRestoreTime &&
812 (systemTime() > mRouteRestoreTime || command == FORCE_ROUTE_RESTORE)) {
813 mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, mMusicMuteSaved);
814 mForcedRoute = 0;
815 if (!(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
816 mHardwareStatus = AUDIO_HW_SET_ROUTING;
817 mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute);
818 mHardwareStatus = AUDIO_HW_IDLE;
819 LOGV("Route forced to Speaker OFF %08x", mSavedRoute);
820 }
821 mRouteRestoreTime = 0;
822 }
823 }
824 break;
825 }
826}
827
828
829// ----------------------------------------------------------------------------
830
831AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType)
832 : Thread(false),
833 mAudioFlinger(audioFlinger), mAudioMixer(0), mOutput(output), mOutputType(outputType),
834 mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
835 mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
836 mInWrite(false)
837{
838 mSampleRate = output->sampleRate();
839 mChannelCount = output->channelCount();
840
841 // FIXME - Current mixer implementation only supports stereo output
842 if (mChannelCount == 1) {
843 LOGE("Invalid audio hardware channel count");
844 }
845
846 mFormat = output->format();
847 mFrameCount = output->bufferSize() / output->channelCount() / sizeof(int16_t);
848 mAudioMixer = new AudioMixer(mFrameCount, output->sampleRate());
849
850 // FIXME - Current mixer implementation only supports stereo output: Always
851 // Allocate a stereo buffer even if HW output is mono.
852 mMixBuffer = new int16_t[mFrameCount * 2];
853 memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
854}
855
856AudioFlinger::MixerThread::~MixerThread()
857{
858 delete [] mMixBuffer;
859 delete mAudioMixer;
860}
861
862status_t AudioFlinger::MixerThread::dump(int fd, const Vector<String16>& args)
863{
864 dumpInternals(fd, args);
865 dumpTracks(fd, args);
866 return NO_ERROR;
867}
868
869status_t AudioFlinger::MixerThread::dumpTracks(int fd, const Vector<String16>& args)
870{
871 const size_t SIZE = 256;
872 char buffer[SIZE];
873 String8 result;
874
875 snprintf(buffer, SIZE, "Output %d mixer thread tracks\n", mOutputType);
876 result.append(buffer);
877 result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
878 for (size_t i = 0; i < mTracks.size(); ++i) {
879 wp<Track> wTrack = mTracks[i];
880 if (wTrack != 0) {
881 sp<Track> track = wTrack.promote();
882 if (track != 0) {
883 track->dump(buffer, SIZE);
884 result.append(buffer);
885 }
886 }
887 }
888
889 snprintf(buffer, SIZE, "Output %d mixer thread active tracks\n", mOutputType);
890 result.append(buffer);
891 result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
892 for (size_t i = 0; i < mActiveTracks.size(); ++i) {
893 wp<Track> wTrack = mTracks[i];
894 if (wTrack != 0) {
895 sp<Track> track = wTrack.promote();
896 if (track != 0) {
897 track->dump(buffer, SIZE);
898 result.append(buffer);
899 }
900 }
901 }
902 write(fd, result.string(), result.size());
903 return NO_ERROR;
904}
905
906status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
907{
908 const size_t SIZE = 256;
909 char buffer[SIZE];
910 String8 result;
911
912 snprintf(buffer, SIZE, "Output %d mixer thread internals\n", mOutputType);
913 result.append(buffer);
914 snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
915 result.append(buffer);
916 snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
917 result.append(buffer);
918 snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
919 result.append(buffer);
920 snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
921 result.append(buffer);
922 snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
923 result.append(buffer);
924 snprintf(buffer, SIZE, "standby: %d\n", mStandby);
925 result.append(buffer);
926 write(fd, result.string(), result.size());
927 return NO_ERROR;
928}
929
930// Thread virtuals
931bool AudioFlinger::MixerThread::threadLoop()
932{
933 unsigned long sleepTime = kBufferRecoveryInUsecs;
934 int16_t* curBuf = mMixBuffer;
935 Vector< sp<Track> > tracksToRemove;
936 size_t enabledTracks = 0;
937 nsecs_t standbyTime = systemTime();
938 size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
939 nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;
940
941#ifdef WITH_A2DP
942 bool outputTrackActive = false;
943#endif
944
945 do {
946 enabledTracks = 0;
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700947 { // scope for the AudioFlinger::mLock
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800948
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700949 Mutex::Autolock _l(mAudioFlinger->mLock);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800950
951#ifdef WITH_A2DP
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800952 if (mOutputTrack != NULL && !mAudioFlinger->isA2dpEnabled()) {
953 if (outputTrackActive) {
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700954 mAudioFlinger->mLock.unlock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800955 mOutputTrack->stop();
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700956 mAudioFlinger->mLock.lock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800957 outputTrackActive = false;
958 }
959 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700960 mAudioFlinger->checkA2dpEnabledChange_l();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800961#endif
962
963 const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
964
965 // put audio hardware into standby after short delay
966 if UNLIKELY(!activeTracks.size() && systemTime() > standbyTime) {
967 // wait until we have something to do...
968 LOGV("Audio hardware entering standby, output %d\n", mOutputType);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800969 if (!mStandby) {
970 mOutput->standby();
971 mStandby = true;
972 }
973
974#ifdef WITH_A2DP
975 if (outputTrackActive) {
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700976 mAudioFlinger->mLock.unlock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800977 mOutputTrack->stop();
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700978 mAudioFlinger->mLock.lock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800979 outputTrackActive = false;
980 }
981#endif
982 if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
983 mAudioFlinger->handleForcedSpeakerRoute(FORCE_ROUTE_RESTORE);
984 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800985 // we're about to wait, flush the binder command buffer
986 IPCThreadState::self()->flushCommands();
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700987 mAudioFlinger->mWaitWorkCV.wait(mAudioFlinger->mLock);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800988 LOGV("Audio hardware exiting standby, output %d\n", mOutputType);
989
990 if (mMasterMute == false) {
991 char value[PROPERTY_VALUE_MAX];
992 property_get("ro.audio.silent", value, "0");
993 if (atoi(value)) {
994 LOGD("Silence is golden");
995 setMasterMute(true);
996 }
997 }
998
999 standbyTime = systemTime() + kStandbyTimeInNsecs;
1000 continue;
1001 }
1002
1003 // Forced route to speaker is handled by hardware mixer thread
1004 if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
1005 mAudioFlinger->handleForcedSpeakerRoute(CHECK_ROUTE_RESTORE_TIME);
1006 }
1007
1008 // find out which tracks need to be processed
1009 size_t count = activeTracks.size();
1010 for (size_t i=0 ; i<count ; i++) {
1011 sp<Track> t = activeTracks[i].promote();
1012 if (t == 0) continue;
1013
1014 Track* const track = t.get();
1015 audio_track_cblk_t* cblk = track->cblk();
1016
1017 // The first time a track is added we wait
1018 // for all its buffers to be filled before processing it
1019 mAudioMixer->setActiveTrack(track->name());
1020 if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
1021 !track->isPaused())
1022 {
1023 //LOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
1024
1025 // compute volume for this track
1026 int16_t left, right;
1027 if (track->isMuted() || mMasterMute || track->isPausing()) {
1028 left = right = 0;
1029 if (track->isPausing()) {
1030 LOGV("paused(%d)", track->name());
1031 track->setPaused();
1032 }
1033 } else {
1034 float typeVolume = mStreamTypes[track->type()].volume;
1035 float v = mMasterVolume * typeVolume;
1036 float v_clamped = v * cblk->volume[0];
1037 if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
1038 left = int16_t(v_clamped);
1039 v_clamped = v * cblk->volume[1];
1040 if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
1041 right = int16_t(v_clamped);
1042 }
1043
1044 // XXX: these things DON'T need to be done each time
1045 mAudioMixer->setBufferProvider(track);
1046 mAudioMixer->enable(AudioMixer::MIXING);
1047
1048 int param;
1049 if ( track->mFillingUpStatus == Track::FS_FILLED) {
1050 // no ramp for the first volume setting
1051 track->mFillingUpStatus = Track::FS_ACTIVE;
1052 if (track->mState == TrackBase::RESUMING) {
1053 track->mState = TrackBase::ACTIVE;
1054 param = AudioMixer::RAMP_VOLUME;
1055 } else {
1056 param = AudioMixer::VOLUME;
1057 }
1058 } else {
1059 param = AudioMixer::RAMP_VOLUME;
1060 }
1061 mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
1062 mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
1063 mAudioMixer->setParameter(
1064 AudioMixer::TRACK,
1065 AudioMixer::FORMAT, track->format());
1066 mAudioMixer->setParameter(
1067 AudioMixer::TRACK,
1068 AudioMixer::CHANNEL_COUNT, track->channelCount());
1069 mAudioMixer->setParameter(
1070 AudioMixer::RESAMPLE,
1071 AudioMixer::SAMPLE_RATE,
1072 int(cblk->sampleRate));
1073
1074 // reset retry count
1075 track->mRetryCount = kMaxTrackRetries;
1076 enabledTracks++;
1077 } else {
1078 //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
1079 if (track->isStopped()) {
1080 track->reset();
1081 }
1082 if (track->isTerminated() || track->isStopped() || track->isPaused()) {
1083 // We have consumed all the buffers of this track.
1084 // Remove it from the list of active tracks.
1085 LOGV("remove(%d) from active list", track->name());
1086 tracksToRemove.add(track);
1087 } else {
1088 // No buffers for this track. Give it a few chances to
1089 // fill a buffer, then remove it from active list.
1090 if (--(track->mRetryCount) <= 0) {
1091 LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
1092 tracksToRemove.add(track);
1093 }
1094 }
1095 // LOGV("disable(%d)", track->name());
1096 mAudioMixer->disable(AudioMixer::MIXING);
1097 }
1098 }
1099
1100 // remove all the tracks that need to be...
1101 count = tracksToRemove.size();
1102 if (UNLIKELY(count)) {
1103 for (size_t i=0 ; i<count ; i++) {
1104 const sp<Track>& track = tracksToRemove[i];
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001105 removeActiveTrack_l(track);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001106 if (track->isTerminated()) {
1107 mTracks.remove(track);
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001108 deleteTrackName_l(track->mName);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001109 }
1110 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001111 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001112 }
1113
1114 if (LIKELY(enabledTracks)) {
1115 // mix buffers...
1116 mAudioMixer->process(curBuf);
1117
1118#ifdef WITH_A2DP
1119 if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
1120 if (!outputTrackActive) {
1121 LOGV("starting output track in mixer for output %d", mOutputType);
1122 mOutputTrack->start();
1123 outputTrackActive = true;
1124 }
1125 mOutputTrack->write(curBuf, mFrameCount);
1126 }
1127#endif
1128
1129 // output audio to hardware
1130 mLastWriteTime = systemTime();
1131 mInWrite = true;
1132 mOutput->write(curBuf, mixBufferSize);
1133 mNumWrites++;
1134 mInWrite = false;
1135 mStandby = false;
1136 nsecs_t temp = systemTime();
1137 standbyTime = temp + kStandbyTimeInNsecs;
1138 nsecs_t delta = temp - mLastWriteTime;
1139 if (delta > maxPeriod) {
1140 LOGW("write blocked for %llu msecs", ns2ms(delta));
1141 mNumDelayedWrites++;
1142 }
1143 sleepTime = kBufferRecoveryInUsecs;
1144 } else {
1145#ifdef WITH_A2DP
1146 if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
1147 if (outputTrackActive) {
1148 mOutputTrack->write(curBuf, 0);
1149 if (mOutputTrack->bufferQueueEmpty()) {
1150 mOutputTrack->stop();
1151 outputTrackActive = false;
1152 } else {
1153 standbyTime = systemTime() + kStandbyTimeInNsecs;
1154 }
1155 }
1156 }
1157#endif
1158 // There was nothing to mix this round, which means all
1159 // active tracks were late. Sleep a little bit to give
1160 // them another chance. If we're too late, the audio
1161 // hardware will zero-fill for us.
1162 //LOGV("no buffers - usleep(%lu)", sleepTime);
1163 usleep(sleepTime);
1164 if (sleepTime < kMaxBufferRecoveryInUsecs) {
1165 sleepTime += kBufferRecoveryInUsecs;
1166 }
1167 }
1168
1169 // finally let go of all our tracks, without the lock held
1170 // since we can't guarantee the destructors won't acquire that
1171 // same lock.
1172 tracksToRemove.clear();
1173 } while (true);
1174
1175 return false;
1176}
1177
1178status_t AudioFlinger::MixerThread::readyToRun()
1179{
1180 if (mSampleRate == 0) {
1181 LOGE("No working audio driver found.");
1182 return NO_INIT;
1183 }
1184 LOGI("AudioFlinger's thread ready to run for output %d", mOutputType);
1185 return NO_ERROR;
1186}
1187
1188void AudioFlinger::MixerThread::onFirstRef()
1189{
1190 const size_t SIZE = 256;
1191 char buffer[SIZE];
1192
1193 snprintf(buffer, SIZE, "Mixer Thread for output %d", mOutputType);
1194
1195 run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
1196}
1197
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001198// MixerThread::createTrack_l() must be called with AudioFlinger::mLock held
1199sp<AudioFlinger::MixerThread::Track> AudioFlinger::MixerThread::createTrack_l(
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001200 const sp<AudioFlinger::Client>& client,
1201 int streamType,
1202 uint32_t sampleRate,
1203 int format,
1204 int channelCount,
1205 int frameCount,
1206 const sp<IMemory>& sharedBuffer,
1207 status_t *status)
1208{
1209 sp<Track> track;
1210 status_t lStatus;
1211
1212 // Resampler implementation limits input sampling rate to 2 x output sampling rate.
1213 if (sampleRate > MAX_SAMPLE_RATE || sampleRate > mSampleRate*2) {
1214 LOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
1215 lStatus = BAD_VALUE;
1216 goto Exit;
1217 }
1218
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001219
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001220 if (mSampleRate == 0) {
1221 LOGE("Audio driver not initialized.");
1222 lStatus = NO_INIT;
1223 goto Exit;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001224 }
1225
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001226 track = new Track(this, client, streamType, sampleRate, format,
1227 channelCount, frameCount, sharedBuffer);
1228 if (track->getCblk() == NULL) {
1229 lStatus = NO_MEMORY;
1230 goto Exit;
1231 }
1232 mTracks.add(track);
1233 lStatus = NO_ERROR;
1234
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001235Exit:
1236 if(status) {
1237 *status = lStatus;
1238 }
1239 return track;
1240}
1241
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001242// getTracks_l() must be called with AudioFlinger::mLock held
1243void AudioFlinger::MixerThread::getTracks_l(
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001244 SortedVector < sp<Track> >& tracks,
1245 SortedVector < wp<Track> >& activeTracks)
1246{
1247 size_t size = mTracks.size();
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001248 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 -08001249 for (size_t i = 0; i < size; i++) {
1250 sp<Track> t = mTracks[i];
1251 if (AudioSystem::routedToA2dpOutput(t->mStreamType)) {
1252 tracks.add(t);
1253 int j = mActiveTracks.indexOf(t);
1254 if (j >= 0) {
1255 t = mActiveTracks[j].promote();
1256 if (t != NULL) {
1257 activeTracks.add(t);
1258 }
1259 }
1260 }
1261 }
1262
1263 size = activeTracks.size();
1264 for (size_t i = 0; i < size; i++) {
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001265 removeActiveTrack_l(activeTracks[i]);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001266 }
1267
1268 size = tracks.size();
1269 for (size_t i = 0; i < size; i++) {
1270 sp<Track> t = tracks[i];
1271 mTracks.remove(t);
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001272 deleteTrackName_l(t->name());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001273 }
1274}
1275
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001276// putTracks_l() must be called with AudioFlinger::mLock held
1277void AudioFlinger::MixerThread::putTracks_l(
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001278 SortedVector < sp<Track> >& tracks,
1279 SortedVector < wp<Track> >& activeTracks)
1280{
1281
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001282 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 -08001283
1284 size_t size = tracks.size();
1285 for (size_t i = 0; i < size ; i++) {
1286 sp<Track> t = tracks[i];
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001287 int name = getTrackName_l();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001288
1289 if (name < 0) return;
1290
1291 t->mName = name;
1292 t->mMixerThread = this;
1293 mTracks.add(t);
1294
1295 int j = activeTracks.indexOf(t);
1296 if (j >= 0) {
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001297 addActiveTrack_l(t);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001298 }
1299 }
1300}
1301
1302uint32_t AudioFlinger::MixerThread::sampleRate() const
1303{
1304 return mSampleRate;
1305}
1306
1307int AudioFlinger::MixerThread::channelCount() const
1308{
1309 return mChannelCount;
1310}
1311
1312int AudioFlinger::MixerThread::format() const
1313{
1314 return mFormat;
1315}
1316
1317size_t AudioFlinger::MixerThread::frameCount() const
1318{
1319 return mFrameCount;
1320}
1321
1322uint32_t AudioFlinger::MixerThread::latency() const
1323{
1324 if (mOutput) {
1325 return mOutput->latency();
1326 }
1327 else {
1328 return 0;
1329 }
1330}
1331
1332status_t AudioFlinger::MixerThread::setMasterVolume(float value)
1333{
1334 mMasterVolume = value;
1335 return NO_ERROR;
1336}
1337
1338status_t AudioFlinger::MixerThread::setMasterMute(bool muted)
1339{
1340 mMasterMute = muted;
1341 return NO_ERROR;
1342}
1343
1344float AudioFlinger::MixerThread::masterVolume() const
1345{
1346 return mMasterVolume;
1347}
1348
1349bool AudioFlinger::MixerThread::masterMute() const
1350{
1351 return mMasterMute;
1352}
1353
1354status_t AudioFlinger::MixerThread::setStreamVolume(int stream, float value)
1355{
1356 mStreamTypes[stream].volume = value;
1357 return NO_ERROR;
1358}
1359
1360status_t AudioFlinger::MixerThread::setStreamMute(int stream, bool muted)
1361{
1362 mStreamTypes[stream].mute = muted;
1363 return NO_ERROR;
1364}
1365
1366float AudioFlinger::MixerThread::streamVolume(int stream) const
1367{
1368 return mStreamTypes[stream].volume;
1369}
1370
1371bool AudioFlinger::MixerThread::streamMute(int stream) const
1372{
1373 return mStreamTypes[stream].mute;
1374}
1375
1376bool AudioFlinger::MixerThread::isMusicActive() const
1377{
1378 size_t count = mActiveTracks.size();
1379 for (size_t i = 0 ; i < count ; ++i) {
1380 sp<Track> t = mActiveTracks[i].promote();
1381 if (t == 0) continue;
1382 Track* const track = t.get();
1383 if (t->mStreamType == AudioSystem::MUSIC)
1384 return true;
1385 }
1386 return false;
1387}
1388
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001389// addTrack_l() must be called with AudioFlinger::mLock held
1390status_t AudioFlinger::MixerThread::addTrack_l(const sp<Track>& track)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001391{
1392 status_t status = ALREADY_EXISTS;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001393
1394 // here the track could be either new, or restarted
1395 // in both cases "unstop" the track
1396 if (track->isPaused()) {
1397 track->mState = TrackBase::RESUMING;
1398 LOGV("PAUSED => RESUMING (%d)", track->name());
1399 } else {
1400 track->mState = TrackBase::ACTIVE;
1401 LOGV("? => ACTIVE (%d)", track->name());
1402 }
1403 // set retry count for buffer fill
1404 track->mRetryCount = kMaxTrackStartupRetries;
1405 if (mActiveTracks.indexOf(track) < 0) {
1406 // the track is newly added, make sure it fills up all its
1407 // buffers before playing. This is to ensure the client will
1408 // effectively get the latency it requested.
1409 track->mFillingUpStatus = Track::FS_FILLING;
1410 track->mResetDone = false;
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001411 addActiveTrack_l(track);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001412 status = NO_ERROR;
1413 }
1414
1415 LOGV("mWaitWorkCV.broadcast");
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001416 mAudioFlinger->mWaitWorkCV.broadcast();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001417
1418 return status;
1419}
1420
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001421// removeTrack_l() must be called with AudioFlinger::mLock held
1422void AudioFlinger::MixerThread::removeTrack_l(wp<Track> track, int name)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001423{
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001424 sp<Track> t = track.promote();
1425 if (t!=NULL && (t->mState <= TrackBase::STOPPED)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001426 t->reset();
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001427 deleteTrackName_l(name);
1428 removeActiveTrack_l(track);
1429 mAudioFlinger->mWaitWorkCV.broadcast();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001430 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001431}
1432
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001433// destroyTrack_l() must be called with AudioFlinger::mLock held
1434void AudioFlinger::MixerThread::destroyTrack_l(const sp<Track>& track)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001435{
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001436 track->mState = TrackBase::TERMINATED;
1437 if (mActiveTracks.indexOf(track) < 0) {
1438 LOGV("remove track (%d) and delete from mixer", track->name());
1439 mTracks.remove(track);
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001440 deleteTrackName_l(track->name());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001441 }
1442}
1443
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001444// addActiveTrack_l() must be called with AudioFlinger::mLock held
1445void AudioFlinger::MixerThread::addActiveTrack_l(const wp<Track>& t)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001446{
1447 mActiveTracks.add(t);
1448
1449 // Force routing to speaker for certain stream types
1450 // The forced routing to speaker is managed by hardware mixer
1451 if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
1452 sp<Track> track = t.promote();
1453 if (track == NULL) return;
1454
1455 if (streamForcedToSpeaker(track->type())) {
1456 mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_ADDED);
1457 }
1458 }
1459}
1460
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001461// removeActiveTrack_l() must be called with AudioFlinger::mLock held
1462void AudioFlinger::MixerThread::removeActiveTrack_l(const wp<Track>& t)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001463{
1464 mActiveTracks.remove(t);
1465
1466 // Force routing to speaker for certain stream types
1467 // The forced routing to speaker is managed by hardware mixer
1468 if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
1469 sp<Track> track = t.promote();
1470 if (track == NULL) return;
1471
1472 if (streamForcedToSpeaker(track->type())) {
1473 mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_REMOVED);
1474 }
1475 }
1476}
1477
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001478// getTrackName_l() must be called with AudioFlinger::mLock held
1479int AudioFlinger::MixerThread::getTrackName_l()
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001480{
1481 return mAudioMixer->getTrackName();
1482}
1483
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001484// deleteTrackName_l() must be called with AudioFlinger::mLock held
1485void AudioFlinger::MixerThread::deleteTrackName_l(int name)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001486{
1487 mAudioMixer->deleteTrackName(name);
1488}
1489
1490size_t AudioFlinger::MixerThread::getOutputFrameCount()
1491{
1492 return mOutput->bufferSize() / mOutput->channelCount() / sizeof(int16_t);
1493}
1494
1495// ----------------------------------------------------------------------------
1496
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001497// TrackBase constructor must be called with AudioFlinger::mLock held
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001498AudioFlinger::MixerThread::TrackBase::TrackBase(
1499 const sp<MixerThread>& mixerThread,
1500 const sp<Client>& client,
1501 int streamType,
1502 uint32_t sampleRate,
1503 int format,
1504 int channelCount,
1505 int frameCount,
1506 uint32_t flags,
1507 const sp<IMemory>& sharedBuffer)
1508 : RefBase(),
1509 mMixerThread(mixerThread),
1510 mClient(client),
1511 mStreamType(streamType),
1512 mFrameCount(0),
1513 mState(IDLE),
1514 mClientTid(-1),
1515 mFormat(format),
1516 mFlags(flags & ~SYSTEM_FLAGS_MASK)
1517{
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001518 mName = mixerThread->getTrackName_l();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001519 LOGV("TrackBase contructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
1520 if (mName < 0) {
1521 LOGE("no more track names availlable");
1522 return;
1523 }
1524
1525 LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
1526
1527 // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
1528 size_t size = sizeof(audio_track_cblk_t);
1529 size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
1530 if (sharedBuffer == 0) {
1531 size += bufferSize;
1532 }
1533
1534 if (client != NULL) {
1535 mCblkMemory = client->heap()->allocate(size);
1536 if (mCblkMemory != 0) {
1537 mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
1538 if (mCblk) { // construct the shared structure in-place.
1539 new(mCblk) audio_track_cblk_t();
1540 // clear all buffers
1541 mCblk->frameCount = frameCount;
1542 mCblk->sampleRate = sampleRate;
1543 mCblk->channels = channelCount;
1544 if (sharedBuffer == 0) {
1545 mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
1546 memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
1547 // Force underrun condition to avoid false underrun callback until first data is
1548 // written to buffer
1549 mCblk->flowControlFlag = 1;
1550 } else {
1551 mBuffer = sharedBuffer->pointer();
1552 }
1553 mBufferEnd = (uint8_t *)mBuffer + bufferSize;
1554 }
1555 } else {
1556 LOGE("not enough memory for AudioTrack size=%u", size);
1557 client->heap()->dump("AudioTrack");
1558 return;
1559 }
1560 } else {
1561 mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
1562 if (mCblk) { // construct the shared structure in-place.
1563 new(mCblk) audio_track_cblk_t();
1564 // clear all buffers
1565 mCblk->frameCount = frameCount;
1566 mCblk->sampleRate = sampleRate;
1567 mCblk->channels = channelCount;
1568 mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
1569 memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
1570 // Force underrun condition to avoid false underrun callback until first data is
1571 // written to buffer
1572 mCblk->flowControlFlag = 1;
1573 mBufferEnd = (uint8_t *)mBuffer + bufferSize;
1574 }
1575 }
1576}
1577
1578AudioFlinger::MixerThread::TrackBase::~TrackBase()
1579{
1580 if (mCblk) {
1581 mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
1582 }
1583 mCblkMemory.clear(); // and free the shared memory
1584 mClient.clear();
1585}
1586
1587void AudioFlinger::MixerThread::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
1588{
1589 buffer->raw = 0;
1590 mFrameCount = buffer->frameCount;
1591 step();
1592 buffer->frameCount = 0;
1593}
1594
1595bool AudioFlinger::MixerThread::TrackBase::step() {
1596 bool result;
1597 audio_track_cblk_t* cblk = this->cblk();
1598
1599 result = cblk->stepServer(mFrameCount);
1600 if (!result) {
1601 LOGV("stepServer failed acquiring cblk mutex");
1602 mFlags |= STEPSERVER_FAILED;
1603 }
1604 return result;
1605}
1606
1607void AudioFlinger::MixerThread::TrackBase::reset() {
1608 audio_track_cblk_t* cblk = this->cblk();
1609
1610 cblk->user = 0;
1611 cblk->server = 0;
1612 cblk->userBase = 0;
1613 cblk->serverBase = 0;
1614 mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
1615 LOGV("TrackBase::reset");
1616}
1617
1618sp<IMemory> AudioFlinger::MixerThread::TrackBase::getCblk() const
1619{
1620 return mCblkMemory;
1621}
1622
1623int AudioFlinger::MixerThread::TrackBase::sampleRate() const {
1624 return mCblk->sampleRate;
1625}
1626
1627int AudioFlinger::MixerThread::TrackBase::channelCount() const {
1628 return mCblk->channels;
1629}
1630
1631void* AudioFlinger::MixerThread::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
1632 audio_track_cblk_t* cblk = this->cblk();
1633 int16_t *bufferStart = (int16_t *)mBuffer + (offset-cblk->serverBase)*cblk->channels;
1634 int16_t *bufferEnd = bufferStart + frames * cblk->channels;
1635
1636 // Check validity of returned pointer in case the track control block would have been corrupted.
1637 if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd) {
1638 LOGW("TrackBase::getBuffer buffer out of range:\n start: %p, end %p , mBuffer %p mBufferEnd %p\n \
1639 server %d, serverBase %d, user %d, userBase %d",
1640 bufferStart, bufferEnd, mBuffer, mBufferEnd,
1641 cblk->server, cblk->serverBase, cblk->user, cblk->userBase);
1642 return 0;
1643 }
1644
1645 return bufferStart;
1646}
1647
1648// ----------------------------------------------------------------------------
1649
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001650// Track constructor must be called with AudioFlinger::mLock held
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001651AudioFlinger::MixerThread::Track::Track(
1652 const sp<MixerThread>& mixerThread,
1653 const sp<Client>& client,
1654 int streamType,
1655 uint32_t sampleRate,
1656 int format,
1657 int channelCount,
1658 int frameCount,
1659 const sp<IMemory>& sharedBuffer)
1660 : TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, 0, sharedBuffer)
1661{
1662 mVolume[0] = 1.0f;
1663 mVolume[1] = 1.0f;
1664 mMute = false;
1665 mSharedBuffer = sharedBuffer;
1666}
1667
1668AudioFlinger::MixerThread::Track::~Track()
1669{
1670 wp<Track> weak(this); // never create a strong ref from the dtor
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001671 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001672 mState = TERMINATED;
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001673 mMixerThread->removeTrack_l(weak, mName);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001674}
1675
1676void AudioFlinger::MixerThread::Track::destroy()
1677{
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001678 // NOTE: destroyTrack_l() can remove a strong reference to this Track
1679 // by removing it from mTracks vector, so there is a risk that this Tracks's
1680 // desctructor is called. As the destructor needs to lock AudioFlinger::mLock,
1681 // we must acquire a strong reference on this Track before locking AudioFlinger::mLock
1682 // here so that the destructor is called only when exiting this function.
1683 // On the other hand, as long as Track::destroy() is only called by
1684 // TrackHandle destructor, the TrackHandle still holds a strong ref on
1685 // this Track with its member mTrack.
1686 sp<Track> keep(this);
1687 { // scope for AudioFlinger::mLock
1688 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
1689 mMixerThread->destroyTrack_l(this);
1690 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001691}
1692
1693void AudioFlinger::MixerThread::Track::dump(char* buffer, size_t size)
1694{
1695 snprintf(buffer, size, " %5d %5d %3u %3u %3u %3u %1d %1d %1d %5u %5u %5u %04x %04x\n",
1696 mName - AudioMixer::TRACK0,
1697 (mClient == NULL) ? getpid() : mClient->pid(),
1698 mStreamType,
1699 mFormat,
1700 mCblk->channels,
1701 mFrameCount,
1702 mState,
1703 mMute,
1704 mFillingUpStatus,
1705 mCblk->sampleRate,
1706 mCblk->volume[0],
1707 mCblk->volume[1],
1708 mCblk->server,
1709 mCblk->user);
1710}
1711
1712status_t AudioFlinger::MixerThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
1713{
1714 audio_track_cblk_t* cblk = this->cblk();
1715 uint32_t framesReady;
1716 uint32_t framesReq = buffer->frameCount;
1717
1718 // Check if last stepServer failed, try to step now
1719 if (mFlags & TrackBase::STEPSERVER_FAILED) {
1720 if (!step()) goto getNextBuffer_exit;
1721 LOGV("stepServer recovered");
1722 mFlags &= ~TrackBase::STEPSERVER_FAILED;
1723 }
1724
1725 framesReady = cblk->framesReady();
1726
1727 if (LIKELY(framesReady)) {
1728 uint32_t s = cblk->server;
1729 uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
1730
1731 bufferEnd = (cblk->loopEnd < bufferEnd) ? cblk->loopEnd : bufferEnd;
1732 if (framesReq > framesReady) {
1733 framesReq = framesReady;
1734 }
1735 if (s + framesReq > bufferEnd) {
1736 framesReq = bufferEnd - s;
1737 }
1738
1739 buffer->raw = getBuffer(s, framesReq);
1740 if (buffer->raw == 0) goto getNextBuffer_exit;
1741
1742 buffer->frameCount = framesReq;
1743 return NO_ERROR;
1744 }
1745
1746getNextBuffer_exit:
1747 buffer->raw = 0;
1748 buffer->frameCount = 0;
1749 return NOT_ENOUGH_DATA;
1750}
1751
1752bool AudioFlinger::MixerThread::Track::isReady() const {
1753 if (mFillingUpStatus != FS_FILLING) return true;
1754
1755 if (mCblk->framesReady() >= mCblk->frameCount ||
1756 mCblk->forceReady) {
1757 mFillingUpStatus = FS_FILLED;
1758 mCblk->forceReady = 0;
1759 LOGV("Track::isReady() track %d for output %d", mName, mMixerThread->mOutputType);
1760 return true;
1761 }
1762 return false;
1763}
1764
1765status_t AudioFlinger::MixerThread::Track::start()
1766{
1767 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 -07001768 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
1769 mMixerThread->addTrack_l(this);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001770 return NO_ERROR;
1771}
1772
1773void AudioFlinger::MixerThread::Track::stop()
1774{
1775 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 -07001776 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001777 if (mState > STOPPED) {
1778 mState = STOPPED;
1779 // If the track is not active (PAUSED and buffers full), flush buffers
1780 if (mMixerThread->mActiveTracks.indexOf(this) < 0) {
1781 reset();
1782 }
1783 LOGV("(> STOPPED) => STOPPED (%d)", mName);
1784 }
1785}
1786
1787void AudioFlinger::MixerThread::Track::pause()
1788{
1789 LOGV("pause(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001790 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001791 if (mState == ACTIVE || mState == RESUMING) {
1792 mState = PAUSING;
1793 LOGV("ACTIVE/RESUMING => PAUSING (%d)", mName);
1794 }
1795}
1796
1797void AudioFlinger::MixerThread::Track::flush()
1798{
1799 LOGV("flush(%d)", mName);
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001800 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001801 if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
1802 return;
1803 }
1804 // No point remaining in PAUSED state after a flush => go to
1805 // STOPPED state
1806 mState = STOPPED;
1807
1808 // NOTE: reset() will reset cblk->user and cblk->server with
1809 // the risk that at the same time, the AudioMixer is trying to read
1810 // data. In this case, getNextBuffer() would return a NULL pointer
1811 // as audio buffer => the AudioMixer code MUST always test that pointer
1812 // returned by getNextBuffer() is not NULL!
1813 reset();
1814}
1815
1816void AudioFlinger::MixerThread::Track::reset()
1817{
1818 // Do not reset twice to avoid discarding data written just after a flush and before
1819 // the audioflinger thread detects the track is stopped.
1820 if (!mResetDone) {
1821 TrackBase::reset();
1822 // Force underrun condition to avoid false underrun callback until first data is
1823 // written to buffer
1824 mCblk->flowControlFlag = 1;
1825 mCblk->forceReady = 0;
1826 mFillingUpStatus = FS_FILLING;
1827 mResetDone = true;
1828 }
1829}
1830
1831void AudioFlinger::MixerThread::Track::mute(bool muted)
1832{
1833 mMute = muted;
1834}
1835
1836void AudioFlinger::MixerThread::Track::setVolume(float left, float right)
1837{
1838 mVolume[0] = left;
1839 mVolume[1] = right;
1840}
1841
1842// ----------------------------------------------------------------------------
1843
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001844// RecordTrack constructor must be called with AudioFlinger::mLock held
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001845AudioFlinger::MixerThread::RecordTrack::RecordTrack(
1846 const sp<MixerThread>& mixerThread,
1847 const sp<Client>& client,
1848 int streamType,
1849 uint32_t sampleRate,
1850 int format,
1851 int channelCount,
1852 int frameCount,
1853 uint32_t flags)
1854 : TrackBase(mixerThread, client, streamType, sampleRate, format,
1855 channelCount, frameCount, flags, 0),
1856 mOverflow(false)
1857{
1858}
1859
1860AudioFlinger::MixerThread::RecordTrack::~RecordTrack()
1861{
The Android Open Source Project22f8def2009-03-09 11:52:12 -07001862 Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
1863 mMixerThread->deleteTrackName_l(mName);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001864}
1865
1866status_t AudioFlinger::MixerThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
1867{
1868 audio_track_cblk_t* cblk = this->cblk();
1869 uint32_t framesAvail;
1870 uint32_t framesReq = buffer->frameCount;
1871
1872 // Check if last stepServer failed, try to step now
1873 if (mFlags & TrackBase::STEPSERVER_FAILED) {
1874 if (!step()) goto getNextBuffer_exit;
1875 LOGV("stepServer recovered");
1876 mFlags &= ~TrackBase::STEPSERVER_FAILED;
1877 }
1878
1879 framesAvail = cblk->framesAvailable_l();
1880
1881 if (LIKELY(framesAvail)) {
1882 uint32_t s = cblk->server;
1883 uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
1884
1885 if (framesReq > framesAvail) {
1886 framesReq = framesAvail;
1887 }
1888 if (s + framesReq > bufferEnd) {
1889 framesReq = bufferEnd - s;
1890 }
1891
1892 buffer->raw = getBuffer(s, framesReq);
1893 if (buffer->raw == 0) goto getNextBuffer_exit;
1894
1895 buffer->frameCount = framesReq;
1896 return NO_ERROR;
1897 }
1898
1899getNextBuffer_exit:
1900 buffer->raw = 0;
1901 buffer->frameCount = 0;
1902 return NOT_ENOUGH_DATA;
1903}
1904
1905status_t AudioFlinger::MixerThread::RecordTrack::start()
1906{
1907 return mMixerThread->mAudioFlinger->startRecord(this);
1908}
1909
1910void AudioFlinger::MixerThread::RecordTrack::stop()
1911{
1912 mMixerThread->mAudioFlinger->stopRecord(this);
1913 TrackBase::reset();
1914 // Force overerrun condition to avoid false overrun callback until first data is
1915 // read from buffer
1916 mCblk->flowControlFlag = 1;
1917}
1918
1919
1920// ----------------------------------------------------------------------------
1921
1922AudioFlinger::MixerThread::OutputTrack::OutputTrack(
1923 const sp<MixerThread>& mixerThread,
1924 uint32_t sampleRate,
1925 int format,
1926 int channelCount,
1927 int frameCount)
1928 : Track(mixerThread, NULL, AudioSystem::SYSTEM, sampleRate, format, channelCount, frameCount, NULL),
1929 mOutputMixerThread(mixerThread)
1930{
1931
1932 mCblk->out = 1;
1933 mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
1934 mCblk->volume[0] = mCblk->volume[1] = 0x1000;
1935 mOutBuffer.frameCount = 0;
1936 mCblk->bufferTimeoutMs = 10;
1937
1938 LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p",
1939 mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd);
1940
1941}
1942
1943AudioFlinger::MixerThread::OutputTrack::~OutputTrack()
1944{
1945 stop();
1946}
1947
1948status_t AudioFlinger::MixerThread::OutputTrack::start()
1949{
1950 status_t status = Track::start();
1951
1952 mRetryCount = 127;
1953 return status;
1954}
1955
1956void AudioFlinger::MixerThread::OutputTrack::stop()
1957{
1958 Track::stop();
1959 clearBufferQueue();
1960 mOutBuffer.frameCount = 0;
1961}
1962
1963void AudioFlinger::MixerThread::OutputTrack::write(int16_t* data, uint32_t frames)
1964{
1965 Buffer *pInBuffer;
1966 Buffer inBuffer;
1967 uint32_t channels = mCblk->channels;
1968
1969 inBuffer.frameCount = frames;
1970 inBuffer.i16 = data;
1971
1972 if (mCblk->user == 0) {
1973 if (mOutputMixerThread->isMusicActive()) {
1974 mCblk->forceReady = 1;
1975 LOGV("OutputTrack::start() force ready");
1976 } else if (mCblk->frameCount > frames){
1977 if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
1978 uint32_t startFrames = (mCblk->frameCount - frames);
1979 LOGV("OutputTrack::start() write %d frames", startFrames);
1980 pInBuffer = new Buffer;
1981 pInBuffer->mBuffer = new int16_t[startFrames * channels];
1982 pInBuffer->frameCount = startFrames;
1983 pInBuffer->i16 = pInBuffer->mBuffer;
1984 memset(pInBuffer->raw, 0, startFrames * channels * sizeof(int16_t));
1985 mBufferQueue.add(pInBuffer);
1986 } else {
1987 LOGW ("OutputTrack::write() no more buffers");
1988 }
1989 }
1990 }
1991
1992 while (1) {
1993 // First write pending buffers, then new data
1994 if (mBufferQueue.size()) {
1995 pInBuffer = mBufferQueue.itemAt(0);
1996 } else {
1997 pInBuffer = &inBuffer;
1998 }
1999
2000 if (pInBuffer->frameCount == 0) {
2001 break;
2002 }
2003
2004 if (mOutBuffer.frameCount == 0) {
2005 mOutBuffer.frameCount = pInBuffer->frameCount;
2006 if (obtainBuffer(&mOutBuffer) == (status_t)AudioTrack::NO_MORE_BUFFERS) {
2007 break;
2008 }
2009 }
2010
2011 uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : pInBuffer->frameCount;
2012 memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channels * sizeof(int16_t));
2013 mCblk->stepUser(outFrames);
2014 pInBuffer->frameCount -= outFrames;
2015 pInBuffer->i16 += outFrames * channels;
2016 mOutBuffer.frameCount -= outFrames;
2017 mOutBuffer.i16 += outFrames * channels;
2018
2019 if (pInBuffer->frameCount == 0) {
2020 if (mBufferQueue.size()) {
2021 mBufferQueue.removeAt(0);
2022 delete [] pInBuffer->mBuffer;
2023 delete pInBuffer;
2024 } else {
2025 break;
2026 }
2027 }
2028 }
2029
2030 // If we could not write all frames, allocate a buffer and queue it for next time.
2031 if (inBuffer.frameCount) {
2032 if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
2033 pInBuffer = new Buffer;
2034 pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channels];
2035 pInBuffer->frameCount = inBuffer.frameCount;
2036 pInBuffer->i16 = pInBuffer->mBuffer;
2037 memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channels * sizeof(int16_t));
2038 mBufferQueue.add(pInBuffer);
2039 } else {
2040 LOGW("OutputTrack::write() no more buffers");
2041 }
2042 }
2043
2044 // Calling write() with a 0 length buffer, means that no more data will be written:
2045 // If no more buffers are pending, fill output track buffer to make sure it is started
2046 // by output mixer.
2047 if (frames == 0 && mBufferQueue.size() == 0 && mCblk->user < mCblk->frameCount) {
2048 frames = mCblk->frameCount - mCblk->user;
2049 pInBuffer = new Buffer;
2050 pInBuffer->mBuffer = new int16_t[frames * channels];
2051 pInBuffer->frameCount = frames;
2052 pInBuffer->i16 = pInBuffer->mBuffer;
2053 memset(pInBuffer->raw, 0, frames * channels * sizeof(int16_t));
2054 mBufferQueue.add(pInBuffer);
2055 }
2056
2057}
2058
2059status_t AudioFlinger::MixerThread::OutputTrack::obtainBuffer(AudioBufferProvider::Buffer* buffer)
2060{
2061 int active;
2062 int timeout = 0;
2063 status_t result;
2064 audio_track_cblk_t* cblk = mCblk;
2065 uint32_t framesReq = buffer->frameCount;
2066
2067 LOGV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
2068 buffer->frameCount = 0;
2069
2070 uint32_t framesAvail = cblk->framesAvailable();
2071
2072 if (framesAvail == 0) {
2073 return AudioTrack::NO_MORE_BUFFERS;
2074 }
2075
2076 if (framesReq > framesAvail) {
2077 framesReq = framesAvail;
2078 }
2079
2080 uint32_t u = cblk->user;
2081 uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
2082
2083 if (u + framesReq > bufferEnd) {
2084 framesReq = bufferEnd - u;
2085 }
2086
2087 buffer->frameCount = framesReq;
2088 buffer->raw = (void *)cblk->buffer(u);
2089 return NO_ERROR;
2090}
2091
2092
2093void AudioFlinger::MixerThread::OutputTrack::clearBufferQueue()
2094{
2095 size_t size = mBufferQueue.size();
2096 Buffer *pBuffer;
2097
2098 for (size_t i = 0; i < size; i++) {
2099 pBuffer = mBufferQueue.itemAt(i);
2100 delete [] pBuffer->mBuffer;
2101 delete pBuffer;
2102 }
2103 mBufferQueue.clear();
2104}
2105
2106// ----------------------------------------------------------------------------
2107
2108AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
2109 : RefBase(),
2110 mAudioFlinger(audioFlinger),
2111 mMemoryDealer(new MemoryDealer(1024*1024)),
2112 mPid(pid)
2113{
2114 // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
2115}
2116
2117AudioFlinger::Client::~Client()
2118{
2119 mAudioFlinger->removeClient(mPid);
2120}
2121
2122const sp<MemoryDealer>& AudioFlinger::Client::heap() const
2123{
2124 return mMemoryDealer;
2125}
2126
2127// ----------------------------------------------------------------------------
2128
2129AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::MixerThread::Track>& track)
2130 : BnAudioTrack(),
2131 mTrack(track)
2132{
2133}
2134
2135AudioFlinger::TrackHandle::~TrackHandle() {
2136 // just stop the track on deletion, associated resources
2137 // will be freed from the main thread once all pending buffers have
2138 // been played. Unless it's not in the active track list, in which
2139 // case we free everything now...
2140 mTrack->destroy();
2141}
2142
2143status_t AudioFlinger::TrackHandle::start() {
2144 return mTrack->start();
2145}
2146
2147void AudioFlinger::TrackHandle::stop() {
2148 mTrack->stop();
2149}
2150
2151void AudioFlinger::TrackHandle::flush() {
2152 mTrack->flush();
2153}
2154
2155void AudioFlinger::TrackHandle::mute(bool e) {
2156 mTrack->mute(e);
2157}
2158
2159void AudioFlinger::TrackHandle::pause() {
2160 mTrack->pause();
2161}
2162
2163void AudioFlinger::TrackHandle::setVolume(float left, float right) {
2164 mTrack->setVolume(left, right);
2165}
2166
2167sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
2168 return mTrack->getCblk();
2169}
2170
2171status_t AudioFlinger::TrackHandle::onTransact(
2172 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2173{
2174 return BnAudioTrack::onTransact(code, data, reply, flags);
2175}
2176
2177// ----------------------------------------------------------------------------
2178
2179sp<IAudioRecord> AudioFlinger::openRecord(
2180 pid_t pid,
2181 int streamType,
2182 uint32_t sampleRate,
2183 int format,
2184 int channelCount,
2185 int frameCount,
2186 uint32_t flags,
2187 status_t *status)
2188{
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002189 sp<MixerThread::RecordTrack> recordTrack;
2190 sp<RecordHandle> recordHandle;
2191 sp<Client> client;
2192 wp<Client> wclient;
2193 AudioStreamIn* input = 0;
2194 int inFrameCount;
2195 size_t inputBufferSize;
2196 status_t lStatus;
2197
2198 // check calling permissions
2199 if (!recordingAllowed()) {
2200 lStatus = PERMISSION_DENIED;
2201 goto Exit;
2202 }
2203
2204 if (uint32_t(streamType) >= AudioRecord::NUM_STREAM_TYPES) {
2205 LOGE("invalid stream type");
2206 lStatus = BAD_VALUE;
2207 goto Exit;
2208 }
2209
2210 if (sampleRate > MAX_SAMPLE_RATE) {
2211 LOGE("Sample rate out of range");
2212 lStatus = BAD_VALUE;
2213 goto Exit;
2214 }
2215
2216 if (mAudioRecordThread == 0) {
2217 LOGE("Audio record thread not started");
2218 lStatus = NO_INIT;
2219 goto Exit;
2220 }
2221
2222
2223 // Check that audio input stream accepts requested audio parameters
2224 inputBufferSize = mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
2225 if (inputBufferSize == 0) {
2226 lStatus = BAD_VALUE;
2227 LOGE("Bad audio input parameters: sampling rate %u, format %d, channels %d", sampleRate, format, channelCount);
2228 goto Exit;
2229 }
2230
2231 // add client to list
The Android Open Source Project22f8def2009-03-09 11:52:12 -07002232 { // scope for mLock
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002233 Mutex::Autolock _l(mLock);
2234 wclient = mClients.valueFor(pid);
2235 if (wclient != NULL) {
2236 client = wclient.promote();
2237 } else {
2238 client = new Client(this, pid);
2239 mClients.add(pid, client);
2240 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -07002241
2242 // frameCount must be a multiple of input buffer size
2243 inFrameCount = inputBufferSize/channelCount/sizeof(short);
2244 frameCount = ((frameCount - 1)/inFrameCount + 1) * inFrameCount;
2245
2246 // create new record track. The record track uses one track in mHardwareMixerThread by convention.
2247 recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, streamType, sampleRate,
2248 format, channelCount, frameCount, flags);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002249 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002250 if (recordTrack->getCblk() == NULL) {
2251 recordTrack.clear();
2252 lStatus = NO_MEMORY;
2253 goto Exit;
2254 }
2255
2256 // return to handle to client
2257 recordHandle = new RecordHandle(recordTrack);
2258 lStatus = NO_ERROR;
2259
2260Exit:
2261 if (status) {
2262 *status = lStatus;
2263 }
2264 return recordHandle;
2265}
2266
2267status_t AudioFlinger::startRecord(MixerThread::RecordTrack* recordTrack) {
2268 if (mAudioRecordThread != 0) {
2269 return mAudioRecordThread->start(recordTrack);
2270 }
2271 return NO_INIT;
2272}
2273
2274void AudioFlinger::stopRecord(MixerThread::RecordTrack* recordTrack) {
2275 if (mAudioRecordThread != 0) {
2276 mAudioRecordThread->stop(recordTrack);
2277 }
2278}
2279
2280// ----------------------------------------------------------------------------
2281
2282AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::MixerThread::RecordTrack>& recordTrack)
2283 : BnAudioRecord(),
2284 mRecordTrack(recordTrack)
2285{
2286}
2287
2288AudioFlinger::RecordHandle::~RecordHandle() {
2289 stop();
2290}
2291
2292status_t AudioFlinger::RecordHandle::start() {
2293 LOGV("RecordHandle::start()");
2294 return mRecordTrack->start();
2295}
2296
2297void AudioFlinger::RecordHandle::stop() {
2298 LOGV("RecordHandle::stop()");
2299 mRecordTrack->stop();
2300}
2301
2302sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
2303 return mRecordTrack->getCblk();
2304}
2305
2306status_t AudioFlinger::RecordHandle::onTransact(
2307 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2308{
2309 return BnAudioRecord::onTransact(code, data, reply, flags);
2310}
2311
2312// ----------------------------------------------------------------------------
2313
2314AudioFlinger::AudioRecordThread::AudioRecordThread(AudioHardwareInterface* audioHardware) :
2315 mAudioHardware(audioHardware),
2316 mActive(false)
2317{
2318}
2319
2320AudioFlinger::AudioRecordThread::~AudioRecordThread()
2321{
2322}
2323
2324bool AudioFlinger::AudioRecordThread::threadLoop()
2325{
2326 LOGV("AudioRecordThread: start record loop");
2327 AudioBufferProvider::Buffer buffer;
2328 int inBufferSize = 0;
2329 int inFrameCount = 0;
2330 AudioStreamIn* input = 0;
2331
2332 mActive = 0;
2333
2334 // start recording
2335 while (!exitPending()) {
2336 if (!mActive) {
2337 mLock.lock();
2338 if (!mActive && !exitPending()) {
2339 LOGV("AudioRecordThread: loop stopping");
2340 if (input) {
2341 delete input;
2342 input = 0;
2343 }
2344 mRecordTrack.clear();
2345 mStopped.signal();
2346
2347 mWaitWorkCV.wait(mLock);
2348
2349 LOGV("AudioRecordThread: loop starting");
2350 if (mRecordTrack != 0) {
2351 input = mAudioHardware->openInputStream(mRecordTrack->format(),
2352 mRecordTrack->channelCount(),
2353 mRecordTrack->sampleRate(),
2354 &mStartStatus,
2355 (AudioSystem::audio_in_acoustics)(mRecordTrack->mFlags >> 16));
2356 if (input != 0) {
2357 inBufferSize = input->bufferSize();
2358 inFrameCount = inBufferSize/input->frameSize();
2359 }
2360 } else {
2361 mStartStatus = NO_INIT;
2362 }
2363 if (mStartStatus !=NO_ERROR) {
2364 LOGW("record start failed, status %d", mStartStatus);
2365 mActive = false;
2366 mRecordTrack.clear();
2367 }
2368 mWaitWorkCV.signal();
2369 }
2370 mLock.unlock();
2371 } else if (mRecordTrack != 0) {
2372
2373 buffer.frameCount = inFrameCount;
The Android Open Source Project22f8def2009-03-09 11:52:12 -07002374 if (LIKELY(mRecordTrack->getNextBuffer(&buffer) == NO_ERROR &&
2375 (int)buffer.frameCount == inFrameCount)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08002376 LOGV("AudioRecordThread read: %d frames", buffer.frameCount);
2377 ssize_t bytesRead = input->read(buffer.raw, inBufferSize);
2378 if (bytesRead < 0) {
2379 LOGE("Error reading audio input");
2380 sleep(1);
2381 }
2382 mRecordTrack->releaseBuffer(&buffer);
2383 mRecordTrack->overflow();
2384 }
2385
2386 // client isn't retrieving buffers fast enough
2387 else {
2388 if (!mRecordTrack->setOverflow())
2389 LOGW("AudioRecordThread: buffer overflow");
2390 // Release the processor for a while before asking for a new buffer.
2391 // This will give the application more chance to read from the buffer and
2392 // clear the overflow.
2393 usleep(5000);
2394 }
2395 }
2396 }
2397
2398
2399 if (input) {
2400 delete input;
2401 }
2402 mRecordTrack.clear();
2403
2404 return false;
2405}
2406
2407status_t AudioFlinger::AudioRecordThread::start(MixerThread::RecordTrack* recordTrack)
2408{
2409 LOGV("AudioRecordThread::start");
2410 AutoMutex lock(&mLock);
2411 mActive = true;
2412 // If starting the active track, just reset mActive in case a stop
2413 // was pending and exit
2414 if (recordTrack == mRecordTrack.get()) return NO_ERROR;
2415
2416 if (mRecordTrack != 0) return -EBUSY;
2417
2418 mRecordTrack = recordTrack;
2419
2420 // signal thread to start
2421 LOGV("Signal record thread");
2422 mWaitWorkCV.signal();
2423 mWaitWorkCV.wait(mLock);
2424 LOGV("Record started, status %d", mStartStatus);
2425 return mStartStatus;
2426}
2427
2428void AudioFlinger::AudioRecordThread::stop(MixerThread::RecordTrack* recordTrack) {
2429 LOGV("AudioRecordThread::stop");
2430 AutoMutex lock(&mLock);
2431 if (mActive && (recordTrack == mRecordTrack.get())) {
2432 mActive = false;
2433 mStopped.wait(mLock);
2434 }
2435}
2436
2437void AudioFlinger::AudioRecordThread::exit()
2438{
2439 LOGV("AudioRecordThread::exit");
2440 {
2441 AutoMutex lock(&mLock);
2442 requestExit();
2443 mWaitWorkCV.signal();
2444 }
2445 requestExitAndWait();
2446}
2447
2448status_t AudioFlinger::AudioRecordThread::dump(int fd, const Vector<String16>& args)
2449{
2450 const size_t SIZE = 256;
2451 char buffer[SIZE];
2452 String8 result;
2453 pid_t pid = 0;
2454
2455 if (mRecordTrack != 0 && mRecordTrack->mClient != 0) {
2456 snprintf(buffer, SIZE, "Record client pid: %d\n", mRecordTrack->mClient->pid());
2457 result.append(buffer);
2458 } else {
2459 result.append("No record client\n");
2460 }
2461 write(fd, result.string(), result.size());
2462 return NO_ERROR;
2463}
2464
2465status_t AudioFlinger::onTransact(
2466 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2467{
2468 return BnAudioFlinger::onTransact(code, data, reply, flags);
2469}
2470
2471// ----------------------------------------------------------------------------
2472void AudioFlinger::instantiate() {
2473 defaultServiceManager()->addService(
2474 String16("media.audio_flinger"), new AudioFlinger());
2475}
2476
2477}; // namespace android