blob: d11e13a7fb4aa50a774300a0ce6d2aec16430644 [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 ||
Eric Laurent933a9412009-03-27 18:18:46 -0700246 streamType == AudioSystem::NOTIFICATION ||
247 streamType == AudioSystem::ENFORCED_AUDIBLE);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800248}
249
250status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
251{
252 const size_t SIZE = 256;
253 char buffer[SIZE];
254 String8 result;
255
256 result.append("Clients:\n");
257 for (size_t i = 0; i < mClients.size(); ++i) {
258 wp<Client> wClient = mClients.valueAt(i);
259 if (wClient != 0) {
260 sp<Client> client = wClient.promote();
261 if (client != 0) {
262 snprintf(buffer, SIZE, " pid: %d\n", client->pid());
263 result.append(buffer);
264 }
265 }
266 }
267 write(fd, result.string(), result.size());
268 return NO_ERROR;
269}
270
271
272status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
273{
274 const size_t SIZE = 256;
275 char buffer[SIZE];
276 String8 result;
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700277 int hardwareStatus = mHardwareStatus;
278
279 if (hardwareStatus == AUDIO_HW_IDLE && mHardwareMixerThread->mStandby) {
280 hardwareStatus = AUDIO_HW_STANDBY;
281 }
282 snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800283 result.append(buffer);
284 write(fd, result.string(), result.size());
285 return NO_ERROR;
286}
287
288status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
289{
290 const size_t SIZE = 256;
291 char buffer[SIZE];
292 String8 result;
293 snprintf(buffer, SIZE, "Permission Denial: "
294 "can't dump AudioFlinger from pid=%d, uid=%d\n",
295 IPCThreadState::self()->getCallingPid(),
296 IPCThreadState::self()->getCallingUid());
297 result.append(buffer);
298 write(fd, result.string(), result.size());
299 return NO_ERROR;
300}
301
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700302static bool tryLock(Mutex& mutex)
303{
304 bool locked = false;
305 for (int i = 0; i < kDumpLockRetries; ++i) {
306 if (mutex.tryLock() == NO_ERROR) {
307 locked = true;
308 break;
309 }
310 usleep(kDumpLockSleep);
311 }
312 return locked;
313}
314
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800315status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
316{
317 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
318 dumpPermissionDenial(fd, args);
319 } else {
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700320 // get state of hardware lock
321 bool hardwareLocked = tryLock(mHardwareLock);
322 if (!hardwareLocked) {
323 String8 result(kHardwareLockedString);
324 write(fd, result.string(), result.size());
325 } else {
326 mHardwareLock.unlock();
327 }
328
329 bool locked = tryLock(mLock);
330
331 // failed to lock - AudioFlinger is probably deadlocked
332 if (!locked) {
333 String8 result(kDeadlockedString);
334 write(fd, result.string(), result.size());
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700335 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800336
337 dumpClients(fd, args);
338 dumpInternals(fd, args);
339 mHardwareMixerThread->dump(fd, args);
340#ifdef WITH_A2DP
341 mA2dpMixerThread->dump(fd, args);
342#endif
343
344 // dump record client
345 if (mAudioRecordThread != 0) mAudioRecordThread->dump(fd, args);
346
347 if (mAudioHardware) {
348 mAudioHardware->dumpState(fd, args);
349 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700350 if (locked) mLock.unlock();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800351 }
352 return NO_ERROR;
353}
354
355// IAudioFlinger interface
356
357
358sp<IAudioTrack> AudioFlinger::createTrack(
359 pid_t pid,
360 int streamType,
361 uint32_t sampleRate,
362 int format,
363 int channelCount,
364 int frameCount,
365 uint32_t flags,
366 const sp<IMemory>& sharedBuffer,
367 status_t *status)
368{
369 sp<MixerThread::Track> track;
370 sp<TrackHandle> trackHandle;
371 sp<Client> client;
372 wp<Client> wclient;
373 status_t lStatus;
374
375 if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
376 LOGE("invalid stream type");
377 lStatus = BAD_VALUE;
378 goto Exit;
379 }
380
381 {
382 Mutex::Autolock _l(mLock);
383
384 wclient = mClients.valueFor(pid);
385
386 if (wclient != NULL) {
387 client = wclient.promote();
388 } else {
389 client = new Client(this, pid);
390 mClients.add(pid, client);
391 }
392#ifdef WITH_A2DP
393 if (isA2dpEnabled() && AudioSystem::routedToA2dpOutput(streamType)) {
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700394 track = mA2dpMixerThread->createTrack_l(client, streamType, sampleRate, format,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800395 channelCount, frameCount, sharedBuffer, &lStatus);
396 } else
397#endif
398 {
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700399 track = mHardwareMixerThread->createTrack_l(client, streamType, sampleRate, format,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800400 channelCount, frameCount, sharedBuffer, &lStatus);
401 }
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700402 }
403 if (lStatus == NO_ERROR) {
404 trackHandle = new TrackHandle(track);
405 } else {
406 track.clear();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800407 }
408
409Exit:
410 if(status) {
411 *status = lStatus;
412 }
413 return trackHandle;
414}
415
416uint32_t AudioFlinger::sampleRate(int output) const
417{
418#ifdef WITH_A2DP
419 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
420 return mA2dpMixerThread->sampleRate();
421 }
422#endif
423 return mHardwareMixerThread->sampleRate();
424}
425
426int AudioFlinger::channelCount(int output) const
427{
428#ifdef WITH_A2DP
429 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
430 return mA2dpMixerThread->channelCount();
431 }
432#endif
433 return mHardwareMixerThread->channelCount();
434}
435
436int AudioFlinger::format(int output) const
437{
438#ifdef WITH_A2DP
439 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
440 return mA2dpMixerThread->format();
441 }
442#endif
443 return mHardwareMixerThread->format();
444}
445
446size_t AudioFlinger::frameCount(int output) const
447{
448#ifdef WITH_A2DP
449 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
450 return mA2dpMixerThread->frameCount();
451 }
452#endif
453 return mHardwareMixerThread->frameCount();
454}
455
456uint32_t AudioFlinger::latency(int output) const
457{
458#ifdef WITH_A2DP
459 if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
460 return mA2dpMixerThread->latency();
461 }
462#endif
463 return mHardwareMixerThread->latency();
464}
465
466status_t AudioFlinger::setMasterVolume(float value)
467{
468 // check calling permissions
469 if (!settingsAllowed()) {
470 return PERMISSION_DENIED;
471 }
472
473 // when hw supports master volume, don't scale in sw mixer
474 AutoMutex lock(mHardwareLock);
475 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
476 if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
477 value = 1.0f;
478 }
479 mHardwareStatus = AUDIO_HW_IDLE;
480 mHardwareMixerThread->setMasterVolume(value);
481#ifdef WITH_A2DP
482 mA2dpMixerThread->setMasterVolume(value);
483#endif
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700484
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800485 return NO_ERROR;
486}
487
488status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
489{
490 status_t err = NO_ERROR;
491
492 // check calling permissions
493 if (!settingsAllowed()) {
494 return PERMISSION_DENIED;
495 }
496 if ((mode < AudioSystem::MODE_CURRENT) || (mode >= AudioSystem::NUM_MODES)) {
497 LOGW("Illegal value: setRouting(%d, %u, %u)", mode, routes, mask);
498 return BAD_VALUE;
499 }
500
501#ifdef WITH_A2DP
502 LOGD("setRouting %d %d %d, tid %d, calling tid %d\n", mode, routes, mask, gettid(), IPCThreadState::self()->getCallingPid());
503 if (mode == AudioSystem::MODE_NORMAL &&
504 (mask & AudioSystem::ROUTE_BLUETOOTH_A2DP)) {
505 AutoMutex lock(&mLock);
506
507 bool enableA2dp = false;
508 if (routes & AudioSystem::ROUTE_BLUETOOTH_A2DP) {
509 enableA2dp = true;
510 }
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700511 if (mA2dpDisableCount > 0) {
512 mA2dpSuppressed = enableA2dp;
513 } else {
514 setA2dpEnabled_l(enableA2dp);
515 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800516 LOGV("setOutput done\n");
517 }
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700518 // setRouting() is always called at least for mode == AudioSystem::MODE_IN_CALL when
519 // SCO is enabled, whatever current mode is so we can safely handle A2DP disabling only
520 // in this case to avoid doing it several times.
521 if (mode == AudioSystem::MODE_IN_CALL &&
522 (mask & AudioSystem::ROUTE_BLUETOOTH_SCO)) {
523 AutoMutex lock(&mLock);
524 handleRouteDisablesA2dp_l(routes);
525 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800526#endif
527
528 // do nothing if only A2DP routing is affected
529 mask &= ~AudioSystem::ROUTE_BLUETOOTH_A2DP;
530 if (mask) {
531 AutoMutex lock(mHardwareLock);
532 mHardwareStatus = AUDIO_HW_GET_ROUTING;
533 uint32_t r;
534 err = mAudioHardware->getRouting(mode, &r);
535 if (err == NO_ERROR) {
536 r = (r & ~mask) | (routes & mask);
537 if (mode == AudioSystem::MODE_NORMAL ||
538 (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
539 mSavedRoute = r;
540 r |= mForcedRoute;
541 LOGV("setRouting mSavedRoute %08x mForcedRoute %08x\n", mSavedRoute, mForcedRoute);
542 }
543 mHardwareStatus = AUDIO_HW_SET_ROUTING;
544 err = mAudioHardware->setRouting(mode, r);
545 }
546 mHardwareStatus = AUDIO_HW_IDLE;
547 }
548 return err;
549}
550
551uint32_t AudioFlinger::getRouting(int mode) const
552{
553 uint32_t routes = 0;
554 if ((mode >= AudioSystem::MODE_CURRENT) && (mode < AudioSystem::NUM_MODES)) {
555 if (mode == AudioSystem::MODE_NORMAL ||
556 (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
557 routes = mSavedRoute;
558 } else {
559 mHardwareStatus = AUDIO_HW_GET_ROUTING;
560 mAudioHardware->getRouting(mode, &routes);
561 mHardwareStatus = AUDIO_HW_IDLE;
562 }
563 } else {
564 LOGW("Illegal value: getRouting(%d)", mode);
565 }
566 return routes;
567}
568
569status_t AudioFlinger::setMode(int mode)
570{
571 // check calling permissions
572 if (!settingsAllowed()) {
573 return PERMISSION_DENIED;
574 }
575 if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
576 LOGW("Illegal value: setMode(%d)", mode);
577 return BAD_VALUE;
578 }
579
580 AutoMutex lock(mHardwareLock);
581 mHardwareStatus = AUDIO_HW_SET_MODE;
582 status_t ret = mAudioHardware->setMode(mode);
583 mHardwareStatus = AUDIO_HW_IDLE;
584 return ret;
585}
586
587int AudioFlinger::getMode() const
588{
589 int mode = AudioSystem::MODE_INVALID;
590 mHardwareStatus = AUDIO_HW_SET_MODE;
591 mAudioHardware->getMode(&mode);
592 mHardwareStatus = AUDIO_HW_IDLE;
593 return mode;
594}
595
596status_t AudioFlinger::setMicMute(bool state)
597{
598 // check calling permissions
599 if (!settingsAllowed()) {
600 return PERMISSION_DENIED;
601 }
602
603 AutoMutex lock(mHardwareLock);
604 mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
605 status_t ret = mAudioHardware->setMicMute(state);
606 mHardwareStatus = AUDIO_HW_IDLE;
607 return ret;
608}
609
610bool AudioFlinger::getMicMute() const
611{
612 bool state = AudioSystem::MODE_INVALID;
613 mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
614 mAudioHardware->getMicMute(&state);
615 mHardwareStatus = AUDIO_HW_IDLE;
616 return state;
617}
618
619status_t AudioFlinger::setMasterMute(bool muted)
620{
621 // check calling permissions
622 if (!settingsAllowed()) {
623 return PERMISSION_DENIED;
624 }
625 mHardwareMixerThread->setMasterMute(muted);
626#ifdef WITH_A2DP
627 mA2dpMixerThread->setMasterMute(muted);
628#endif
629 return NO_ERROR;
630}
631
632float AudioFlinger::masterVolume() const
633{
634 return mHardwareMixerThread->masterVolume();
635}
636
637bool AudioFlinger::masterMute() const
638{
639 return mHardwareMixerThread->masterMute();
640}
641
642status_t AudioFlinger::setStreamVolume(int stream, float value)
643{
644 // check calling permissions
645 if (!settingsAllowed()) {
646 return PERMISSION_DENIED;
647 }
648
Eric Laurent933a9412009-03-27 18:18:46 -0700649 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES ||
650 uint32_t(stream) == AudioSystem::ENFORCED_AUDIBLE) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800651 return BAD_VALUE;
652 }
653
654 mHardwareMixerThread->setStreamVolume(stream, value);
655#ifdef WITH_A2DP
656 mA2dpMixerThread->setStreamVolume(stream, value);
657#endif
658
659 status_t ret = NO_ERROR;
660 if (stream == AudioSystem::VOICE_CALL ||
661 stream == AudioSystem::BLUETOOTH_SCO) {
662
663 if (stream == AudioSystem::VOICE_CALL) {
664 value = (float)AudioSystem::logToLinear(value)/100.0f;
665 } else { // (type == AudioSystem::BLUETOOTH_SCO)
666 value = 1.0f;
667 }
668
669 AutoMutex lock(mHardwareLock);
670 mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
671 ret = mAudioHardware->setVoiceVolume(value);
672 mHardwareStatus = AUDIO_HW_IDLE;
673 }
674
675 return ret;
676}
677
678status_t AudioFlinger::setStreamMute(int stream, bool muted)
679{
680 // check calling permissions
681 if (!settingsAllowed()) {
682 return PERMISSION_DENIED;
683 }
684
Eric Laurent933a9412009-03-27 18:18:46 -0700685 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES ||
686 uint32_t(stream) == AudioSystem::ENFORCED_AUDIBLE) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800687 return BAD_VALUE;
688 }
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700689
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800690#ifdef WITH_A2DP
691 mA2dpMixerThread->setStreamMute(stream, muted);
692#endif
693 if (stream == AudioSystem::MUSIC)
694 {
695 AutoMutex lock(&mHardwareLock);
696 if (mForcedRoute != 0)
697 mMusicMuteSaved = muted;
698 else
699 mHardwareMixerThread->setStreamMute(stream, muted);
700 } else {
701 mHardwareMixerThread->setStreamMute(stream, muted);
702 }
703
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800704 return NO_ERROR;
705}
706
707float AudioFlinger::streamVolume(int stream) const
708{
709 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
710 return 0.0f;
711 }
712 return mHardwareMixerThread->streamVolume(stream);
713}
714
715bool AudioFlinger::streamMute(int stream) const
716{
717 if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
718 return true;
719 }
720
721 if (stream == AudioSystem::MUSIC && mForcedRoute != 0)
722 {
723 return mMusicMuteSaved;
724 }
725 return mHardwareMixerThread->streamMute(stream);
726}
727
728bool AudioFlinger::isMusicActive() const
729{
730 #ifdef WITH_A2DP
731 if (isA2dpEnabled()) {
732 return mA2dpMixerThread->isMusicActive();
733 }
734 #endif
735 return mHardwareMixerThread->isMusicActive();
736}
737
738status_t AudioFlinger::setParameter(const char* key, const char* value)
739{
740 status_t result, result2;
741 AutoMutex lock(mHardwareLock);
742 mHardwareStatus = AUDIO_SET_PARAMETER;
743
744 LOGV("setParameter() key %s, value %s, tid %d, calling tid %d", key, value, gettid(), IPCThreadState::self()->getCallingPid());
745 result = mAudioHardware->setParameter(key, value);
746 if (mA2dpAudioInterface) {
747 result2 = mA2dpAudioInterface->setParameter(key, value);
748 if (result2)
749 result = result2;
750 }
751 mHardwareStatus = AUDIO_HW_IDLE;
752 return result;
753}
754
755size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
756{
757 return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
758}
759
760void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
761{
762
763 LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
764 Mutex::Autolock _l(mLock);
765
766 sp<IBinder> binder = client->asBinder();
767 if (mNotificationClients.indexOf(binder) < 0) {
768 LOGV("Adding notification client %p", binder.get());
769 binder->linkToDeath(this);
770 mNotificationClients.add(binder);
771 client->a2dpEnabledChanged(isA2dpEnabled());
772 }
773}
774
775void AudioFlinger::binderDied(const wp<IBinder>& who) {
776
777 LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
778 Mutex::Autolock _l(mLock);
779
780 IBinder *binder = who.unsafe_get();
781
782 if (binder != NULL) {
783 int index = mNotificationClients.indexOf(binder);
784 if (index >= 0) {
785 LOGV("Removing notification client %p", binder);
786 mNotificationClients.removeAt(index);
787 }
788 }
789}
790
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800791void AudioFlinger::removeClient(pid_t pid)
792{
793 LOGV("removeClient() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
794 Mutex::Autolock _l(mLock);
795 mClients.removeItem(pid);
796}
797
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800798bool AudioFlinger::isA2dpEnabled() const
799{
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700800 return mA2dpEnabled;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800801}
802
803void AudioFlinger::handleForcedSpeakerRoute(int command)
804{
805 switch(command) {
806 case ACTIVE_TRACK_ADDED:
807 {
808 AutoMutex lock(mHardwareLock);
809 if (mForcedSpeakerCount++ == 0) {
810 mRouteRestoreTime = 0;
811 mMusicMuteSaved = mHardwareMixerThread->streamMute(AudioSystem::MUSIC);
812 if (mForcedRoute == 0 && !(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
813 LOGV("Route forced to Speaker ON %08x", mSavedRoute | AudioSystem::ROUTE_SPEAKER);
814 mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, true);
815 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
816 mAudioHardware->setMasterVolume(0);
817 usleep(mHardwareMixerThread->latency()*1000);
818 mHardwareStatus = AUDIO_HW_SET_ROUTING;
819 mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute | AudioSystem::ROUTE_SPEAKER);
820 mHardwareStatus = AUDIO_HW_IDLE;
821 // delay track start so that audio hardware has time to siwtch routes
822 usleep(kStartSleepTime);
823 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
824 mAudioHardware->setMasterVolume(mHardwareMixerThread->masterVolume());
825 mHardwareStatus = AUDIO_HW_IDLE;
826 }
827 mForcedRoute = AudioSystem::ROUTE_SPEAKER;
828 }
829 LOGV("mForcedSpeakerCount incremented to %d", mForcedSpeakerCount);
830 }
831 break;
832 case ACTIVE_TRACK_REMOVED:
833 {
834 AutoMutex lock(mHardwareLock);
835 if (mForcedSpeakerCount > 0){
836 if (--mForcedSpeakerCount == 0) {
837 mRouteRestoreTime = systemTime() + milliseconds(kStopSleepTime/1000);
838 }
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700839 LOGV("mForcedSpeakerCount decremented to %d", mForcedSpeakerCount);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800840 } else {
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700841 LOGE("mForcedSpeakerCount is already zero");
The Android Open Source Project22f8def2009-03-09 11:52:12 -0700842 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800843 }
844 break;
845 case CHECK_ROUTE_RESTORE_TIME:
846 case FORCE_ROUTE_RESTORE:
847 if (mRouteRestoreTime) {
848 AutoMutex lock(mHardwareLock);
849 if (mRouteRestoreTime &&
850 (systemTime() > mRouteRestoreTime || command == FORCE_ROUTE_RESTORE)) {
851 mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, mMusicMuteSaved);
852 mForcedRoute = 0;
853 if (!(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
854 mHardwareStatus = AUDIO_HW_SET_ROUTING;
855 mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute);
856 mHardwareStatus = AUDIO_HW_IDLE;
857 LOGV("Route forced to Speaker OFF %08x", mSavedRoute);
858 }
859 mRouteRestoreTime = 0;
860 }
861 }
862 break;
863 }
864}
865
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700866#ifdef WITH_A2DP
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700867// handleRouteDisablesA2dp_l() must be called with AudioFlinger::mLock held
868void AudioFlinger::handleRouteDisablesA2dp_l(int routes)
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700869{
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700870 if (routes & AudioSystem::ROUTE_BLUETOOTH_SCO) {
871 if (mA2dpDisableCount++ == 0) {
872 if (mA2dpEnabled) {
873 setA2dpEnabled_l(false);
874 mA2dpSuppressed = true;
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700875 }
876 }
The Android Open Source Project4f68be12009-03-18 17:39:46 -0700877 LOGV("mA2dpDisableCount incremented to %d", mA2dpDisableCount);
878 } else {
879 if (mA2dpDisableCount > 0) {
880 if (--mA2dpDisableCount == 0) {
881 if (mA2dpSuppressed) {
882 setA2dpEnabled_l(true);
883 mA2dpSuppressed = false;
884 }
885 }
886 LOGV("mA2dpDisableCount decremented to %d", mA2dpDisableCount);
887 } else {
888 LOGE("mA2dpDisableCount is already zero");
889 }
The Android Open Source Projectbcef13b2009-03-11 12:11:56 -0700890 }
891}
892#endif
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800893
894// ----------------------------------------------------------------------------
895
896AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType)
897 : Thread(false),
898 mAudioFlinger(audioFlinger), mAudioMixer(0), mOutput(output), mOutputType(outputType),
899 mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
900 mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
901 mInWrite(false)
902{
903 mSampleRate = output->sampleRate();
904 mChannelCount = output->channelCount();
905
906 // FIXME - Current mixer implementation only supports stereo output
907 if (mChannelCount == 1) {
908 LOGE("Invalid audio hardware channel count");
909 }
910
911 mFormat = output->format();
912 mFrameCount = output->bufferSize() / output->channelCount() / sizeof(int16_t);
913 mAudioMixer = new AudioMixer(mFrameCount, output->sampleRate());
914
915 // FIXME - Current mixer implementation only supports stereo output: Always
916 // Allocate a stereo buffer even if HW output is mono.
917 mMixBuffer = new int16_t[mFrameCount * 2];
918 memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
919}
920
921AudioFlinger::MixerThread::~MixerThread()
922{
923 delete [] mMixBuffer;
924 delete mAudioMixer;
925}
926
927status_t AudioFlinger::MixerThread::dump(int fd, const Vector<String16>& args)
928{
929 dumpInternals(fd, args);
930 dumpTracks(fd, args);
931 return NO_ERROR;
932}
933
934status_t AudioFlinger::MixerThread::dumpTracks(int fd, const Vector<String16>& args)
935{
936 const size_t SIZE = 256;
937 char buffer[SIZE];
938 String8 result;
939
940 snprintf(buffer, SIZE, "Output %d mixer thread tracks\n", mOutputType);
941 result.append(buffer);
942 result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
943 for (size_t i = 0; i < mTracks.size(); ++i) {
Eric Laurentc828f6a2009-03-31 14:34:35 -0700944 sp<Track> track = mTracks[i];
945 if (track != 0) {
946 track->dump(buffer, SIZE);
947 result.append(buffer);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800948 }
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) {
Eric Laurentc828f6a2009-03-31 14:34:35 -0700955 wp<Track> wTrack = mActiveTracks[i];
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800956 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