blob: 886c25b7d1e24e22984db38ef2cfb1d3d932beea [file] [log] [blame]
Mathias Agopian65ab4712010-07-14 17:59:35 -07001/* //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 <binder/IServiceManager.h>
28#include <utils/Log.h>
29#include <binder/Parcel.h>
30#include <binder/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#include <private/media/AudioEffectShared.h>
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#ifdef LVMX
51#include "lifevibes.h"
52#endif
53
54#include <media/EffectsFactoryApi.h>
55#include <media/EffectVisualizerApi.h>
56
57// ----------------------------------------------------------------------------
58// the sim build doesn't have gettid
59
60#ifndef HAVE_GETTID
61# define gettid getpid
62#endif
63
64// ----------------------------------------------------------------------------
65
Eric Laurentde070132010-07-13 04:45:46 -070066extern const char * const gEffectLibPath;
67
Mathias Agopian65ab4712010-07-14 17:59:35 -070068namespace android {
69
70static const char* kDeadlockedString = "AudioFlinger may be deadlocked\n";
71static const char* kHardwareLockedString = "Hardware lock is taken\n";
72
73//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
74static const float MAX_GAIN = 4096.0f;
75static const float MAX_GAIN_INT = 0x1000;
76
77// retry counts for buffer fill timeout
78// 50 * ~20msecs = 1 second
79static const int8_t kMaxTrackRetries = 50;
80static const int8_t kMaxTrackStartupRetries = 50;
81// allow less retry attempts on direct output thread.
82// direct outputs can be a scarce resource in audio hardware and should
83// be released as quickly as possible.
84static const int8_t kMaxTrackRetriesDirect = 2;
85
86static const int kDumpLockRetries = 50;
87static const int kDumpLockSleep = 20000;
88
89static const nsecs_t kWarningThrottle = seconds(5);
90
91
92#define AUDIOFLINGER_SECURITY_ENABLED 1
93
94// ----------------------------------------------------------------------------
95
96static bool recordingAllowed() {
97#ifndef HAVE_ANDROID_OS
98 return true;
99#endif
100#if AUDIOFLINGER_SECURITY_ENABLED
101 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
102 bool ok = checkCallingPermission(String16("android.permission.RECORD_AUDIO"));
103 if (!ok) LOGE("Request requires android.permission.RECORD_AUDIO");
104 return ok;
105#else
106 if (!checkCallingPermission(String16("android.permission.RECORD_AUDIO")))
107 LOGW("WARNING: Need to add android.permission.RECORD_AUDIO to manifest");
108 return true;
109#endif
110}
111
112static bool settingsAllowed() {
113#ifndef HAVE_ANDROID_OS
114 return true;
115#endif
116#if AUDIOFLINGER_SECURITY_ENABLED
117 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
118 bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
119 if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
120 return ok;
121#else
122 if (!checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")))
123 LOGW("WARNING: Need to add android.permission.MODIFY_AUDIO_SETTINGS to manifest");
124 return true;
125#endif
126}
127
128// ----------------------------------------------------------------------------
129
130AudioFlinger::AudioFlinger()
131 : BnAudioFlinger(),
Eric Laurentde070132010-07-13 04:45:46 -0700132 mAudioHardware(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700133{
134 mHardwareStatus = AUDIO_HW_IDLE;
135
136 mAudioHardware = AudioHardwareInterface::create();
137
138 mHardwareStatus = AUDIO_HW_INIT;
139 if (mAudioHardware->initCheck() == NO_ERROR) {
140 // open 16-bit output stream for s/w mixer
141 mMode = AudioSystem::MODE_NORMAL;
142 setMode(mMode);
143
144 setMasterVolume(1.0f);
145 setMasterMute(false);
146 } else {
147 LOGE("Couldn't even initialize the stubbed audio hardware!");
148 }
149#ifdef LVMX
150 LifeVibes::init();
151 mLifeVibesClientPid = -1;
152#endif
153}
154
155AudioFlinger::~AudioFlinger()
156{
157 while (!mRecordThreads.isEmpty()) {
158 // closeInput() will remove first entry from mRecordThreads
159 closeInput(mRecordThreads.keyAt(0));
160 }
161 while (!mPlaybackThreads.isEmpty()) {
162 // closeOutput() will remove first entry from mPlaybackThreads
163 closeOutput(mPlaybackThreads.keyAt(0));
164 }
165 if (mAudioHardware) {
166 delete mAudioHardware;
167 }
168}
169
170
171
172status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
173{
174 const size_t SIZE = 256;
175 char buffer[SIZE];
176 String8 result;
177
178 result.append("Clients:\n");
179 for (size_t i = 0; i < mClients.size(); ++i) {
180 wp<Client> wClient = mClients.valueAt(i);
181 if (wClient != 0) {
182 sp<Client> client = wClient.promote();
183 if (client != 0) {
184 snprintf(buffer, SIZE, " pid: %d\n", client->pid());
185 result.append(buffer);
186 }
187 }
188 }
189 write(fd, result.string(), result.size());
190 return NO_ERROR;
191}
192
193
194status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
195{
196 const size_t SIZE = 256;
197 char buffer[SIZE];
198 String8 result;
199 int hardwareStatus = mHardwareStatus;
200
201 snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
202 result.append(buffer);
203 write(fd, result.string(), result.size());
204 return NO_ERROR;
205}
206
207status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
208{
209 const size_t SIZE = 256;
210 char buffer[SIZE];
211 String8 result;
212 snprintf(buffer, SIZE, "Permission Denial: "
213 "can't dump AudioFlinger from pid=%d, uid=%d\n",
214 IPCThreadState::self()->getCallingPid(),
215 IPCThreadState::self()->getCallingUid());
216 result.append(buffer);
217 write(fd, result.string(), result.size());
218 return NO_ERROR;
219}
220
221static bool tryLock(Mutex& mutex)
222{
223 bool locked = false;
224 for (int i = 0; i < kDumpLockRetries; ++i) {
225 if (mutex.tryLock() == NO_ERROR) {
226 locked = true;
227 break;
228 }
229 usleep(kDumpLockSleep);
230 }
231 return locked;
232}
233
234status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
235{
236 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
237 dumpPermissionDenial(fd, args);
238 } else {
239 // get state of hardware lock
240 bool hardwareLocked = tryLock(mHardwareLock);
241 if (!hardwareLocked) {
242 String8 result(kHardwareLockedString);
243 write(fd, result.string(), result.size());
244 } else {
245 mHardwareLock.unlock();
246 }
247
248 bool locked = tryLock(mLock);
249
250 // failed to lock - AudioFlinger is probably deadlocked
251 if (!locked) {
252 String8 result(kDeadlockedString);
253 write(fd, result.string(), result.size());
254 }
255
256 dumpClients(fd, args);
257 dumpInternals(fd, args);
258
259 // dump playback threads
260 for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
261 mPlaybackThreads.valueAt(i)->dump(fd, args);
262 }
263
264 // dump record threads
265 for (size_t i = 0; i < mRecordThreads.size(); i++) {
266 mRecordThreads.valueAt(i)->dump(fd, args);
267 }
268
269 if (mAudioHardware) {
270 mAudioHardware->dumpState(fd, args);
271 }
272 if (locked) mLock.unlock();
273 }
274 return NO_ERROR;
275}
276
277
278// IAudioFlinger interface
279
280
281sp<IAudioTrack> AudioFlinger::createTrack(
282 pid_t pid,
283 int streamType,
284 uint32_t sampleRate,
285 int format,
286 int channelCount,
287 int frameCount,
288 uint32_t flags,
289 const sp<IMemory>& sharedBuffer,
290 int output,
291 int *sessionId,
292 status_t *status)
293{
294 sp<PlaybackThread::Track> track;
295 sp<TrackHandle> trackHandle;
296 sp<Client> client;
297 wp<Client> wclient;
298 status_t lStatus;
299 int lSessionId;
300
301 if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
302 LOGE("invalid stream type");
303 lStatus = BAD_VALUE;
304 goto Exit;
305 }
306
307 {
308 Mutex::Autolock _l(mLock);
309 PlaybackThread *thread = checkPlaybackThread_l(output);
Eric Laurent39e94f82010-07-28 01:32:47 -0700310 PlaybackThread *effectThread = NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700311 if (thread == NULL) {
312 LOGE("unknown output thread");
313 lStatus = BAD_VALUE;
314 goto Exit;
315 }
316
317 wclient = mClients.valueFor(pid);
318
319 if (wclient != NULL) {
320 client = wclient.promote();
321 } else {
322 client = new Client(this, pid);
323 mClients.add(pid, client);
324 }
325
Mathias Agopian65ab4712010-07-14 17:59:35 -0700326 LOGV("createTrack() sessionId: %d", (sessionId == NULL) ? -2 : *sessionId);
Eric Laurentde070132010-07-13 04:45:46 -0700327 if (sessionId != NULL && *sessionId != AudioSystem::SESSION_OUTPUT_MIX) {
Eric Laurentde070132010-07-13 04:45:46 -0700328 for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
Eric Laurent39e94f82010-07-28 01:32:47 -0700329 sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
330 if (mPlaybackThreads.keyAt(i) != output) {
331 // prevent same audio session on different output threads
332 uint32_t sessions = t->hasAudioSession(*sessionId);
333 if (sessions & PlaybackThread::TRACK_SESSION) {
334 lStatus = BAD_VALUE;
335 goto Exit;
336 }
337 // check if an effect with same session ID is waiting for a track to be created
338 if (sessions & PlaybackThread::EFFECT_SESSION) {
339 effectThread = t.get();
340 }
Eric Laurentde070132010-07-13 04:45:46 -0700341 }
342 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700343 lSessionId = *sessionId;
344 } else {
Eric Laurentde070132010-07-13 04:45:46 -0700345 // if no audio session id is provided, create one here
Mathias Agopian65ab4712010-07-14 17:59:35 -0700346 lSessionId = nextUniqueId();
347 if (sessionId != NULL) {
348 *sessionId = lSessionId;
349 }
350 }
351 LOGV("createTrack() lSessionId: %d", lSessionId);
352
353 track = thread->createTrack_l(client, streamType, sampleRate, format,
354 channelCount, frameCount, sharedBuffer, lSessionId, &lStatus);
Eric Laurent39e94f82010-07-28 01:32:47 -0700355
356 // move effect chain to this output thread if an effect on same session was waiting
357 // for a track to be created
358 if (lStatus == NO_ERROR && effectThread != NULL) {
359 Mutex::Autolock _dl(thread->mLock);
360 Mutex::Autolock _sl(effectThread->mLock);
361 moveEffectChain_l(lSessionId, effectThread, thread, true);
362 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700363 }
364 if (lStatus == NO_ERROR) {
365 trackHandle = new TrackHandle(track);
366 } else {
367 // remove local strong reference to Client before deleting the Track so that the Client
368 // destructor is called by the TrackBase destructor with mLock held
369 client.clear();
370 track.clear();
371 }
372
373Exit:
374 if(status) {
375 *status = lStatus;
376 }
377 return trackHandle;
378}
379
380uint32_t AudioFlinger::sampleRate(int output) const
381{
382 Mutex::Autolock _l(mLock);
383 PlaybackThread *thread = checkPlaybackThread_l(output);
384 if (thread == NULL) {
385 LOGW("sampleRate() unknown thread %d", output);
386 return 0;
387 }
388 return thread->sampleRate();
389}
390
391int AudioFlinger::channelCount(int output) const
392{
393 Mutex::Autolock _l(mLock);
394 PlaybackThread *thread = checkPlaybackThread_l(output);
395 if (thread == NULL) {
396 LOGW("channelCount() unknown thread %d", output);
397 return 0;
398 }
399 return thread->channelCount();
400}
401
402int AudioFlinger::format(int output) const
403{
404 Mutex::Autolock _l(mLock);
405 PlaybackThread *thread = checkPlaybackThread_l(output);
406 if (thread == NULL) {
407 LOGW("format() unknown thread %d", output);
408 return 0;
409 }
410 return thread->format();
411}
412
413size_t AudioFlinger::frameCount(int output) const
414{
415 Mutex::Autolock _l(mLock);
416 PlaybackThread *thread = checkPlaybackThread_l(output);
417 if (thread == NULL) {
418 LOGW("frameCount() unknown thread %d", output);
419 return 0;
420 }
421 return thread->frameCount();
422}
423
424uint32_t AudioFlinger::latency(int output) const
425{
426 Mutex::Autolock _l(mLock);
427 PlaybackThread *thread = checkPlaybackThread_l(output);
428 if (thread == NULL) {
429 LOGW("latency() unknown thread %d", output);
430 return 0;
431 }
432 return thread->latency();
433}
434
435status_t AudioFlinger::setMasterVolume(float value)
436{
437 // check calling permissions
438 if (!settingsAllowed()) {
439 return PERMISSION_DENIED;
440 }
441
442 // when hw supports master volume, don't scale in sw mixer
443 AutoMutex lock(mHardwareLock);
444 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
445 if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
446 value = 1.0f;
447 }
448 mHardwareStatus = AUDIO_HW_IDLE;
449
450 mMasterVolume = value;
451 for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
452 mPlaybackThreads.valueAt(i)->setMasterVolume(value);
453
454 return NO_ERROR;
455}
456
457status_t AudioFlinger::setMode(int mode)
458{
459 status_t ret;
460
461 // check calling permissions
462 if (!settingsAllowed()) {
463 return PERMISSION_DENIED;
464 }
465 if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
466 LOGW("Illegal value: setMode(%d)", mode);
467 return BAD_VALUE;
468 }
469
470 { // scope for the lock
471 AutoMutex lock(mHardwareLock);
472 mHardwareStatus = AUDIO_HW_SET_MODE;
473 ret = mAudioHardware->setMode(mode);
474 mHardwareStatus = AUDIO_HW_IDLE;
475 }
476
477 if (NO_ERROR == ret) {
478 Mutex::Autolock _l(mLock);
479 mMode = mode;
480 for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
481 mPlaybackThreads.valueAt(i)->setMode(mode);
482#ifdef LVMX
483 LifeVibes::setMode(mode);
484#endif
485 }
486
487 return ret;
488}
489
490status_t AudioFlinger::setMicMute(bool state)
491{
492 // check calling permissions
493 if (!settingsAllowed()) {
494 return PERMISSION_DENIED;
495 }
496
497 AutoMutex lock(mHardwareLock);
498 mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
499 status_t ret = mAudioHardware->setMicMute(state);
500 mHardwareStatus = AUDIO_HW_IDLE;
501 return ret;
502}
503
504bool AudioFlinger::getMicMute() const
505{
506 bool state = AudioSystem::MODE_INVALID;
507 mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
508 mAudioHardware->getMicMute(&state);
509 mHardwareStatus = AUDIO_HW_IDLE;
510 return state;
511}
512
513status_t AudioFlinger::setMasterMute(bool muted)
514{
515 // check calling permissions
516 if (!settingsAllowed()) {
517 return PERMISSION_DENIED;
518 }
519
520 mMasterMute = muted;
521 for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
522 mPlaybackThreads.valueAt(i)->setMasterMute(muted);
523
524 return NO_ERROR;
525}
526
527float AudioFlinger::masterVolume() const
528{
529 return mMasterVolume;
530}
531
532bool AudioFlinger::masterMute() const
533{
534 return mMasterMute;
535}
536
537status_t AudioFlinger::setStreamVolume(int stream, float value, int output)
538{
539 // check calling permissions
540 if (!settingsAllowed()) {
541 return PERMISSION_DENIED;
542 }
543
544 if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
545 return BAD_VALUE;
546 }
547
548 AutoMutex lock(mLock);
549 PlaybackThread *thread = NULL;
550 if (output) {
551 thread = checkPlaybackThread_l(output);
552 if (thread == NULL) {
553 return BAD_VALUE;
554 }
555 }
556
557 mStreamTypes[stream].volume = value;
558
559 if (thread == NULL) {
560 for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) {
561 mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value);
562 }
563 } else {
564 thread->setStreamVolume(stream, value);
565 }
566
567 return NO_ERROR;
568}
569
570status_t AudioFlinger::setStreamMute(int stream, bool muted)
571{
572 // check calling permissions
573 if (!settingsAllowed()) {
574 return PERMISSION_DENIED;
575 }
576
577 if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES ||
578 uint32_t(stream) == AudioSystem::ENFORCED_AUDIBLE) {
579 return BAD_VALUE;
580 }
581
582 mStreamTypes[stream].mute = muted;
583 for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
584 mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
585
586 return NO_ERROR;
587}
588
589float AudioFlinger::streamVolume(int stream, int output) const
590{
591 if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
592 return 0.0f;
593 }
594
595 AutoMutex lock(mLock);
596 float volume;
597 if (output) {
598 PlaybackThread *thread = checkPlaybackThread_l(output);
599 if (thread == NULL) {
600 return 0.0f;
601 }
602 volume = thread->streamVolume(stream);
603 } else {
604 volume = mStreamTypes[stream].volume;
605 }
606
607 return volume;
608}
609
610bool AudioFlinger::streamMute(int stream) const
611{
612 if (stream < 0 || stream >= (int)AudioSystem::NUM_STREAM_TYPES) {
613 return true;
614 }
615
616 return mStreamTypes[stream].mute;
617}
618
619bool AudioFlinger::isStreamActive(int stream) const
620{
621 Mutex::Autolock _l(mLock);
622 for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) {
623 if (mPlaybackThreads.valueAt(i)->isStreamActive(stream)) {
624 return true;
625 }
626 }
627 return false;
628}
629
630status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs)
631{
632 status_t result;
633
634 LOGV("setParameters(): io %d, keyvalue %s, tid %d, calling tid %d",
635 ioHandle, keyValuePairs.string(), gettid(), IPCThreadState::self()->getCallingPid());
636 // check calling permissions
637 if (!settingsAllowed()) {
638 return PERMISSION_DENIED;
639 }
640
641#ifdef LVMX
642 AudioParameter param = AudioParameter(keyValuePairs);
643 LifeVibes::setParameters(ioHandle,keyValuePairs);
644 String8 key = String8(AudioParameter::keyRouting);
645 int device;
646 if (NO_ERROR != param.getInt(key, device)) {
647 device = -1;
648 }
649
650 key = String8(LifevibesTag);
651 String8 value;
652 int musicEnabled = -1;
653 if (NO_ERROR == param.get(key, value)) {
654 if (value == LifevibesEnable) {
655 mLifeVibesClientPid = IPCThreadState::self()->getCallingPid();
656 musicEnabled = 1;
657 } else if (value == LifevibesDisable) {
658 mLifeVibesClientPid = -1;
659 musicEnabled = 0;
660 }
661 }
662#endif
663
664 // ioHandle == 0 means the parameters are global to the audio hardware interface
665 if (ioHandle == 0) {
666 AutoMutex lock(mHardwareLock);
667 mHardwareStatus = AUDIO_SET_PARAMETER;
668 result = mAudioHardware->setParameters(keyValuePairs);
669#ifdef LVMX
670 if (musicEnabled != -1) {
671 LifeVibes::enableMusic((bool) musicEnabled);
672 }
673#endif
674 mHardwareStatus = AUDIO_HW_IDLE;
675 return result;
676 }
677
678 // hold a strong ref on thread in case closeOutput() or closeInput() is called
679 // and the thread is exited once the lock is released
680 sp<ThreadBase> thread;
681 {
682 Mutex::Autolock _l(mLock);
683 thread = checkPlaybackThread_l(ioHandle);
684 if (thread == NULL) {
685 thread = checkRecordThread_l(ioHandle);
686 }
687 }
688 if (thread != NULL) {
689 result = thread->setParameters(keyValuePairs);
690#ifdef LVMX
691 if ((NO_ERROR == result) && (device != -1)) {
692 LifeVibes::setDevice(LifeVibes::threadIdToAudioOutputType(thread->id()), device);
693 }
694#endif
695 return result;
696 }
697 return BAD_VALUE;
698}
699
700String8 AudioFlinger::getParameters(int ioHandle, const String8& keys)
701{
702// LOGV("getParameters() io %d, keys %s, tid %d, calling tid %d",
703// ioHandle, keys.string(), gettid(), IPCThreadState::self()->getCallingPid());
704
705 if (ioHandle == 0) {
706 return mAudioHardware->getParameters(keys);
707 }
708
709 Mutex::Autolock _l(mLock);
710
711 PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle);
712 if (playbackThread != NULL) {
713 return playbackThread->getParameters(keys);
714 }
715 RecordThread *recordThread = checkRecordThread_l(ioHandle);
716 if (recordThread != NULL) {
717 return recordThread->getParameters(keys);
718 }
719 return String8("");
720}
721
722size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
723{
724 return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
725}
726
727unsigned int AudioFlinger::getInputFramesLost(int ioHandle)
728{
729 if (ioHandle == 0) {
730 return 0;
731 }
732
733 Mutex::Autolock _l(mLock);
734
735 RecordThread *recordThread = checkRecordThread_l(ioHandle);
736 if (recordThread != NULL) {
737 return recordThread->getInputFramesLost();
738 }
739 return 0;
740}
741
742status_t AudioFlinger::setVoiceVolume(float value)
743{
744 // check calling permissions
745 if (!settingsAllowed()) {
746 return PERMISSION_DENIED;
747 }
748
749 AutoMutex lock(mHardwareLock);
750 mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
751 status_t ret = mAudioHardware->setVoiceVolume(value);
752 mHardwareStatus = AUDIO_HW_IDLE;
753
754 return ret;
755}
756
757status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output)
758{
759 status_t status;
760
761 Mutex::Autolock _l(mLock);
762
763 PlaybackThread *playbackThread = checkPlaybackThread_l(output);
764 if (playbackThread != NULL) {
765 return playbackThread->getRenderPosition(halFrames, dspFrames);
766 }
767
768 return BAD_VALUE;
769}
770
771void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
772{
773
774 Mutex::Autolock _l(mLock);
775
776 int pid = IPCThreadState::self()->getCallingPid();
777 if (mNotificationClients.indexOfKey(pid) < 0) {
778 sp<NotificationClient> notificationClient = new NotificationClient(this,
779 client,
780 pid);
781 LOGV("registerClient() client %p, pid %d", notificationClient.get(), pid);
782
783 mNotificationClients.add(pid, notificationClient);
784
785 sp<IBinder> binder = client->asBinder();
786 binder->linkToDeath(notificationClient);
787
788 // the config change is always sent from playback or record threads to avoid deadlock
789 // with AudioSystem::gLock
790 for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
791 mPlaybackThreads.valueAt(i)->sendConfigEvent(AudioSystem::OUTPUT_OPENED);
792 }
793
794 for (size_t i = 0; i < mRecordThreads.size(); i++) {
795 mRecordThreads.valueAt(i)->sendConfigEvent(AudioSystem::INPUT_OPENED);
796 }
797 }
798}
799
800void AudioFlinger::removeNotificationClient(pid_t pid)
801{
802 Mutex::Autolock _l(mLock);
803
804 int index = mNotificationClients.indexOfKey(pid);
805 if (index >= 0) {
806 sp <NotificationClient> client = mNotificationClients.valueFor(pid);
807 LOGV("removeNotificationClient() %p, pid %d", client.get(), pid);
808#ifdef LVMX
809 if (pid == mLifeVibesClientPid) {
810 LOGV("Disabling lifevibes");
811 LifeVibes::enableMusic(false);
812 mLifeVibesClientPid = -1;
813 }
814#endif
815 mNotificationClients.removeItem(pid);
816 }
817}
818
819// audioConfigChanged_l() must be called with AudioFlinger::mLock held
820void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2)
821{
822 size_t size = mNotificationClients.size();
823 for (size_t i = 0; i < size; i++) {
824 mNotificationClients.valueAt(i)->client()->ioConfigChanged(event, ioHandle, param2);
825 }
826}
827
828// removeClient_l() must be called with AudioFlinger::mLock held
829void AudioFlinger::removeClient_l(pid_t pid)
830{
831 LOGV("removeClient_l() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
832 mClients.removeItem(pid);
833}
834
835
836// ----------------------------------------------------------------------------
837
838AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id)
839 : Thread(false),
840 mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0),
841 mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false)
842{
843}
844
845AudioFlinger::ThreadBase::~ThreadBase()
846{
847 mParamCond.broadcast();
848 mNewParameters.clear();
849}
850
851void AudioFlinger::ThreadBase::exit()
852{
853 // keep a strong ref on ourself so that we wont get
854 // destroyed in the middle of requestExitAndWait()
855 sp <ThreadBase> strongMe = this;
856
857 LOGV("ThreadBase::exit");
858 {
859 AutoMutex lock(&mLock);
860 mExiting = true;
861 requestExit();
862 mWaitWorkCV.signal();
863 }
864 requestExitAndWait();
865}
866
867uint32_t AudioFlinger::ThreadBase::sampleRate() const
868{
869 return mSampleRate;
870}
871
872int AudioFlinger::ThreadBase::channelCount() const
873{
874 return (int)mChannelCount;
875}
876
877int AudioFlinger::ThreadBase::format() const
878{
879 return mFormat;
880}
881
882size_t AudioFlinger::ThreadBase::frameCount() const
883{
884 return mFrameCount;
885}
886
887status_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs)
888{
889 status_t status;
890
891 LOGV("ThreadBase::setParameters() %s", keyValuePairs.string());
892 Mutex::Autolock _l(mLock);
893
894 mNewParameters.add(keyValuePairs);
895 mWaitWorkCV.signal();
896 // wait condition with timeout in case the thread loop has exited
897 // before the request could be processed
898 if (mParamCond.waitRelative(mLock, seconds(2)) == NO_ERROR) {
899 status = mParamStatus;
900 mWaitWorkCV.signal();
901 } else {
902 status = TIMED_OUT;
903 }
904 return status;
905}
906
907void AudioFlinger::ThreadBase::sendConfigEvent(int event, int param)
908{
909 Mutex::Autolock _l(mLock);
910 sendConfigEvent_l(event, param);
911}
912
913// sendConfigEvent_l() must be called with ThreadBase::mLock held
914void AudioFlinger::ThreadBase::sendConfigEvent_l(int event, int param)
915{
916 ConfigEvent *configEvent = new ConfigEvent();
917 configEvent->mEvent = event;
918 configEvent->mParam = param;
919 mConfigEvents.add(configEvent);
920 LOGV("sendConfigEvent() num events %d event %d, param %d", mConfigEvents.size(), event, param);
921 mWaitWorkCV.signal();
922}
923
924void AudioFlinger::ThreadBase::processConfigEvents()
925{
926 mLock.lock();
927 while(!mConfigEvents.isEmpty()) {
928 LOGV("processConfigEvents() remaining events %d", mConfigEvents.size());
929 ConfigEvent *configEvent = mConfigEvents[0];
930 mConfigEvents.removeAt(0);
931 // release mLock before locking AudioFlinger mLock: lock order is always
932 // AudioFlinger then ThreadBase to avoid cross deadlock
933 mLock.unlock();
934 mAudioFlinger->mLock.lock();
935 audioConfigChanged_l(configEvent->mEvent, configEvent->mParam);
936 mAudioFlinger->mLock.unlock();
937 delete configEvent;
938 mLock.lock();
939 }
940 mLock.unlock();
941}
942
943status_t AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args)
944{
945 const size_t SIZE = 256;
946 char buffer[SIZE];
947 String8 result;
948
949 bool locked = tryLock(mLock);
950 if (!locked) {
951 snprintf(buffer, SIZE, "thread %p maybe dead locked\n", this);
952 write(fd, buffer, strlen(buffer));
953 }
954
955 snprintf(buffer, SIZE, "standby: %d\n", mStandby);
956 result.append(buffer);
957 snprintf(buffer, SIZE, "Sample rate: %d\n", mSampleRate);
958 result.append(buffer);
959 snprintf(buffer, SIZE, "Frame count: %d\n", mFrameCount);
960 result.append(buffer);
961 snprintf(buffer, SIZE, "Channel Count: %d\n", mChannelCount);
962 result.append(buffer);
963 snprintf(buffer, SIZE, "Format: %d\n", mFormat);
964 result.append(buffer);
965 snprintf(buffer, SIZE, "Frame size: %d\n", mFrameSize);
966 result.append(buffer);
967
968 snprintf(buffer, SIZE, "\nPending setParameters commands: \n");
969 result.append(buffer);
970 result.append(" Index Command");
971 for (size_t i = 0; i < mNewParameters.size(); ++i) {
972 snprintf(buffer, SIZE, "\n %02d ", i);
973 result.append(buffer);
974 result.append(mNewParameters[i]);
975 }
976
977 snprintf(buffer, SIZE, "\n\nPending config events: \n");
978 result.append(buffer);
979 snprintf(buffer, SIZE, " Index event param\n");
980 result.append(buffer);
981 for (size_t i = 0; i < mConfigEvents.size(); i++) {
982 snprintf(buffer, SIZE, " %02d %02d %d\n", i, mConfigEvents[i]->mEvent, mConfigEvents[i]->mParam);
983 result.append(buffer);
984 }
985 result.append("\n");
986
987 write(fd, result.string(), result.size());
988
989 if (locked) {
990 mLock.unlock();
991 }
992 return NO_ERROR;
993}
994
995
996// ----------------------------------------------------------------------------
997
998AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
999 : ThreadBase(audioFlinger, id),
1000 mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output),
1001 mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
1002 mDevice(device)
1003{
1004 readOutputParameters();
1005
1006 mMasterVolume = mAudioFlinger->masterVolume();
1007 mMasterMute = mAudioFlinger->masterMute();
1008
1009 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
1010 mStreamTypes[stream].volume = mAudioFlinger->streamVolumeInternal(stream);
1011 mStreamTypes[stream].mute = mAudioFlinger->streamMute(stream);
1012 }
1013}
1014
1015AudioFlinger::PlaybackThread::~PlaybackThread()
1016{
1017 delete [] mMixBuffer;
1018}
1019
1020status_t AudioFlinger::PlaybackThread::dump(int fd, const Vector<String16>& args)
1021{
1022 dumpInternals(fd, args);
1023 dumpTracks(fd, args);
1024 dumpEffectChains(fd, args);
1025 return NO_ERROR;
1026}
1027
1028status_t AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args)
1029{
1030 const size_t SIZE = 256;
1031 char buffer[SIZE];
1032 String8 result;
1033
1034 snprintf(buffer, SIZE, "Output thread %p tracks\n", this);
1035 result.append(buffer);
1036 result.append(" Name Clien Typ Fmt Chn Session Buf S M F SRate LeftV RighV Serv User Main buf Aux Buf\n");
1037 for (size_t i = 0; i < mTracks.size(); ++i) {
1038 sp<Track> track = mTracks[i];
1039 if (track != 0) {
1040 track->dump(buffer, SIZE);
1041 result.append(buffer);
1042 }
1043 }
1044
1045 snprintf(buffer, SIZE, "Output thread %p active tracks\n", this);
1046 result.append(buffer);
1047 result.append(" Name Clien Typ Fmt Chn Session Buf S M F SRate LeftV RighV Serv User Main buf Aux Buf\n");
1048 for (size_t i = 0; i < mActiveTracks.size(); ++i) {
1049 wp<Track> wTrack = mActiveTracks[i];
1050 if (wTrack != 0) {
1051 sp<Track> track = wTrack.promote();
1052 if (track != 0) {
1053 track->dump(buffer, SIZE);
1054 result.append(buffer);
1055 }
1056 }
1057 }
1058 write(fd, result.string(), result.size());
1059 return NO_ERROR;
1060}
1061
1062status_t AudioFlinger::PlaybackThread::dumpEffectChains(int fd, const Vector<String16>& args)
1063{
1064 const size_t SIZE = 256;
1065 char buffer[SIZE];
1066 String8 result;
1067
1068 snprintf(buffer, SIZE, "\n- %d Effect Chains:\n", mEffectChains.size());
1069 write(fd, buffer, strlen(buffer));
1070
1071 for (size_t i = 0; i < mEffectChains.size(); ++i) {
1072 sp<EffectChain> chain = mEffectChains[i];
1073 if (chain != 0) {
1074 chain->dump(fd, args);
1075 }
1076 }
1077 return NO_ERROR;
1078}
1079
1080status_t AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
1081{
1082 const size_t SIZE = 256;
1083 char buffer[SIZE];
1084 String8 result;
1085
1086 snprintf(buffer, SIZE, "\nOutput thread %p internals\n", this);
1087 result.append(buffer);
1088 snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
1089 result.append(buffer);
1090 snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
1091 result.append(buffer);
1092 snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
1093 result.append(buffer);
1094 snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
1095 result.append(buffer);
1096 snprintf(buffer, SIZE, "suspend count: %d\n", mSuspended);
1097 result.append(buffer);
1098 snprintf(buffer, SIZE, "mix buffer : %p\n", mMixBuffer);
1099 result.append(buffer);
1100 write(fd, result.string(), result.size());
1101
1102 dumpBase(fd, args);
1103
1104 return NO_ERROR;
1105}
1106
1107// Thread virtuals
1108status_t AudioFlinger::PlaybackThread::readyToRun()
1109{
1110 if (mSampleRate == 0) {
1111 LOGE("No working audio driver found.");
1112 return NO_INIT;
1113 }
1114 LOGI("AudioFlinger's thread %p ready to run", this);
1115 return NO_ERROR;
1116}
1117
1118void AudioFlinger::PlaybackThread::onFirstRef()
1119{
1120 const size_t SIZE = 256;
1121 char buffer[SIZE];
1122
1123 snprintf(buffer, SIZE, "Playback Thread %p", this);
1124
1125 run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
1126}
1127
1128// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
1129sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l(
1130 const sp<AudioFlinger::Client>& client,
1131 int streamType,
1132 uint32_t sampleRate,
1133 int format,
1134 int channelCount,
1135 int frameCount,
1136 const sp<IMemory>& sharedBuffer,
1137 int sessionId,
1138 status_t *status)
1139{
1140 sp<Track> track;
1141 status_t lStatus;
1142
1143 if (mType == DIRECT) {
1144 if (sampleRate != mSampleRate || format != mFormat || channelCount != (int)mChannelCount) {
1145 LOGE("createTrack_l() Bad parameter: sampleRate %d format %d, channelCount %d for output %p",
1146 sampleRate, format, channelCount, mOutput);
1147 lStatus = BAD_VALUE;
1148 goto Exit;
1149 }
1150 } else {
1151 // Resampler implementation limits input sampling rate to 2 x output sampling rate.
1152 if (sampleRate > mSampleRate*2) {
1153 LOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
1154 lStatus = BAD_VALUE;
1155 goto Exit;
1156 }
1157 }
1158
1159 if (mOutput == 0) {
1160 LOGE("Audio driver not initialized.");
1161 lStatus = NO_INIT;
1162 goto Exit;
1163 }
1164
1165 { // scope for mLock
1166 Mutex::Autolock _l(mLock);
Eric Laurentde070132010-07-13 04:45:46 -07001167
1168 // all tracks in same audio session must share the same routing strategy otherwise
1169 // conflicts will happen when tracks are moved from one output to another by audio policy
1170 // manager
1171 uint32_t strategy =
1172 AudioSystem::getStrategyForStream((AudioSystem::stream_type)streamType);
1173 for (size_t i = 0; i < mTracks.size(); ++i) {
1174 sp<Track> t = mTracks[i];
1175 if (t != 0) {
1176 if (sessionId == t->sessionId() &&
1177 strategy != AudioSystem::getStrategyForStream((AudioSystem::stream_type)t->type())) {
1178 lStatus = BAD_VALUE;
1179 goto Exit;
1180 }
1181 }
1182 }
1183
Mathias Agopian65ab4712010-07-14 17:59:35 -07001184 track = new Track(this, client, streamType, sampleRate, format,
1185 channelCount, frameCount, sharedBuffer, sessionId);
1186 if (track->getCblk() == NULL || track->name() < 0) {
1187 lStatus = NO_MEMORY;
1188 goto Exit;
1189 }
1190 mTracks.add(track);
1191
1192 sp<EffectChain> chain = getEffectChain_l(sessionId);
1193 if (chain != 0) {
1194 LOGV("createTrack_l() setting main buffer %p", chain->inBuffer());
1195 track->setMainBuffer(chain->inBuffer());
Eric Laurentde070132010-07-13 04:45:46 -07001196 chain->setStrategy(AudioSystem::getStrategyForStream((AudioSystem::stream_type)track->type()));
Mathias Agopian65ab4712010-07-14 17:59:35 -07001197 }
1198 }
1199 lStatus = NO_ERROR;
1200
1201Exit:
1202 if(status) {
1203 *status = lStatus;
1204 }
1205 return track;
1206}
1207
1208uint32_t AudioFlinger::PlaybackThread::latency() const
1209{
1210 if (mOutput) {
1211 return mOutput->latency();
1212 }
1213 else {
1214 return 0;
1215 }
1216}
1217
1218status_t AudioFlinger::PlaybackThread::setMasterVolume(float value)
1219{
1220#ifdef LVMX
1221 int audioOutputType = LifeVibes::getMixerType(mId, mType);
1222 if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
1223 LifeVibes::setMasterVolume(audioOutputType, value);
1224 }
1225#endif
1226 mMasterVolume = value;
1227 return NO_ERROR;
1228}
1229
1230status_t AudioFlinger::PlaybackThread::setMasterMute(bool muted)
1231{
1232#ifdef LVMX
1233 int audioOutputType = LifeVibes::getMixerType(mId, mType);
1234 if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
1235 LifeVibes::setMasterMute(audioOutputType, muted);
1236 }
1237#endif
1238 mMasterMute = muted;
1239 return NO_ERROR;
1240}
1241
1242float AudioFlinger::PlaybackThread::masterVolume() const
1243{
1244 return mMasterVolume;
1245}
1246
1247bool AudioFlinger::PlaybackThread::masterMute() const
1248{
1249 return mMasterMute;
1250}
1251
1252status_t AudioFlinger::PlaybackThread::setStreamVolume(int stream, float value)
1253{
1254#ifdef LVMX
1255 int audioOutputType = LifeVibes::getMixerType(mId, mType);
1256 if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
1257 LifeVibes::setStreamVolume(audioOutputType, stream, value);
1258 }
1259#endif
1260 mStreamTypes[stream].volume = value;
1261 return NO_ERROR;
1262}
1263
1264status_t AudioFlinger::PlaybackThread::setStreamMute(int stream, bool muted)
1265{
1266#ifdef LVMX
1267 int audioOutputType = LifeVibes::getMixerType(mId, mType);
1268 if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
1269 LifeVibes::setStreamMute(audioOutputType, stream, muted);
1270 }
1271#endif
1272 mStreamTypes[stream].mute = muted;
1273 return NO_ERROR;
1274}
1275
1276float AudioFlinger::PlaybackThread::streamVolume(int stream) const
1277{
1278 return mStreamTypes[stream].volume;
1279}
1280
1281bool AudioFlinger::PlaybackThread::streamMute(int stream) const
1282{
1283 return mStreamTypes[stream].mute;
1284}
1285
1286bool AudioFlinger::PlaybackThread::isStreamActive(int stream) const
1287{
1288 Mutex::Autolock _l(mLock);
1289 size_t count = mActiveTracks.size();
1290 for (size_t i = 0 ; i < count ; ++i) {
1291 sp<Track> t = mActiveTracks[i].promote();
1292 if (t == 0) continue;
1293 Track* const track = t.get();
1294 if (t->type() == stream)
1295 return true;
1296 }
1297 return false;
1298}
1299
1300// addTrack_l() must be called with ThreadBase::mLock held
1301status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
1302{
1303 status_t status = ALREADY_EXISTS;
1304
1305 // set retry count for buffer fill
1306 track->mRetryCount = kMaxTrackStartupRetries;
1307 if (mActiveTracks.indexOf(track) < 0) {
1308 // the track is newly added, make sure it fills up all its
1309 // buffers before playing. This is to ensure the client will
1310 // effectively get the latency it requested.
1311 track->mFillingUpStatus = Track::FS_FILLING;
1312 track->mResetDone = false;
1313 mActiveTracks.add(track);
1314 if (track->mainBuffer() != mMixBuffer) {
1315 sp<EffectChain> chain = getEffectChain_l(track->sessionId());
1316 if (chain != 0) {
1317 LOGV("addTrack_l() starting track on chain %p for session %d", chain.get(), track->sessionId());
1318 chain->startTrack();
1319 }
1320 }
1321
1322 status = NO_ERROR;
1323 }
1324
1325 LOGV("mWaitWorkCV.broadcast");
1326 mWaitWorkCV.broadcast();
1327
1328 return status;
1329}
1330
1331// destroyTrack_l() must be called with ThreadBase::mLock held
1332void AudioFlinger::PlaybackThread::destroyTrack_l(const sp<Track>& track)
1333{
1334 track->mState = TrackBase::TERMINATED;
1335 if (mActiveTracks.indexOf(track) < 0) {
1336 mTracks.remove(track);
1337 deleteTrackName_l(track->name());
1338 }
1339}
1340
1341String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys)
1342{
1343 return mOutput->getParameters(keys);
1344}
1345
1346// destroyTrack_l() must be called with AudioFlinger::mLock held
1347void AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) {
1348 AudioSystem::OutputDescriptor desc;
1349 void *param2 = 0;
1350
1351 LOGV("PlaybackThread::audioConfigChanged_l, thread %p, event %d, param %d", this, event, param);
1352
1353 switch (event) {
1354 case AudioSystem::OUTPUT_OPENED:
1355 case AudioSystem::OUTPUT_CONFIG_CHANGED:
1356 desc.channels = mChannels;
1357 desc.samplingRate = mSampleRate;
1358 desc.format = mFormat;
1359 desc.frameCount = mFrameCount;
1360 desc.latency = latency();
1361 param2 = &desc;
1362 break;
1363
1364 case AudioSystem::STREAM_CONFIG_CHANGED:
1365 param2 = &param;
1366 case AudioSystem::OUTPUT_CLOSED:
1367 default:
1368 break;
1369 }
1370 mAudioFlinger->audioConfigChanged_l(event, mId, param2);
1371}
1372
1373void AudioFlinger::PlaybackThread::readOutputParameters()
1374{
1375 mSampleRate = mOutput->sampleRate();
1376 mChannels = mOutput->channels();
1377 mChannelCount = (uint16_t)AudioSystem::popCount(mChannels);
1378 mFormat = mOutput->format();
1379 mFrameSize = (uint16_t)mOutput->frameSize();
1380 mFrameCount = mOutput->bufferSize() / mFrameSize;
1381
1382 // FIXME - Current mixer implementation only supports stereo output: Always
1383 // Allocate a stereo buffer even if HW output is mono.
1384 if (mMixBuffer != NULL) delete[] mMixBuffer;
1385 mMixBuffer = new int16_t[mFrameCount * 2];
1386 memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
1387
Eric Laurentde070132010-07-13 04:45:46 -07001388 // force reconfiguration of effect chains and engines to take new buffer size and audio
1389 // parameters into account
1390 // Note that mLock is not held when readOutputParameters() is called from the constructor
1391 // but in this case nothing is done below as no audio sessions have effect yet so it doesn't
1392 // matter.
1393 // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains
1394 Vector< sp<EffectChain> > effectChains = mEffectChains;
1395 for (size_t i = 0; i < effectChains.size(); i ++) {
Eric Laurent39e94f82010-07-28 01:32:47 -07001396 mAudioFlinger->moveEffectChain_l(effectChains[i]->sessionId(), this, this, false);
Eric Laurentde070132010-07-13 04:45:46 -07001397 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001398}
1399
1400status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
1401{
1402 if (halFrames == 0 || dspFrames == 0) {
1403 return BAD_VALUE;
1404 }
1405 if (mOutput == 0) {
1406 return INVALID_OPERATION;
1407 }
1408 *halFrames = mBytesWritten/mOutput->frameSize();
1409
1410 return mOutput->getRenderPosition(dspFrames);
1411}
1412
Eric Laurent39e94f82010-07-28 01:32:47 -07001413uint32_t AudioFlinger::PlaybackThread::hasAudioSession(int sessionId)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001414{
1415 Mutex::Autolock _l(mLock);
Eric Laurent39e94f82010-07-28 01:32:47 -07001416 uint32_t result = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001417 if (getEffectChain_l(sessionId) != 0) {
Eric Laurent39e94f82010-07-28 01:32:47 -07001418 result = EFFECT_SESSION;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001419 }
1420
1421 for (size_t i = 0; i < mTracks.size(); ++i) {
1422 sp<Track> track = mTracks[i];
Eric Laurentde070132010-07-13 04:45:46 -07001423 if (sessionId == track->sessionId() &&
1424 !(track->mCblk->flags & CBLK_INVALID_MSK)) {
Eric Laurent39e94f82010-07-28 01:32:47 -07001425 result |= TRACK_SESSION;
1426 break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001427 }
1428 }
1429
Eric Laurent39e94f82010-07-28 01:32:47 -07001430 return result;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001431}
1432
Eric Laurentde070132010-07-13 04:45:46 -07001433uint32_t AudioFlinger::PlaybackThread::getStrategyForSession_l(int sessionId)
1434{
1435 // session AudioSystem::SESSION_OUTPUT_MIX is placed in same strategy as MUSIC stream so that
1436 // it is moved to correct output by audio policy manager when A2DP is connected or disconnected
1437 if (sessionId == AudioSystem::SESSION_OUTPUT_MIX) {
1438 return AudioSystem::getStrategyForStream(AudioSystem::MUSIC);
1439 }
1440 for (size_t i = 0; i < mTracks.size(); i++) {
1441 sp<Track> track = mTracks[i];
1442 if (sessionId == track->sessionId() &&
1443 !(track->mCblk->flags & CBLK_INVALID_MSK)) {
1444 return AudioSystem::getStrategyForStream((AudioSystem::stream_type) track->type());
1445 }
1446 }
1447 return AudioSystem::getStrategyForStream(AudioSystem::MUSIC);
1448}
1449
Mathias Agopian65ab4712010-07-14 17:59:35 -07001450sp<AudioFlinger::EffectChain> AudioFlinger::PlaybackThread::getEffectChain(int sessionId)
1451{
1452 Mutex::Autolock _l(mLock);
1453 return getEffectChain_l(sessionId);
1454}
1455
1456sp<AudioFlinger::EffectChain> AudioFlinger::PlaybackThread::getEffectChain_l(int sessionId)
1457{
1458 sp<EffectChain> chain;
1459
1460 size_t size = mEffectChains.size();
1461 for (size_t i = 0; i < size; i++) {
1462 if (mEffectChains[i]->sessionId() == sessionId) {
1463 chain = mEffectChains[i];
1464 break;
1465 }
1466 }
1467 return chain;
1468}
1469
1470void AudioFlinger::PlaybackThread::setMode(uint32_t mode)
1471{
1472 Mutex::Autolock _l(mLock);
1473 size_t size = mEffectChains.size();
1474 for (size_t i = 0; i < size; i++) {
Eric Laurentcab11242010-07-15 12:50:15 -07001475 mEffectChains[i]->setMode_l(mode);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001476 }
1477}
1478
1479// ----------------------------------------------------------------------------
1480
1481AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
1482 : PlaybackThread(audioFlinger, output, id, device),
1483 mAudioMixer(0)
1484{
1485 mType = PlaybackThread::MIXER;
1486 mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
1487
1488 // FIXME - Current mixer implementation only supports stereo output
1489 if (mChannelCount == 1) {
1490 LOGE("Invalid audio hardware channel count");
1491 }
1492}
1493
1494AudioFlinger::MixerThread::~MixerThread()
1495{
1496 delete mAudioMixer;
1497}
1498
1499bool AudioFlinger::MixerThread::threadLoop()
1500{
1501 Vector< sp<Track> > tracksToRemove;
1502 uint32_t mixerStatus = MIXER_IDLE;
1503 nsecs_t standbyTime = systemTime();
1504 size_t mixBufferSize = mFrameCount * mFrameSize;
1505 // FIXME: Relaxed timing because of a certain device that can't meet latency
1506 // Should be reduced to 2x after the vendor fixes the driver issue
1507 nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 3;
1508 nsecs_t lastWarning = 0;
1509 bool longStandbyExit = false;
1510 uint32_t activeSleepTime = activeSleepTimeUs();
1511 uint32_t idleSleepTime = idleSleepTimeUs();
1512 uint32_t sleepTime = idleSleepTime;
1513 Vector< sp<EffectChain> > effectChains;
1514
1515 while (!exitPending())
1516 {
1517 processConfigEvents();
1518
1519 mixerStatus = MIXER_IDLE;
1520 { // scope for mLock
1521
1522 Mutex::Autolock _l(mLock);
1523
1524 if (checkForNewParameters_l()) {
1525 mixBufferSize = mFrameCount * mFrameSize;
1526 // FIXME: Relaxed timing because of a certain device that can't meet latency
1527 // Should be reduced to 2x after the vendor fixes the driver issue
1528 maxPeriod = seconds(mFrameCount) / mSampleRate * 3;
1529 activeSleepTime = activeSleepTimeUs();
1530 idleSleepTime = idleSleepTimeUs();
1531 }
1532
1533 const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
1534
1535 // put audio hardware into standby after short delay
1536 if UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
1537 mSuspended) {
1538 if (!mStandby) {
1539 LOGV("Audio hardware entering standby, mixer %p, mSuspended %d\n", this, mSuspended);
1540 mOutput->standby();
1541 mStandby = true;
1542 mBytesWritten = 0;
1543 }
1544
1545 if (!activeTracks.size() && mConfigEvents.isEmpty()) {
1546 // we're about to wait, flush the binder command buffer
1547 IPCThreadState::self()->flushCommands();
1548
1549 if (exitPending()) break;
1550
1551 // wait until we have something to do...
1552 LOGV("MixerThread %p TID %d going to sleep\n", this, gettid());
1553 mWaitWorkCV.wait(mLock);
1554 LOGV("MixerThread %p TID %d waking up\n", this, gettid());
1555
1556 if (mMasterMute == false) {
1557 char value[PROPERTY_VALUE_MAX];
1558 property_get("ro.audio.silent", value, "0");
1559 if (atoi(value)) {
1560 LOGD("Silence is golden");
1561 setMasterMute(true);
1562 }
1563 }
1564
1565 standbyTime = systemTime() + kStandbyTimeInNsecs;
1566 sleepTime = idleSleepTime;
1567 continue;
1568 }
1569 }
1570
1571 mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
1572
1573 // prevent any changes in effect chain list and in each effect chain
1574 // during mixing and effect process as the audio buffers could be deleted
1575 // or modified if an effect is created or deleted
Eric Laurentde070132010-07-13 04:45:46 -07001576 lockEffectChains_l(effectChains);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001577 }
1578
1579 if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
1580 // mix buffers...
1581 mAudioMixer->process();
1582 sleepTime = 0;
1583 standbyTime = systemTime() + kStandbyTimeInNsecs;
1584 //TODO: delay standby when effects have a tail
1585 } else {
1586 // If no tracks are ready, sleep once for the duration of an output
1587 // buffer size, then write 0s to the output
1588 if (sleepTime == 0) {
1589 if (mixerStatus == MIXER_TRACKS_ENABLED) {
1590 sleepTime = activeSleepTime;
1591 } else {
1592 sleepTime = idleSleepTime;
1593 }
1594 } else if (mBytesWritten != 0 ||
1595 (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)) {
1596 memset (mMixBuffer, 0, mixBufferSize);
1597 sleepTime = 0;
1598 LOGV_IF((mBytesWritten == 0 && (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)), "anticipated start");
1599 }
1600 // TODO add standby time extension fct of effect tail
1601 }
1602
1603 if (mSuspended) {
Eric Laurent25cbe0e2010-08-18 18:13:17 -07001604 sleepTime = suspendSleepTimeUs();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001605 }
1606 // sleepTime == 0 means we must write to audio hardware
1607 if (sleepTime == 0) {
1608 for (size_t i = 0; i < effectChains.size(); i ++) {
1609 effectChains[i]->process_l();
1610 }
1611 // enable changes in effect chain
Eric Laurentde070132010-07-13 04:45:46 -07001612 unlockEffectChains(effectChains);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001613#ifdef LVMX
1614 int audioOutputType = LifeVibes::getMixerType(mId, mType);
1615 if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
1616 LifeVibes::process(audioOutputType, mMixBuffer, mixBufferSize);
1617 }
1618#endif
1619 mLastWriteTime = systemTime();
1620 mInWrite = true;
1621 mBytesWritten += mixBufferSize;
1622
1623 int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
1624 if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
1625 mNumWrites++;
1626 mInWrite = false;
1627 nsecs_t now = systemTime();
1628 nsecs_t delta = now - mLastWriteTime;
1629 if (delta > maxPeriod) {
1630 mNumDelayedWrites++;
1631 if ((now - lastWarning) > kWarningThrottle) {
1632 LOGW("write blocked for %llu msecs, %d delayed writes, thread %p",
1633 ns2ms(delta), mNumDelayedWrites, this);
1634 lastWarning = now;
1635 }
1636 if (mStandby) {
1637 longStandbyExit = true;
1638 }
1639 }
1640 mStandby = false;
1641 } else {
1642 // enable changes in effect chain
Eric Laurentde070132010-07-13 04:45:46 -07001643 unlockEffectChains(effectChains);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001644 usleep(sleepTime);
1645 }
1646
1647 // finally let go of all our tracks, without the lock held
1648 // since we can't guarantee the destructors won't acquire that
1649 // same lock.
1650 tracksToRemove.clear();
1651
1652 // Effect chains will be actually deleted here if they were removed from
1653 // mEffectChains list during mixing or effects processing
1654 effectChains.clear();
1655 }
1656
1657 if (!mStandby) {
1658 mOutput->standby();
1659 }
1660
1661 LOGV("MixerThread %p exiting", this);
1662 return false;
1663}
1664
1665// prepareTracks_l() must be called with ThreadBase::mLock held
1666uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove)
1667{
1668
1669 uint32_t mixerStatus = MIXER_IDLE;
1670 // find out which tracks need to be processed
1671 size_t count = activeTracks.size();
1672 size_t mixedTracks = 0;
1673 size_t tracksWithEffect = 0;
1674
1675 float masterVolume = mMasterVolume;
1676 bool masterMute = mMasterMute;
1677
Eric Laurent571d49c2010-08-11 05:20:11 -07001678 if (masterMute) {
1679 masterVolume = 0;
1680 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001681#ifdef LVMX
1682 bool tracksConnectedChanged = false;
1683 bool stateChanged = false;
1684
1685 int audioOutputType = LifeVibes::getMixerType(mId, mType);
1686 if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType))
1687 {
1688 int activeTypes = 0;
1689 for (size_t i=0 ; i<count ; i++) {
1690 sp<Track> t = activeTracks[i].promote();
1691 if (t == 0) continue;
1692 Track* const track = t.get();
1693 int iTracktype=track->type();
1694 activeTypes |= 1<<track->type();
1695 }
1696 LifeVibes::computeVolumes(audioOutputType, activeTypes, tracksConnectedChanged, stateChanged, masterVolume, masterMute);
1697 }
1698#endif
1699 // Delegate master volume control to effect in output mix effect chain if needed
Eric Laurentde070132010-07-13 04:45:46 -07001700 sp<EffectChain> chain = getEffectChain_l(AudioSystem::SESSION_OUTPUT_MIX);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001701 if (chain != 0) {
Eric Laurent571d49c2010-08-11 05:20:11 -07001702 uint32_t v = (uint32_t)(masterVolume * (1 << 24));
Eric Laurentcab11242010-07-15 12:50:15 -07001703 chain->setVolume_l(&v, &v);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001704 masterVolume = (float)((v + (1 << 23)) >> 24);
1705 chain.clear();
1706 }
1707
1708 for (size_t i=0 ; i<count ; i++) {
1709 sp<Track> t = activeTracks[i].promote();
1710 if (t == 0) continue;
1711
1712 Track* const track = t.get();
1713 audio_track_cblk_t* cblk = track->cblk();
1714
1715 // The first time a track is added we wait
1716 // for all its buffers to be filled before processing it
1717 mAudioMixer->setActiveTrack(track->name());
1718 if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
1719 !track->isPaused() && !track->isTerminated())
1720 {
1721 //LOGV("track %d u=%08x, s=%08x [OK] on thread %p", track->name(), cblk->user, cblk->server, this);
1722
1723 mixedTracks++;
1724
1725 // track->mainBuffer() != mMixBuffer means there is an effect chain
1726 // connected to the track
1727 chain.clear();
1728 if (track->mainBuffer() != mMixBuffer) {
1729 chain = getEffectChain_l(track->sessionId());
1730 // Delegate volume control to effect in track effect chain if needed
1731 if (chain != 0) {
1732 tracksWithEffect++;
1733 } else {
1734 LOGW("prepareTracks_l(): track %08x attached to effect but no chain found on session %d",
1735 track->name(), track->sessionId());
1736 }
1737 }
1738
1739
1740 int param = AudioMixer::VOLUME;
1741 if (track->mFillingUpStatus == Track::FS_FILLED) {
1742 // no ramp for the first volume setting
1743 track->mFillingUpStatus = Track::FS_ACTIVE;
1744 if (track->mState == TrackBase::RESUMING) {
1745 track->mState = TrackBase::ACTIVE;
1746 param = AudioMixer::RAMP_VOLUME;
1747 }
1748 } else if (cblk->server != 0) {
1749 // If the track is stopped before the first frame was mixed,
1750 // do not apply ramp
1751 param = AudioMixer::RAMP_VOLUME;
1752 }
1753
1754 // compute volume for this track
Eric Laurente0aed6d2010-09-10 17:44:44 -07001755 uint32_t vl, vr, va;
Eric Laurent8569f0d2010-07-29 23:43:43 -07001756 if (track->isMuted() || track->isPausing() ||
Mathias Agopian65ab4712010-07-14 17:59:35 -07001757 mStreamTypes[track->type()].mute) {
Eric Laurente0aed6d2010-09-10 17:44:44 -07001758 vl = vr = va = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001759 if (track->isPausing()) {
1760 track->setPaused();
1761 }
1762 } else {
Eric Laurente0aed6d2010-09-10 17:44:44 -07001763
Mathias Agopian65ab4712010-07-14 17:59:35 -07001764 // read original volumes with volume control
1765 float typeVolume = mStreamTypes[track->type()].volume;
1766#ifdef LVMX
1767 bool streamMute=false;
1768 // read the volume from the LivesVibes audio engine.
1769 if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType))
1770 {
1771 LifeVibes::getStreamVolumes(audioOutputType, track->type(), &typeVolume, &streamMute);
1772 if (streamMute) {
1773 typeVolume = 0;
1774 }
1775 }
1776#endif
1777 float v = masterVolume * typeVolume;
Eric Laurente0aed6d2010-09-10 17:44:44 -07001778 vl = (uint32_t)(v * cblk->volume[0]) << 12;
1779 vr = (uint32_t)(v * cblk->volume[1]) << 12;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001780
Eric Laurente0aed6d2010-09-10 17:44:44 -07001781 va = (uint32_t)(v * cblk->sendLevel);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001782 }
Eric Laurente0aed6d2010-09-10 17:44:44 -07001783 // Delegate volume control to effect in track effect chain if needed
1784 if (chain != 0 && chain->setVolume_l(&vl, &vr)) {
1785 // Do not ramp volume if volume is controlled by effect
1786 param = AudioMixer::VOLUME;
1787 track->mHasVolumeController = true;
1788 } else {
1789 // force no volume ramp when volume controller was just disabled or removed
1790 // from effect chain to avoid volume spike
1791 if (track->mHasVolumeController) {
1792 param = AudioMixer::VOLUME;
1793 }
1794 track->mHasVolumeController = false;
1795 }
1796
1797 // Convert volumes from 8.24 to 4.12 format
1798 int16_t left, right, aux;
1799 uint32_t v_clamped = (vl + (1 << 11)) >> 12;
1800 if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT;
1801 left = int16_t(v_clamped);
1802 v_clamped = (vr + (1 << 11)) >> 12;
1803 if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT;
1804 right = int16_t(v_clamped);
1805
1806 if (va > MAX_GAIN_INT) va = MAX_GAIN_INT;
1807 aux = int16_t(va);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001808
1809#ifdef LVMX
1810 if ( tracksConnectedChanged || stateChanged )
1811 {
1812 // only do the ramp when the volume is changed by the user / application
1813 param = AudioMixer::VOLUME;
1814 }
1815#endif
1816
1817 // XXX: these things DON'T need to be done each time
1818 mAudioMixer->setBufferProvider(track);
1819 mAudioMixer->enable(AudioMixer::MIXING);
1820
1821 mAudioMixer->setParameter(param, AudioMixer::VOLUME0, (void *)left);
1822 mAudioMixer->setParameter(param, AudioMixer::VOLUME1, (void *)right);
1823 mAudioMixer->setParameter(param, AudioMixer::AUXLEVEL, (void *)aux);
1824 mAudioMixer->setParameter(
1825 AudioMixer::TRACK,
1826 AudioMixer::FORMAT, (void *)track->format());
1827 mAudioMixer->setParameter(
1828 AudioMixer::TRACK,
1829 AudioMixer::CHANNEL_COUNT, (void *)track->channelCount());
1830 mAudioMixer->setParameter(
1831 AudioMixer::RESAMPLE,
1832 AudioMixer::SAMPLE_RATE,
1833 (void *)(cblk->sampleRate));
1834 mAudioMixer->setParameter(
1835 AudioMixer::TRACK,
1836 AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer());
1837 mAudioMixer->setParameter(
1838 AudioMixer::TRACK,
1839 AudioMixer::AUX_BUFFER, (void *)track->auxBuffer());
1840
1841 // reset retry count
1842 track->mRetryCount = kMaxTrackRetries;
1843 mixerStatus = MIXER_TRACKS_READY;
1844 } else {
1845 //LOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", track->name(), cblk->user, cblk->server, this);
1846 if (track->isStopped()) {
1847 track->reset();
1848 }
1849 if (track->isTerminated() || track->isStopped() || track->isPaused()) {
1850 // We have consumed all the buffers of this track.
1851 // Remove it from the list of active tracks.
1852 tracksToRemove->add(track);
1853 } else {
1854 // No buffers for this track. Give it a few chances to
1855 // fill a buffer, then remove it from active list.
1856 if (--(track->mRetryCount) <= 0) {
1857 LOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this);
1858 tracksToRemove->add(track);
1859 } else if (mixerStatus != MIXER_TRACKS_READY) {
1860 mixerStatus = MIXER_TRACKS_ENABLED;
1861 }
1862 }
1863 mAudioMixer->disable(AudioMixer::MIXING);
1864 }
1865 }
1866
1867 // remove all the tracks that need to be...
1868 count = tracksToRemove->size();
1869 if (UNLIKELY(count)) {
1870 for (size_t i=0 ; i<count ; i++) {
1871 const sp<Track>& track = tracksToRemove->itemAt(i);
1872 mActiveTracks.remove(track);
1873 if (track->mainBuffer() != mMixBuffer) {
1874 chain = getEffectChain_l(track->sessionId());
1875 if (chain != 0) {
1876 LOGV("stopping track on chain %p for session Id: %d", chain.get(), track->sessionId());
1877 chain->stopTrack();
1878 }
1879 }
1880 if (track->isTerminated()) {
1881 mTracks.remove(track);
1882 deleteTrackName_l(track->mName);
1883 }
1884 }
1885 }
1886
1887 // mix buffer must be cleared if all tracks are connected to an
1888 // effect chain as in this case the mixer will not write to
1889 // mix buffer and track effects will accumulate into it
1890 if (mixedTracks != 0 && mixedTracks == tracksWithEffect) {
1891 memset(mMixBuffer, 0, mFrameCount * mChannelCount * sizeof(int16_t));
1892 }
1893
1894 return mixerStatus;
1895}
1896
1897void AudioFlinger::MixerThread::invalidateTracks(int streamType)
1898{
Eric Laurentde070132010-07-13 04:45:46 -07001899 LOGV ("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d",
1900 this, streamType, mTracks.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001901 Mutex::Autolock _l(mLock);
Eric Laurentde070132010-07-13 04:45:46 -07001902
Mathias Agopian65ab4712010-07-14 17:59:35 -07001903 size_t size = mTracks.size();
1904 for (size_t i = 0; i < size; i++) {
1905 sp<Track> t = mTracks[i];
1906 if (t->type() == streamType) {
1907 t->mCblk->lock.lock();
1908 t->mCblk->flags |= CBLK_INVALID_ON;
1909 t->mCblk->cv.signal();
1910 t->mCblk->lock.unlock();
1911 }
1912 }
1913}
1914
1915
1916// getTrackName_l() must be called with ThreadBase::mLock held
1917int AudioFlinger::MixerThread::getTrackName_l()
1918{
1919 return mAudioMixer->getTrackName();
1920}
1921
1922// deleteTrackName_l() must be called with ThreadBase::mLock held
1923void AudioFlinger::MixerThread::deleteTrackName_l(int name)
1924{
1925 LOGV("remove track (%d) and delete from mixer", name);
1926 mAudioMixer->deleteTrackName(name);
1927}
1928
1929// checkForNewParameters_l() must be called with ThreadBase::mLock held
1930bool AudioFlinger::MixerThread::checkForNewParameters_l()
1931{
1932 bool reconfig = false;
1933
1934 while (!mNewParameters.isEmpty()) {
1935 status_t status = NO_ERROR;
1936 String8 keyValuePair = mNewParameters[0];
1937 AudioParameter param = AudioParameter(keyValuePair);
1938 int value;
1939
1940 if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
1941 reconfig = true;
1942 }
1943 if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
1944 if (value != AudioSystem::PCM_16_BIT) {
1945 status = BAD_VALUE;
1946 } else {
1947 reconfig = true;
1948 }
1949 }
1950 if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
1951 if (value != AudioSystem::CHANNEL_OUT_STEREO) {
1952 status = BAD_VALUE;
1953 } else {
1954 reconfig = true;
1955 }
1956 }
1957 if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
1958 // do not accept frame count changes if tracks are open as the track buffer
1959 // size depends on frame count and correct behavior would not be garantied
1960 // if frame count is changed after track creation
1961 if (!mTracks.isEmpty()) {
1962 status = INVALID_OPERATION;
1963 } else {
1964 reconfig = true;
1965 }
1966 }
1967 if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
1968 // forward device change to effects that have requested to be
1969 // aware of attached audio device.
1970 mDevice = (uint32_t)value;
1971 for (size_t i = 0; i < mEffectChains.size(); i++) {
Eric Laurentcab11242010-07-15 12:50:15 -07001972 mEffectChains[i]->setDevice_l(mDevice);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001973 }
1974 }
1975
1976 if (status == NO_ERROR) {
1977 status = mOutput->setParameters(keyValuePair);
1978 if (!mStandby && status == INVALID_OPERATION) {
1979 mOutput->standby();
1980 mStandby = true;
1981 mBytesWritten = 0;
1982 status = mOutput->setParameters(keyValuePair);
1983 }
1984 if (status == NO_ERROR && reconfig) {
1985 delete mAudioMixer;
1986 readOutputParameters();
1987 mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
1988 for (size_t i = 0; i < mTracks.size() ; i++) {
1989 int name = getTrackName_l();
1990 if (name < 0) break;
1991 mTracks[i]->mName = name;
1992 // limit track sample rate to 2 x new output sample rate
1993 if (mTracks[i]->mCblk->sampleRate > 2 * sampleRate()) {
1994 mTracks[i]->mCblk->sampleRate = 2 * sampleRate();
1995 }
1996 }
1997 sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
1998 }
1999 }
2000
2001 mNewParameters.removeAt(0);
2002
2003 mParamStatus = status;
2004 mParamCond.signal();
2005 mWaitWorkCV.wait(mLock);
2006 }
2007 return reconfig;
2008}
2009
2010status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
2011{
2012 const size_t SIZE = 256;
2013 char buffer[SIZE];
2014 String8 result;
2015
2016 PlaybackThread::dumpInternals(fd, args);
2017
2018 snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
2019 result.append(buffer);
2020 write(fd, result.string(), result.size());
2021 return NO_ERROR;
2022}
2023
2024uint32_t AudioFlinger::MixerThread::activeSleepTimeUs()
2025{
2026 return (uint32_t)(mOutput->latency() * 1000) / 2;
2027}
2028
2029uint32_t AudioFlinger::MixerThread::idleSleepTimeUs()
2030{
Eric Laurent60e18242010-07-29 06:50:24 -07002031 return (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000) / 2;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002032}
2033
Eric Laurent25cbe0e2010-08-18 18:13:17 -07002034uint32_t AudioFlinger::MixerThread::suspendSleepTimeUs()
2035{
2036 return (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000);
2037}
2038
Mathias Agopian65ab4712010-07-14 17:59:35 -07002039// ----------------------------------------------------------------------------
2040AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
2041 : PlaybackThread(audioFlinger, output, id, device)
2042{
2043 mType = PlaybackThread::DIRECT;
2044}
2045
2046AudioFlinger::DirectOutputThread::~DirectOutputThread()
2047{
2048}
2049
2050
2051static inline int16_t clamp16(int32_t sample)
2052{
2053 if ((sample>>15) ^ (sample>>31))
2054 sample = 0x7FFF ^ (sample>>31);
2055 return sample;
2056}
2057
2058static inline
2059int32_t mul(int16_t in, int16_t v)
2060{
2061#if defined(__arm__) && !defined(__thumb__)
2062 int32_t out;
2063 asm( "smulbb %[out], %[in], %[v] \n"
2064 : [out]"=r"(out)
2065 : [in]"%r"(in), [v]"r"(v)
2066 : );
2067 return out;
2068#else
2069 return in * int32_t(v);
2070#endif
2071}
2072
2073void AudioFlinger::DirectOutputThread::applyVolume(uint16_t leftVol, uint16_t rightVol, bool ramp)
2074{
2075 // Do not apply volume on compressed audio
2076 if (!AudioSystem::isLinearPCM(mFormat)) {
2077 return;
2078 }
2079
2080 // convert to signed 16 bit before volume calculation
2081 if (mFormat == AudioSystem::PCM_8_BIT) {
2082 size_t count = mFrameCount * mChannelCount;
2083 uint8_t *src = (uint8_t *)mMixBuffer + count-1;
2084 int16_t *dst = mMixBuffer + count-1;
2085 while(count--) {
2086 *dst-- = (int16_t)(*src--^0x80) << 8;
2087 }
2088 }
2089
2090 size_t frameCount = mFrameCount;
2091 int16_t *out = mMixBuffer;
2092 if (ramp) {
2093 if (mChannelCount == 1) {
2094 int32_t d = ((int32_t)leftVol - (int32_t)mLeftVolShort) << 16;
2095 int32_t vlInc = d / (int32_t)frameCount;
2096 int32_t vl = ((int32_t)mLeftVolShort << 16);
2097 do {
2098 out[0] = clamp16(mul(out[0], vl >> 16) >> 12);
2099 out++;
2100 vl += vlInc;
2101 } while (--frameCount);
2102
2103 } else {
2104 int32_t d = ((int32_t)leftVol - (int32_t)mLeftVolShort) << 16;
2105 int32_t vlInc = d / (int32_t)frameCount;
2106 d = ((int32_t)rightVol - (int32_t)mRightVolShort) << 16;
2107 int32_t vrInc = d / (int32_t)frameCount;
2108 int32_t vl = ((int32_t)mLeftVolShort << 16);
2109 int32_t vr = ((int32_t)mRightVolShort << 16);
2110 do {
2111 out[0] = clamp16(mul(out[0], vl >> 16) >> 12);
2112 out[1] = clamp16(mul(out[1], vr >> 16) >> 12);
2113 out += 2;
2114 vl += vlInc;
2115 vr += vrInc;
2116 } while (--frameCount);
2117 }
2118 } else {
2119 if (mChannelCount == 1) {
2120 do {
2121 out[0] = clamp16(mul(out[0], leftVol) >> 12);
2122 out++;
2123 } while (--frameCount);
2124 } else {
2125 do {
2126 out[0] = clamp16(mul(out[0], leftVol) >> 12);
2127 out[1] = clamp16(mul(out[1], rightVol) >> 12);
2128 out += 2;
2129 } while (--frameCount);
2130 }
2131 }
2132
2133 // convert back to unsigned 8 bit after volume calculation
2134 if (mFormat == AudioSystem::PCM_8_BIT) {
2135 size_t count = mFrameCount * mChannelCount;
2136 int16_t *src = mMixBuffer;
2137 uint8_t *dst = (uint8_t *)mMixBuffer;
2138 while(count--) {
2139 *dst++ = (uint8_t)(((int32_t)*src++ + (1<<7)) >> 8)^0x80;
2140 }
2141 }
2142
2143 mLeftVolShort = leftVol;
2144 mRightVolShort = rightVol;
2145}
2146
2147bool AudioFlinger::DirectOutputThread::threadLoop()
2148{
2149 uint32_t mixerStatus = MIXER_IDLE;
2150 sp<Track> trackToRemove;
2151 sp<Track> activeTrack;
2152 nsecs_t standbyTime = systemTime();
2153 int8_t *curBuf;
2154 size_t mixBufferSize = mFrameCount*mFrameSize;
2155 uint32_t activeSleepTime = activeSleepTimeUs();
2156 uint32_t idleSleepTime = idleSleepTimeUs();
2157 uint32_t sleepTime = idleSleepTime;
2158 // use shorter standby delay as on normal output to release
2159 // hardware resources as soon as possible
2160 nsecs_t standbyDelay = microseconds(activeSleepTime*2);
2161
Mathias Agopian65ab4712010-07-14 17:59:35 -07002162 while (!exitPending())
2163 {
2164 bool rampVolume;
2165 uint16_t leftVol;
2166 uint16_t rightVol;
2167 Vector< sp<EffectChain> > effectChains;
2168
2169 processConfigEvents();
2170
2171 mixerStatus = MIXER_IDLE;
2172
2173 { // scope for the mLock
2174
2175 Mutex::Autolock _l(mLock);
2176
2177 if (checkForNewParameters_l()) {
2178 mixBufferSize = mFrameCount*mFrameSize;
2179 activeSleepTime = activeSleepTimeUs();
2180 idleSleepTime = idleSleepTimeUs();
2181 standbyDelay = microseconds(activeSleepTime*2);
2182 }
2183
2184 // put audio hardware into standby after short delay
2185 if UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
2186 mSuspended) {
2187 // wait until we have something to do...
2188 if (!mStandby) {
2189 LOGV("Audio hardware entering standby, mixer %p\n", this);
2190 mOutput->standby();
2191 mStandby = true;
2192 mBytesWritten = 0;
2193 }
2194
2195 if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
2196 // we're about to wait, flush the binder command buffer
2197 IPCThreadState::self()->flushCommands();
2198
2199 if (exitPending()) break;
2200
2201 LOGV("DirectOutputThread %p TID %d going to sleep\n", this, gettid());
2202 mWaitWorkCV.wait(mLock);
2203 LOGV("DirectOutputThread %p TID %d waking up in active mode\n", this, gettid());
2204
2205 if (mMasterMute == false) {
2206 char value[PROPERTY_VALUE_MAX];
2207 property_get("ro.audio.silent", value, "0");
2208 if (atoi(value)) {
2209 LOGD("Silence is golden");
2210 setMasterMute(true);
2211 }
2212 }
2213
2214 standbyTime = systemTime() + standbyDelay;
2215 sleepTime = idleSleepTime;
2216 continue;
2217 }
2218 }
2219
2220 effectChains = mEffectChains;
2221
2222 // find out which tracks need to be processed
2223 if (mActiveTracks.size() != 0) {
2224 sp<Track> t = mActiveTracks[0].promote();
2225 if (t == 0) continue;
2226
2227 Track* const track = t.get();
2228 audio_track_cblk_t* cblk = track->cblk();
2229
2230 // The first time a track is added we wait
2231 // for all its buffers to be filled before processing it
2232 if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
2233 !track->isPaused() && !track->isTerminated())
2234 {
2235 //LOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
2236
2237 if (track->mFillingUpStatus == Track::FS_FILLED) {
2238 track->mFillingUpStatus = Track::FS_ACTIVE;
2239 mLeftVolFloat = mRightVolFloat = 0;
2240 mLeftVolShort = mRightVolShort = 0;
2241 if (track->mState == TrackBase::RESUMING) {
2242 track->mState = TrackBase::ACTIVE;
2243 rampVolume = true;
2244 }
2245 } else if (cblk->server != 0) {
2246 // If the track is stopped before the first frame was mixed,
2247 // do not apply ramp
2248 rampVolume = true;
2249 }
2250 // compute volume for this track
2251 float left, right;
2252 if (track->isMuted() || mMasterMute || track->isPausing() ||
2253 mStreamTypes[track->type()].mute) {
2254 left = right = 0;
2255 if (track->isPausing()) {
2256 track->setPaused();
2257 }
2258 } else {
2259 float typeVolume = mStreamTypes[track->type()].volume;
2260 float v = mMasterVolume * typeVolume;
2261 float v_clamped = v * cblk->volume[0];
2262 if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
2263 left = v_clamped/MAX_GAIN;
2264 v_clamped = v * cblk->volume[1];
2265 if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
2266 right = v_clamped/MAX_GAIN;
2267 }
2268
2269 if (left != mLeftVolFloat || right != mRightVolFloat) {
2270 mLeftVolFloat = left;
2271 mRightVolFloat = right;
2272
2273 // If audio HAL implements volume control,
2274 // force software volume to nominal value
2275 if (mOutput->setVolume(left, right) == NO_ERROR) {
2276 left = 1.0f;
2277 right = 1.0f;
2278 }
2279
2280 // Convert volumes from float to 8.24
2281 uint32_t vl = (uint32_t)(left * (1 << 24));
2282 uint32_t vr = (uint32_t)(right * (1 << 24));
2283
2284 // Delegate volume control to effect in track effect chain if needed
2285 // only one effect chain can be present on DirectOutputThread, so if
2286 // there is one, the track is connected to it
2287 if (!effectChains.isEmpty()) {
Eric Laurente0aed6d2010-09-10 17:44:44 -07002288 // Do not ramp volume if volume is controlled by effect
Eric Laurentcab11242010-07-15 12:50:15 -07002289 if(effectChains[0]->setVolume_l(&vl, &vr)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07002290 rampVolume = false;
2291 }
2292 }
2293
2294 // Convert volumes from 8.24 to 4.12 format
2295 uint32_t v_clamped = (vl + (1 << 11)) >> 12;
2296 if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT;
2297 leftVol = (uint16_t)v_clamped;
2298 v_clamped = (vr + (1 << 11)) >> 12;
2299 if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT;
2300 rightVol = (uint16_t)v_clamped;
2301 } else {
2302 leftVol = mLeftVolShort;
2303 rightVol = mRightVolShort;
2304 rampVolume = false;
2305 }
2306
2307 // reset retry count
2308 track->mRetryCount = kMaxTrackRetriesDirect;
2309 activeTrack = t;
2310 mixerStatus = MIXER_TRACKS_READY;
2311 } else {
2312 //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
2313 if (track->isStopped()) {
2314 track->reset();
2315 }
2316 if (track->isTerminated() || track->isStopped() || track->isPaused()) {
2317 // We have consumed all the buffers of this track.
2318 // Remove it from the list of active tracks.
2319 trackToRemove = track;
2320 } else {
2321 // No buffers for this track. Give it a few chances to
2322 // fill a buffer, then remove it from active list.
2323 if (--(track->mRetryCount) <= 0) {
2324 LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
2325 trackToRemove = track;
2326 } else {
2327 mixerStatus = MIXER_TRACKS_ENABLED;
2328 }
2329 }
2330 }
2331 }
2332
2333 // remove all the tracks that need to be...
2334 if (UNLIKELY(trackToRemove != 0)) {
2335 mActiveTracks.remove(trackToRemove);
2336 if (!effectChains.isEmpty()) {
Eric Laurentde070132010-07-13 04:45:46 -07002337 LOGV("stopping track on chain %p for session Id: %d", effectChains[0].get(),
2338 trackToRemove->sessionId());
Mathias Agopian65ab4712010-07-14 17:59:35 -07002339 effectChains[0]->stopTrack();
2340 }
2341 if (trackToRemove->isTerminated()) {
2342 mTracks.remove(trackToRemove);
2343 deleteTrackName_l(trackToRemove->mName);
2344 }
2345 }
2346
Eric Laurentde070132010-07-13 04:45:46 -07002347 lockEffectChains_l(effectChains);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002348 }
2349
2350 if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
2351 AudioBufferProvider::Buffer buffer;
2352 size_t frameCount = mFrameCount;
2353 curBuf = (int8_t *)mMixBuffer;
2354 // output audio to hardware
2355 while (frameCount) {
2356 buffer.frameCount = frameCount;
2357 activeTrack->getNextBuffer(&buffer);
2358 if (UNLIKELY(buffer.raw == 0)) {
2359 memset(curBuf, 0, frameCount * mFrameSize);
2360 break;
2361 }
2362 memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
2363 frameCount -= buffer.frameCount;
2364 curBuf += buffer.frameCount * mFrameSize;
2365 activeTrack->releaseBuffer(&buffer);
2366 }
2367 sleepTime = 0;
2368 standbyTime = systemTime() + standbyDelay;
2369 } else {
2370 if (sleepTime == 0) {
2371 if (mixerStatus == MIXER_TRACKS_ENABLED) {
2372 sleepTime = activeSleepTime;
2373 } else {
2374 sleepTime = idleSleepTime;
2375 }
2376 } else if (mBytesWritten != 0 && AudioSystem::isLinearPCM(mFormat)) {
2377 memset (mMixBuffer, 0, mFrameCount * mFrameSize);
2378 sleepTime = 0;
2379 }
2380 }
2381
2382 if (mSuspended) {
Eric Laurent25cbe0e2010-08-18 18:13:17 -07002383 sleepTime = suspendSleepTimeUs();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002384 }
2385 // sleepTime == 0 means we must write to audio hardware
2386 if (sleepTime == 0) {
2387 if (mixerStatus == MIXER_TRACKS_READY) {
2388 applyVolume(leftVol, rightVol, rampVolume);
2389 }
2390 for (size_t i = 0; i < effectChains.size(); i ++) {
2391 effectChains[i]->process_l();
2392 }
Eric Laurentde070132010-07-13 04:45:46 -07002393 unlockEffectChains(effectChains);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002394
2395 mLastWriteTime = systemTime();
2396 mInWrite = true;
2397 mBytesWritten += mixBufferSize;
2398 int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
2399 if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
2400 mNumWrites++;
2401 mInWrite = false;
2402 mStandby = false;
2403 } else {
Eric Laurentde070132010-07-13 04:45:46 -07002404 unlockEffectChains(effectChains);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002405 usleep(sleepTime);
2406 }
2407
2408 // finally let go of removed track, without the lock held
2409 // since we can't guarantee the destructors won't acquire that
2410 // same lock.
2411 trackToRemove.clear();
2412 activeTrack.clear();
2413
2414 // Effect chains will be actually deleted here if they were removed from
2415 // mEffectChains list during mixing or effects processing
2416 effectChains.clear();
2417 }
2418
2419 if (!mStandby) {
2420 mOutput->standby();
2421 }
2422
2423 LOGV("DirectOutputThread %p exiting", this);
2424 return false;
2425}
2426
2427// getTrackName_l() must be called with ThreadBase::mLock held
2428int AudioFlinger::DirectOutputThread::getTrackName_l()
2429{
2430 return 0;
2431}
2432
2433// deleteTrackName_l() must be called with ThreadBase::mLock held
2434void AudioFlinger::DirectOutputThread::deleteTrackName_l(int name)
2435{
2436}
2437
2438// checkForNewParameters_l() must be called with ThreadBase::mLock held
2439bool AudioFlinger::DirectOutputThread::checkForNewParameters_l()
2440{
2441 bool reconfig = false;
2442
2443 while (!mNewParameters.isEmpty()) {
2444 status_t status = NO_ERROR;
2445 String8 keyValuePair = mNewParameters[0];
2446 AudioParameter param = AudioParameter(keyValuePair);
2447 int value;
2448
2449 if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
2450 // do not accept frame count changes if tracks are open as the track buffer
2451 // size depends on frame count and correct behavior would not be garantied
2452 // if frame count is changed after track creation
2453 if (!mTracks.isEmpty()) {
2454 status = INVALID_OPERATION;
2455 } else {
2456 reconfig = true;
2457 }
2458 }
2459 if (status == NO_ERROR) {
2460 status = mOutput->setParameters(keyValuePair);
2461 if (!mStandby && status == INVALID_OPERATION) {
2462 mOutput->standby();
2463 mStandby = true;
2464 mBytesWritten = 0;
2465 status = mOutput->setParameters(keyValuePair);
2466 }
2467 if (status == NO_ERROR && reconfig) {
2468 readOutputParameters();
2469 sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
2470 }
2471 }
2472
2473 mNewParameters.removeAt(0);
2474
2475 mParamStatus = status;
2476 mParamCond.signal();
2477 mWaitWorkCV.wait(mLock);
2478 }
2479 return reconfig;
2480}
2481
2482uint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs()
2483{
2484 uint32_t time;
2485 if (AudioSystem::isLinearPCM(mFormat)) {
2486 time = (uint32_t)(mOutput->latency() * 1000) / 2;
2487 } else {
2488 time = 10000;
2489 }
2490 return time;
2491}
2492
2493uint32_t AudioFlinger::DirectOutputThread::idleSleepTimeUs()
2494{
2495 uint32_t time;
2496 if (AudioSystem::isLinearPCM(mFormat)) {
Eric Laurent60e18242010-07-29 06:50:24 -07002497 time = (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000) / 2;
Mathias Agopian65ab4712010-07-14 17:59:35 -07002498 } else {
2499 time = 10000;
2500 }
2501 return time;
2502}
2503
Eric Laurent25cbe0e2010-08-18 18:13:17 -07002504uint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs()
2505{
2506 uint32_t time;
2507 if (AudioSystem::isLinearPCM(mFormat)) {
2508 time = (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000);
2509 } else {
2510 time = 10000;
2511 }
2512 return time;
2513}
2514
2515
Mathias Agopian65ab4712010-07-14 17:59:35 -07002516// ----------------------------------------------------------------------------
2517
2518AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::MixerThread* mainThread, int id)
2519 : MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->device()), mWaitTimeMs(UINT_MAX)
2520{
2521 mType = PlaybackThread::DUPLICATING;
2522 addOutputTrack(mainThread);
2523}
2524
2525AudioFlinger::DuplicatingThread::~DuplicatingThread()
2526{
2527 for (size_t i = 0; i < mOutputTracks.size(); i++) {
2528 mOutputTracks[i]->destroy();
2529 }
2530 mOutputTracks.clear();
2531}
2532
2533bool AudioFlinger::DuplicatingThread::threadLoop()
2534{
2535 Vector< sp<Track> > tracksToRemove;
2536 uint32_t mixerStatus = MIXER_IDLE;
2537 nsecs_t standbyTime = systemTime();
2538 size_t mixBufferSize = mFrameCount*mFrameSize;
2539 SortedVector< sp<OutputTrack> > outputTracks;
2540 uint32_t writeFrames = 0;
2541 uint32_t activeSleepTime = activeSleepTimeUs();
2542 uint32_t idleSleepTime = idleSleepTimeUs();
2543 uint32_t sleepTime = idleSleepTime;
2544 Vector< sp<EffectChain> > effectChains;
2545
2546 while (!exitPending())
2547 {
2548 processConfigEvents();
2549
2550 mixerStatus = MIXER_IDLE;
2551 { // scope for the mLock
2552
2553 Mutex::Autolock _l(mLock);
2554
2555 if (checkForNewParameters_l()) {
2556 mixBufferSize = mFrameCount*mFrameSize;
2557 updateWaitTime();
2558 activeSleepTime = activeSleepTimeUs();
2559 idleSleepTime = idleSleepTimeUs();
2560 }
2561
2562 const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
2563
2564 for (size_t i = 0; i < mOutputTracks.size(); i++) {
2565 outputTracks.add(mOutputTracks[i]);
2566 }
2567
2568 // put audio hardware into standby after short delay
2569 if UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
2570 mSuspended) {
2571 if (!mStandby) {
2572 for (size_t i = 0; i < outputTracks.size(); i++) {
2573 outputTracks[i]->stop();
2574 }
2575 mStandby = true;
2576 mBytesWritten = 0;
2577 }
2578
2579 if (!activeTracks.size() && mConfigEvents.isEmpty()) {
2580 // we're about to wait, flush the binder command buffer
2581 IPCThreadState::self()->flushCommands();
2582 outputTracks.clear();
2583
2584 if (exitPending()) break;
2585
2586 LOGV("DuplicatingThread %p TID %d going to sleep\n", this, gettid());
2587 mWaitWorkCV.wait(mLock);
2588 LOGV("DuplicatingThread %p TID %d waking up\n", this, gettid());
2589 if (mMasterMute == false) {
2590 char value[PROPERTY_VALUE_MAX];
2591 property_get("ro.audio.silent", value, "0");
2592 if (atoi(value)) {
2593 LOGD("Silence is golden");
2594 setMasterMute(true);
2595 }
2596 }
2597
2598 standbyTime = systemTime() + kStandbyTimeInNsecs;
2599 sleepTime = idleSleepTime;
2600 continue;
2601 }
2602 }
2603
2604 mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
2605
2606 // prevent any changes in effect chain list and in each effect chain
2607 // during mixing and effect process as the audio buffers could be deleted
2608 // or modified if an effect is created or deleted
Eric Laurentde070132010-07-13 04:45:46 -07002609 lockEffectChains_l(effectChains);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002610 }
2611
2612 if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
2613 // mix buffers...
2614 if (outputsReady(outputTracks)) {
2615 mAudioMixer->process();
2616 } else {
2617 memset(mMixBuffer, 0, mixBufferSize);
2618 }
2619 sleepTime = 0;
2620 writeFrames = mFrameCount;
2621 } else {
2622 if (sleepTime == 0) {
2623 if (mixerStatus == MIXER_TRACKS_ENABLED) {
2624 sleepTime = activeSleepTime;
2625 } else {
2626 sleepTime = idleSleepTime;
2627 }
2628 } else if (mBytesWritten != 0) {
2629 // flush remaining overflow buffers in output tracks
2630 for (size_t i = 0; i < outputTracks.size(); i++) {
2631 if (outputTracks[i]->isActive()) {
2632 sleepTime = 0;
2633 writeFrames = 0;
2634 memset(mMixBuffer, 0, mixBufferSize);
2635 break;
2636 }
2637 }
2638 }
2639 }
2640
2641 if (mSuspended) {
Eric Laurent25cbe0e2010-08-18 18:13:17 -07002642 sleepTime = suspendSleepTimeUs();
Mathias Agopian65ab4712010-07-14 17:59:35 -07002643 }
2644 // sleepTime == 0 means we must write to audio hardware
2645 if (sleepTime == 0) {
2646 for (size_t i = 0; i < effectChains.size(); i ++) {
2647 effectChains[i]->process_l();
2648 }
2649 // enable changes in effect chain
Eric Laurentde070132010-07-13 04:45:46 -07002650 unlockEffectChains(effectChains);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002651
2652 standbyTime = systemTime() + kStandbyTimeInNsecs;
2653 for (size_t i = 0; i < outputTracks.size(); i++) {
2654 outputTracks[i]->write(mMixBuffer, writeFrames);
2655 }
2656 mStandby = false;
2657 mBytesWritten += mixBufferSize;
2658 } else {
2659 // enable changes in effect chain
Eric Laurentde070132010-07-13 04:45:46 -07002660 unlockEffectChains(effectChains);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002661 usleep(sleepTime);
2662 }
2663
2664 // finally let go of all our tracks, without the lock held
2665 // since we can't guarantee the destructors won't acquire that
2666 // same lock.
2667 tracksToRemove.clear();
2668 outputTracks.clear();
2669
2670 // Effect chains will be actually deleted here if they were removed from
2671 // mEffectChains list during mixing or effects processing
2672 effectChains.clear();
2673 }
2674
2675 return false;
2676}
2677
2678void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
2679{
2680 int frameCount = (3 * mFrameCount * mSampleRate) / thread->sampleRate();
2681 OutputTrack *outputTrack = new OutputTrack((ThreadBase *)thread,
2682 this,
2683 mSampleRate,
2684 mFormat,
2685 mChannelCount,
2686 frameCount);
2687 if (outputTrack->cblk() != NULL) {
2688 thread->setStreamVolume(AudioSystem::NUM_STREAM_TYPES, 1.0f);
2689 mOutputTracks.add(outputTrack);
2690 LOGV("addOutputTrack() track %p, on thread %p", outputTrack, thread);
2691 updateWaitTime();
2692 }
2693}
2694
2695void AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread)
2696{
2697 Mutex::Autolock _l(mLock);
2698 for (size_t i = 0; i < mOutputTracks.size(); i++) {
2699 if (mOutputTracks[i]->thread() == (ThreadBase *)thread) {
2700 mOutputTracks[i]->destroy();
2701 mOutputTracks.removeAt(i);
2702 updateWaitTime();
2703 return;
2704 }
2705 }
2706 LOGV("removeOutputTrack(): unkonwn thread: %p", thread);
2707}
2708
2709void AudioFlinger::DuplicatingThread::updateWaitTime()
2710{
2711 mWaitTimeMs = UINT_MAX;
2712 for (size_t i = 0; i < mOutputTracks.size(); i++) {
2713 sp<ThreadBase> strong = mOutputTracks[i]->thread().promote();
2714 if (strong != NULL) {
2715 uint32_t waitTimeMs = (strong->frameCount() * 2 * 1000) / strong->sampleRate();
2716 if (waitTimeMs < mWaitTimeMs) {
2717 mWaitTimeMs = waitTimeMs;
2718 }
2719 }
2720 }
2721}
2722
2723
2724bool AudioFlinger::DuplicatingThread::outputsReady(SortedVector< sp<OutputTrack> > &outputTracks)
2725{
2726 for (size_t i = 0; i < outputTracks.size(); i++) {
2727 sp <ThreadBase> thread = outputTracks[i]->thread().promote();
2728 if (thread == 0) {
2729 LOGW("DuplicatingThread::outputsReady() could not promote thread on output track %p", outputTracks[i].get());
2730 return false;
2731 }
2732 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
2733 if (playbackThread->standby() && !playbackThread->isSuspended()) {
2734 LOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(), thread.get());
2735 return false;
2736 }
2737 }
2738 return true;
2739}
2740
2741uint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs()
2742{
2743 return (mWaitTimeMs * 1000) / 2;
2744}
2745
2746// ----------------------------------------------------------------------------
2747
2748// TrackBase constructor must be called with AudioFlinger::mLock held
2749AudioFlinger::ThreadBase::TrackBase::TrackBase(
2750 const wp<ThreadBase>& thread,
2751 const sp<Client>& client,
2752 uint32_t sampleRate,
2753 int format,
2754 int channelCount,
2755 int frameCount,
2756 uint32_t flags,
2757 const sp<IMemory>& sharedBuffer,
2758 int sessionId)
2759 : RefBase(),
2760 mThread(thread),
2761 mClient(client),
2762 mCblk(0),
2763 mFrameCount(0),
2764 mState(IDLE),
2765 mClientTid(-1),
2766 mFormat(format),
2767 mFlags(flags & ~SYSTEM_FLAGS_MASK),
2768 mSessionId(sessionId)
2769{
2770 LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
2771
2772 // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
2773 size_t size = sizeof(audio_track_cblk_t);
2774 size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
2775 if (sharedBuffer == 0) {
2776 size += bufferSize;
2777 }
2778
2779 if (client != NULL) {
2780 mCblkMemory = client->heap()->allocate(size);
2781 if (mCblkMemory != 0) {
2782 mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
2783 if (mCblk) { // construct the shared structure in-place.
2784 new(mCblk) audio_track_cblk_t();
2785 // clear all buffers
2786 mCblk->frameCount = frameCount;
2787 mCblk->sampleRate = sampleRate;
2788 mCblk->channelCount = (uint8_t)channelCount;
2789 if (sharedBuffer == 0) {
2790 mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
2791 memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
2792 // Force underrun condition to avoid false underrun callback until first data is
2793 // written to buffer
2794 mCblk->flags = CBLK_UNDERRUN_ON;
2795 } else {
2796 mBuffer = sharedBuffer->pointer();
2797 }
2798 mBufferEnd = (uint8_t *)mBuffer + bufferSize;
2799 }
2800 } else {
2801 LOGE("not enough memory for AudioTrack size=%u", size);
2802 client->heap()->dump("AudioTrack");
2803 return;
2804 }
2805 } else {
2806 mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
2807 if (mCblk) { // construct the shared structure in-place.
2808 new(mCblk) audio_track_cblk_t();
2809 // clear all buffers
2810 mCblk->frameCount = frameCount;
2811 mCblk->sampleRate = sampleRate;
2812 mCblk->channelCount = (uint8_t)channelCount;
2813 mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
2814 memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
2815 // Force underrun condition to avoid false underrun callback until first data is
2816 // written to buffer
2817 mCblk->flags = CBLK_UNDERRUN_ON;
2818 mBufferEnd = (uint8_t *)mBuffer + bufferSize;
2819 }
2820 }
2821}
2822
2823AudioFlinger::ThreadBase::TrackBase::~TrackBase()
2824{
2825 if (mCblk) {
2826 mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
2827 if (mClient == NULL) {
2828 delete mCblk;
2829 }
2830 }
2831 mCblkMemory.clear(); // and free the shared memory
2832 if (mClient != NULL) {
2833 Mutex::Autolock _l(mClient->audioFlinger()->mLock);
2834 mClient.clear();
2835 }
2836}
2837
2838void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
2839{
2840 buffer->raw = 0;
2841 mFrameCount = buffer->frameCount;
2842 step();
2843 buffer->frameCount = 0;
2844}
2845
2846bool AudioFlinger::ThreadBase::TrackBase::step() {
2847 bool result;
2848 audio_track_cblk_t* cblk = this->cblk();
2849
2850 result = cblk->stepServer(mFrameCount);
2851 if (!result) {
2852 LOGV("stepServer failed acquiring cblk mutex");
2853 mFlags |= STEPSERVER_FAILED;
2854 }
2855 return result;
2856}
2857
2858void AudioFlinger::ThreadBase::TrackBase::reset() {
2859 audio_track_cblk_t* cblk = this->cblk();
2860
2861 cblk->user = 0;
2862 cblk->server = 0;
2863 cblk->userBase = 0;
2864 cblk->serverBase = 0;
2865 mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
2866 LOGV("TrackBase::reset");
2867}
2868
2869sp<IMemory> AudioFlinger::ThreadBase::TrackBase::getCblk() const
2870{
2871 return mCblkMemory;
2872}
2873
2874int AudioFlinger::ThreadBase::TrackBase::sampleRate() const {
2875 return (int)mCblk->sampleRate;
2876}
2877
2878int AudioFlinger::ThreadBase::TrackBase::channelCount() const {
2879 return (int)mCblk->channelCount;
2880}
2881
2882void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
2883 audio_track_cblk_t* cblk = this->cblk();
2884 int8_t *bufferStart = (int8_t *)mBuffer + (offset-cblk->serverBase)*cblk->frameSize;
2885 int8_t *bufferEnd = bufferStart + frames * cblk->frameSize;
2886
2887 // Check validity of returned pointer in case the track control block would have been corrupted.
2888 if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd ||
2889 ((unsigned long)bufferStart & (unsigned long)(cblk->frameSize - 1))) {
2890 LOGE("TrackBase::getBuffer buffer out of range:\n start: %p, end %p , mBuffer %p mBufferEnd %p\n \
2891 server %d, serverBase %d, user %d, userBase %d, channelCount %d",
2892 bufferStart, bufferEnd, mBuffer, mBufferEnd,
2893 cblk->server, cblk->serverBase, cblk->user, cblk->userBase, cblk->channelCount);
2894 return 0;
2895 }
2896
2897 return bufferStart;
2898}
2899
2900// ----------------------------------------------------------------------------
2901
2902// Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
2903AudioFlinger::PlaybackThread::Track::Track(
2904 const wp<ThreadBase>& thread,
2905 const sp<Client>& client,
2906 int streamType,
2907 uint32_t sampleRate,
2908 int format,
2909 int channelCount,
2910 int frameCount,
2911 const sp<IMemory>& sharedBuffer,
2912 int sessionId)
2913 : TrackBase(thread, client, sampleRate, format, channelCount, frameCount, 0, sharedBuffer, sessionId),
Eric Laurent8f45bd72010-08-31 13:50:07 -07002914 mMute(false), mSharedBuffer(sharedBuffer), mName(-1), mMainBuffer(NULL), mAuxBuffer(NULL),
2915 mAuxEffectId(0), mHasVolumeController(false)
Mathias Agopian65ab4712010-07-14 17:59:35 -07002916{
2917 if (mCblk != NULL) {
2918 sp<ThreadBase> baseThread = thread.promote();
2919 if (baseThread != 0) {
2920 PlaybackThread *playbackThread = (PlaybackThread *)baseThread.get();
2921 mName = playbackThread->getTrackName_l();
2922 mMainBuffer = playbackThread->mixBuffer();
2923 }
2924 LOGV("Track constructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
2925 if (mName < 0) {
2926 LOGE("no more track names available");
2927 }
2928 mVolume[0] = 1.0f;
2929 mVolume[1] = 1.0f;
2930 mStreamType = streamType;
2931 // NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of
2932 // 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack
2933 mCblk->frameSize = AudioSystem::isLinearPCM(format) ? channelCount * sizeof(int16_t) : sizeof(int8_t);
2934 }
2935}
2936
2937AudioFlinger::PlaybackThread::Track::~Track()
2938{
2939 LOGV("PlaybackThread::Track destructor");
2940 sp<ThreadBase> thread = mThread.promote();
2941 if (thread != 0) {
2942 Mutex::Autolock _l(thread->mLock);
2943 mState = TERMINATED;
2944 }
2945}
2946
2947void AudioFlinger::PlaybackThread::Track::destroy()
2948{
2949 // NOTE: destroyTrack_l() can remove a strong reference to this Track
2950 // by removing it from mTracks vector, so there is a risk that this Tracks's
2951 // desctructor is called. As the destructor needs to lock mLock,
2952 // we must acquire a strong reference on this Track before locking mLock
2953 // here so that the destructor is called only when exiting this function.
2954 // On the other hand, as long as Track::destroy() is only called by
2955 // TrackHandle destructor, the TrackHandle still holds a strong ref on
2956 // this Track with its member mTrack.
2957 sp<Track> keep(this);
2958 { // scope for mLock
2959 sp<ThreadBase> thread = mThread.promote();
2960 if (thread != 0) {
2961 if (!isOutputTrack()) {
2962 if (mState == ACTIVE || mState == RESUMING) {
Eric Laurentde070132010-07-13 04:45:46 -07002963 AudioSystem::stopOutput(thread->id(),
2964 (AudioSystem::stream_type)mStreamType,
2965 mSessionId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07002966 }
2967 AudioSystem::releaseOutput(thread->id());
2968 }
2969 Mutex::Autolock _l(thread->mLock);
2970 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
2971 playbackThread->destroyTrack_l(this);
2972 }
2973 }
2974}
2975
2976void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
2977{
2978 snprintf(buffer, size, " %05d %05d %03u %03u %03u %05u %04u %1d %1d %1d %05u %05u %05u 0x%08x 0x%08x 0x%08x 0x%08x\n",
2979 mName - AudioMixer::TRACK0,
2980 (mClient == NULL) ? getpid() : mClient->pid(),
2981 mStreamType,
2982 mFormat,
2983 mCblk->channelCount,
2984 mSessionId,
2985 mFrameCount,
2986 mState,
2987 mMute,
2988 mFillingUpStatus,
2989 mCblk->sampleRate,
2990 mCblk->volume[0],
2991 mCblk->volume[1],
2992 mCblk->server,
2993 mCblk->user,
2994 (int)mMainBuffer,
2995 (int)mAuxBuffer);
2996}
2997
2998status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
2999{
3000 audio_track_cblk_t* cblk = this->cblk();
3001 uint32_t framesReady;
3002 uint32_t framesReq = buffer->frameCount;
3003
3004 // Check if last stepServer failed, try to step now
3005 if (mFlags & TrackBase::STEPSERVER_FAILED) {
3006 if (!step()) goto getNextBuffer_exit;
3007 LOGV("stepServer recovered");
3008 mFlags &= ~TrackBase::STEPSERVER_FAILED;
3009 }
3010
3011 framesReady = cblk->framesReady();
3012
3013 if (LIKELY(framesReady)) {
3014 uint32_t s = cblk->server;
3015 uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
3016
3017 bufferEnd = (cblk->loopEnd < bufferEnd) ? cblk->loopEnd : bufferEnd;
3018 if (framesReq > framesReady) {
3019 framesReq = framesReady;
3020 }
3021 if (s + framesReq > bufferEnd) {
3022 framesReq = bufferEnd - s;
3023 }
3024
3025 buffer->raw = getBuffer(s, framesReq);
3026 if (buffer->raw == 0) goto getNextBuffer_exit;
3027
3028 buffer->frameCount = framesReq;
3029 return NO_ERROR;
3030 }
3031
3032getNextBuffer_exit:
3033 buffer->raw = 0;
3034 buffer->frameCount = 0;
3035 LOGV("getNextBuffer() no more data for track %d on thread %p", mName, mThread.unsafe_get());
3036 return NOT_ENOUGH_DATA;
3037}
3038
3039bool AudioFlinger::PlaybackThread::Track::isReady() const {
3040 if (mFillingUpStatus != FS_FILLING) return true;
3041
3042 if (mCblk->framesReady() >= mCblk->frameCount ||
3043 (mCblk->flags & CBLK_FORCEREADY_MSK)) {
3044 mFillingUpStatus = FS_FILLED;
3045 mCblk->flags &= ~CBLK_FORCEREADY_MSK;
3046 return true;
3047 }
3048 return false;
3049}
3050
3051status_t AudioFlinger::PlaybackThread::Track::start()
3052{
3053 status_t status = NO_ERROR;
Eric Laurentf997cab2010-07-19 06:24:46 -07003054 LOGV("start(%d), calling thread %d session %d",
3055 mName, IPCThreadState::self()->getCallingPid(), mSessionId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07003056 sp<ThreadBase> thread = mThread.promote();
3057 if (thread != 0) {
3058 Mutex::Autolock _l(thread->mLock);
3059 int state = mState;
3060 // here the track could be either new, or restarted
3061 // in both cases "unstop" the track
3062 if (mState == PAUSED) {
3063 mState = TrackBase::RESUMING;
3064 LOGV("PAUSED => RESUMING (%d) on thread %p", mName, this);
3065 } else {
3066 mState = TrackBase::ACTIVE;
3067 LOGV("? => ACTIVE (%d) on thread %p", mName, this);
3068 }
3069
3070 if (!isOutputTrack() && state != ACTIVE && state != RESUMING) {
3071 thread->mLock.unlock();
Eric Laurentde070132010-07-13 04:45:46 -07003072 status = AudioSystem::startOutput(thread->id(),
3073 (AudioSystem::stream_type)mStreamType,
3074 mSessionId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07003075 thread->mLock.lock();
3076 }
3077 if (status == NO_ERROR) {
3078 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
3079 playbackThread->addTrack_l(this);
3080 } else {
3081 mState = state;
3082 }
3083 } else {
3084 status = BAD_VALUE;
3085 }
3086 return status;
3087}
3088
3089void AudioFlinger::PlaybackThread::Track::stop()
3090{
3091 LOGV("stop(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
3092 sp<ThreadBase> thread = mThread.promote();
3093 if (thread != 0) {
3094 Mutex::Autolock _l(thread->mLock);
3095 int state = mState;
3096 if (mState > STOPPED) {
3097 mState = STOPPED;
3098 // If the track is not active (PAUSED and buffers full), flush buffers
3099 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
3100 if (playbackThread->mActiveTracks.indexOf(this) < 0) {
3101 reset();
3102 }
3103 LOGV("(> STOPPED) => STOPPED (%d) on thread %p", mName, playbackThread);
3104 }
3105 if (!isOutputTrack() && (state == ACTIVE || state == RESUMING)) {
3106 thread->mLock.unlock();
Eric Laurentde070132010-07-13 04:45:46 -07003107 AudioSystem::stopOutput(thread->id(),
3108 (AudioSystem::stream_type)mStreamType,
3109 mSessionId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07003110 thread->mLock.lock();
3111 }
3112 }
3113}
3114
3115void AudioFlinger::PlaybackThread::Track::pause()
3116{
3117 LOGV("pause(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
3118 sp<ThreadBase> thread = mThread.promote();
3119 if (thread != 0) {
3120 Mutex::Autolock _l(thread->mLock);
3121 if (mState == ACTIVE || mState == RESUMING) {
3122 mState = PAUSING;
3123 LOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
3124 if (!isOutputTrack()) {
3125 thread->mLock.unlock();
Eric Laurentde070132010-07-13 04:45:46 -07003126 AudioSystem::stopOutput(thread->id(),
3127 (AudioSystem::stream_type)mStreamType,
3128 mSessionId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07003129 thread->mLock.lock();
3130 }
3131 }
3132 }
3133}
3134
3135void AudioFlinger::PlaybackThread::Track::flush()
3136{
3137 LOGV("flush(%d)", mName);
3138 sp<ThreadBase> thread = mThread.promote();
3139 if (thread != 0) {
3140 Mutex::Autolock _l(thread->mLock);
3141 if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
3142 return;
3143 }
3144 // No point remaining in PAUSED state after a flush => go to
3145 // STOPPED state
3146 mState = STOPPED;
3147
3148 mCblk->lock.lock();
3149 // NOTE: reset() will reset cblk->user and cblk->server with
3150 // the risk that at the same time, the AudioMixer is trying to read
3151 // data. In this case, getNextBuffer() would return a NULL pointer
3152 // as audio buffer => the AudioMixer code MUST always test that pointer
3153 // returned by getNextBuffer() is not NULL!
3154 reset();
3155 mCblk->lock.unlock();
3156 }
3157}
3158
3159void AudioFlinger::PlaybackThread::Track::reset()
3160{
3161 // Do not reset twice to avoid discarding data written just after a flush and before
3162 // the audioflinger thread detects the track is stopped.
3163 if (!mResetDone) {
3164 TrackBase::reset();
3165 // Force underrun condition to avoid false underrun callback until first data is
3166 // written to buffer
3167 mCblk->flags |= CBLK_UNDERRUN_ON;
3168 mCblk->flags &= ~CBLK_FORCEREADY_MSK;
3169 mFillingUpStatus = FS_FILLING;
3170 mResetDone = true;
3171 }
3172}
3173
3174void AudioFlinger::PlaybackThread::Track::mute(bool muted)
3175{
3176 mMute = muted;
3177}
3178
3179void AudioFlinger::PlaybackThread::Track::setVolume(float left, float right)
3180{
3181 mVolume[0] = left;
3182 mVolume[1] = right;
3183}
3184
3185status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
3186{
3187 status_t status = DEAD_OBJECT;
3188 sp<ThreadBase> thread = mThread.promote();
3189 if (thread != 0) {
3190 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
3191 status = playbackThread->attachAuxEffect(this, EffectId);
3192 }
3193 return status;
3194}
3195
3196void AudioFlinger::PlaybackThread::Track::setAuxBuffer(int EffectId, int32_t *buffer)
3197{
3198 mAuxEffectId = EffectId;
3199 mAuxBuffer = buffer;
3200}
3201
3202// ----------------------------------------------------------------------------
3203
3204// RecordTrack constructor must be called with AudioFlinger::mLock held
3205AudioFlinger::RecordThread::RecordTrack::RecordTrack(
3206 const wp<ThreadBase>& thread,
3207 const sp<Client>& client,
3208 uint32_t sampleRate,
3209 int format,
3210 int channelCount,
3211 int frameCount,
3212 uint32_t flags,
3213 int sessionId)
3214 : TrackBase(thread, client, sampleRate, format,
3215 channelCount, frameCount, flags, 0, sessionId),
3216 mOverflow(false)
3217{
3218 if (mCblk != NULL) {
3219 LOGV("RecordTrack constructor, size %d", (int)mBufferEnd - (int)mBuffer);
3220 if (format == AudioSystem::PCM_16_BIT) {
3221 mCblk->frameSize = channelCount * sizeof(int16_t);
3222 } else if (format == AudioSystem::PCM_8_BIT) {
3223 mCblk->frameSize = channelCount * sizeof(int8_t);
3224 } else {
3225 mCblk->frameSize = sizeof(int8_t);
3226 }
3227 }
3228}
3229
3230AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
3231{
3232 sp<ThreadBase> thread = mThread.promote();
3233 if (thread != 0) {
3234 AudioSystem::releaseInput(thread->id());
3235 }
3236}
3237
3238status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
3239{
3240 audio_track_cblk_t* cblk = this->cblk();
3241 uint32_t framesAvail;
3242 uint32_t framesReq = buffer->frameCount;
3243
3244 // Check if last stepServer failed, try to step now
3245 if (mFlags & TrackBase::STEPSERVER_FAILED) {
3246 if (!step()) goto getNextBuffer_exit;
3247 LOGV("stepServer recovered");
3248 mFlags &= ~TrackBase::STEPSERVER_FAILED;
3249 }
3250
3251 framesAvail = cblk->framesAvailable_l();
3252
3253 if (LIKELY(framesAvail)) {
3254 uint32_t s = cblk->server;
3255 uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
3256
3257 if (framesReq > framesAvail) {
3258 framesReq = framesAvail;
3259 }
3260 if (s + framesReq > bufferEnd) {
3261 framesReq = bufferEnd - s;
3262 }
3263
3264 buffer->raw = getBuffer(s, framesReq);
3265 if (buffer->raw == 0) goto getNextBuffer_exit;
3266
3267 buffer->frameCount = framesReq;
3268 return NO_ERROR;
3269 }
3270
3271getNextBuffer_exit:
3272 buffer->raw = 0;
3273 buffer->frameCount = 0;
3274 return NOT_ENOUGH_DATA;
3275}
3276
3277status_t AudioFlinger::RecordThread::RecordTrack::start()
3278{
3279 sp<ThreadBase> thread = mThread.promote();
3280 if (thread != 0) {
3281 RecordThread *recordThread = (RecordThread *)thread.get();
3282 return recordThread->start(this);
3283 } else {
3284 return BAD_VALUE;
3285 }
3286}
3287
3288void AudioFlinger::RecordThread::RecordTrack::stop()
3289{
3290 sp<ThreadBase> thread = mThread.promote();
3291 if (thread != 0) {
3292 RecordThread *recordThread = (RecordThread *)thread.get();
3293 recordThread->stop(this);
3294 TrackBase::reset();
3295 // Force overerrun condition to avoid false overrun callback until first data is
3296 // read from buffer
3297 mCblk->flags |= CBLK_UNDERRUN_ON;
3298 }
3299}
3300
3301void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
3302{
3303 snprintf(buffer, size, " %05d %03u %03u %05d %04u %01d %05u %08x %08x\n",
3304 (mClient == NULL) ? getpid() : mClient->pid(),
3305 mFormat,
3306 mCblk->channelCount,
3307 mSessionId,
3308 mFrameCount,
3309 mState,
3310 mCblk->sampleRate,
3311 mCblk->server,
3312 mCblk->user);
3313}
3314
3315
3316// ----------------------------------------------------------------------------
3317
3318AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
3319 const wp<ThreadBase>& thread,
3320 DuplicatingThread *sourceThread,
3321 uint32_t sampleRate,
3322 int format,
3323 int channelCount,
3324 int frameCount)
3325 : Track(thread, NULL, AudioSystem::NUM_STREAM_TYPES, sampleRate, format, channelCount, frameCount, NULL, 0),
3326 mActive(false), mSourceThread(sourceThread)
3327{
3328
3329 PlaybackThread *playbackThread = (PlaybackThread *)thread.unsafe_get();
3330 if (mCblk != NULL) {
3331 mCblk->flags |= CBLK_DIRECTION_OUT;
3332 mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
3333 mCblk->volume[0] = mCblk->volume[1] = 0x1000;
3334 mOutBuffer.frameCount = 0;
3335 playbackThread->mTracks.add(this);
3336 LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channelCount %d mBufferEnd %p",
3337 mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channelCount, mBufferEnd);
3338 } else {
3339 LOGW("Error creating output track on thread %p", playbackThread);
3340 }
3341}
3342
3343AudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
3344{
3345 clearBufferQueue();
3346}
3347
3348status_t AudioFlinger::PlaybackThread::OutputTrack::start()
3349{
3350 status_t status = Track::start();
3351 if (status != NO_ERROR) {
3352 return status;
3353 }
3354
3355 mActive = true;
3356 mRetryCount = 127;
3357 return status;
3358}
3359
3360void AudioFlinger::PlaybackThread::OutputTrack::stop()
3361{
3362 Track::stop();
3363 clearBufferQueue();
3364 mOutBuffer.frameCount = 0;
3365 mActive = false;
3366}
3367
3368bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t frames)
3369{
3370 Buffer *pInBuffer;
3371 Buffer inBuffer;
3372 uint32_t channelCount = mCblk->channelCount;
3373 bool outputBufferFull = false;
3374 inBuffer.frameCount = frames;
3375 inBuffer.i16 = data;
3376
3377 uint32_t waitTimeLeftMs = mSourceThread->waitTimeMs();
3378
3379 if (!mActive && frames != 0) {
3380 start();
3381 sp<ThreadBase> thread = mThread.promote();
3382 if (thread != 0) {
3383 MixerThread *mixerThread = (MixerThread *)thread.get();
3384 if (mCblk->frameCount > frames){
3385 if (mBufferQueue.size() < kMaxOverFlowBuffers) {
3386 uint32_t startFrames = (mCblk->frameCount - frames);
3387 pInBuffer = new Buffer;
3388 pInBuffer->mBuffer = new int16_t[startFrames * channelCount];
3389 pInBuffer->frameCount = startFrames;
3390 pInBuffer->i16 = pInBuffer->mBuffer;
3391 memset(pInBuffer->raw, 0, startFrames * channelCount * sizeof(int16_t));
3392 mBufferQueue.add(pInBuffer);
3393 } else {
3394 LOGW ("OutputTrack::write() %p no more buffers in queue", this);
3395 }
3396 }
3397 }
3398 }
3399
3400 while (waitTimeLeftMs) {
3401 // First write pending buffers, then new data
3402 if (mBufferQueue.size()) {
3403 pInBuffer = mBufferQueue.itemAt(0);
3404 } else {
3405 pInBuffer = &inBuffer;
3406 }
3407
3408 if (pInBuffer->frameCount == 0) {
3409 break;
3410 }
3411
3412 if (mOutBuffer.frameCount == 0) {
3413 mOutBuffer.frameCount = pInBuffer->frameCount;
3414 nsecs_t startTime = systemTime();
3415 if (obtainBuffer(&mOutBuffer, waitTimeLeftMs) == (status_t)AudioTrack::NO_MORE_BUFFERS) {
3416 LOGV ("OutputTrack::write() %p thread %p no more output buffers", this, mThread.unsafe_get());
3417 outputBufferFull = true;
3418 break;
3419 }
3420 uint32_t waitTimeMs = (uint32_t)ns2ms(systemTime() - startTime);
3421 if (waitTimeLeftMs >= waitTimeMs) {
3422 waitTimeLeftMs -= waitTimeMs;
3423 } else {
3424 waitTimeLeftMs = 0;
3425 }
3426 }
3427
3428 uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : pInBuffer->frameCount;
3429 memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channelCount * sizeof(int16_t));
3430 mCblk->stepUser(outFrames);
3431 pInBuffer->frameCount -= outFrames;
3432 pInBuffer->i16 += outFrames * channelCount;
3433 mOutBuffer.frameCount -= outFrames;
3434 mOutBuffer.i16 += outFrames * channelCount;
3435
3436 if (pInBuffer->frameCount == 0) {
3437 if (mBufferQueue.size()) {
3438 mBufferQueue.removeAt(0);
3439 delete [] pInBuffer->mBuffer;
3440 delete pInBuffer;
3441 LOGV("OutputTrack::write() %p thread %p released overflow buffer %d", this, mThread.unsafe_get(), mBufferQueue.size());
3442 } else {
3443 break;
3444 }
3445 }
3446 }
3447
3448 // If we could not write all frames, allocate a buffer and queue it for next time.
3449 if (inBuffer.frameCount) {
3450 sp<ThreadBase> thread = mThread.promote();
3451 if (thread != 0 && !thread->standby()) {
3452 if (mBufferQueue.size() < kMaxOverFlowBuffers) {
3453 pInBuffer = new Buffer;
3454 pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channelCount];
3455 pInBuffer->frameCount = inBuffer.frameCount;
3456 pInBuffer->i16 = pInBuffer->mBuffer;
3457 memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channelCount * sizeof(int16_t));
3458 mBufferQueue.add(pInBuffer);
3459 LOGV("OutputTrack::write() %p thread %p adding overflow buffer %d", this, mThread.unsafe_get(), mBufferQueue.size());
3460 } else {
3461 LOGW("OutputTrack::write() %p thread %p no more overflow buffers", mThread.unsafe_get(), this);
3462 }
3463 }
3464 }
3465
3466 // Calling write() with a 0 length buffer, means that no more data will be written:
3467 // If no more buffers are pending, fill output track buffer to make sure it is started
3468 // by output mixer.
3469 if (frames == 0 && mBufferQueue.size() == 0) {
3470 if (mCblk->user < mCblk->frameCount) {
3471 frames = mCblk->frameCount - mCblk->user;
3472 pInBuffer = new Buffer;
3473 pInBuffer->mBuffer = new int16_t[frames * channelCount];
3474 pInBuffer->frameCount = frames;
3475 pInBuffer->i16 = pInBuffer->mBuffer;
3476 memset(pInBuffer->raw, 0, frames * channelCount * sizeof(int16_t));
3477 mBufferQueue.add(pInBuffer);
3478 } else if (mActive) {
3479 stop();
3480 }
3481 }
3482
3483 return outputBufferFull;
3484}
3485
3486status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
3487{
3488 int active;
3489 status_t result;
3490 audio_track_cblk_t* cblk = mCblk;
3491 uint32_t framesReq = buffer->frameCount;
3492
3493// LOGV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
3494 buffer->frameCount = 0;
3495
3496 uint32_t framesAvail = cblk->framesAvailable();
3497
3498
3499 if (framesAvail == 0) {
3500 Mutex::Autolock _l(cblk->lock);
3501 goto start_loop_here;
3502 while (framesAvail == 0) {
3503 active = mActive;
3504 if (UNLIKELY(!active)) {
3505 LOGV("Not active and NO_MORE_BUFFERS");
3506 return AudioTrack::NO_MORE_BUFFERS;
3507 }
3508 result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
3509 if (result != NO_ERROR) {
3510 return AudioTrack::NO_MORE_BUFFERS;
3511 }
3512 // read the server count again
3513 start_loop_here:
3514 framesAvail = cblk->framesAvailable_l();
3515 }
3516 }
3517
3518// if (framesAvail < framesReq) {
3519// return AudioTrack::NO_MORE_BUFFERS;
3520// }
3521
3522 if (framesReq > framesAvail) {
3523 framesReq = framesAvail;
3524 }
3525
3526 uint32_t u = cblk->user;
3527 uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
3528
3529 if (u + framesReq > bufferEnd) {
3530 framesReq = bufferEnd - u;
3531 }
3532
3533 buffer->frameCount = framesReq;
3534 buffer->raw = (void *)cblk->buffer(u);
3535 return NO_ERROR;
3536}
3537
3538
3539void AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
3540{
3541 size_t size = mBufferQueue.size();
3542 Buffer *pBuffer;
3543
3544 for (size_t i = 0; i < size; i++) {
3545 pBuffer = mBufferQueue.itemAt(i);
3546 delete [] pBuffer->mBuffer;
3547 delete pBuffer;
3548 }
3549 mBufferQueue.clear();
3550}
3551
3552// ----------------------------------------------------------------------------
3553
3554AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
3555 : RefBase(),
3556 mAudioFlinger(audioFlinger),
3557 mMemoryDealer(new MemoryDealer(1024*1024, "AudioFlinger::Client")),
3558 mPid(pid)
3559{
3560 // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
3561}
3562
3563// Client destructor must be called with AudioFlinger::mLock held
3564AudioFlinger::Client::~Client()
3565{
3566 mAudioFlinger->removeClient_l(mPid);
3567}
3568
3569const sp<MemoryDealer>& AudioFlinger::Client::heap() const
3570{
3571 return mMemoryDealer;
3572}
3573
3574// ----------------------------------------------------------------------------
3575
3576AudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
3577 const sp<IAudioFlingerClient>& client,
3578 pid_t pid)
3579 : mAudioFlinger(audioFlinger), mPid(pid), mClient(client)
3580{
3581}
3582
3583AudioFlinger::NotificationClient::~NotificationClient()
3584{
3585 mClient.clear();
3586}
3587
3588void AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who)
3589{
3590 sp<NotificationClient> keep(this);
3591 {
3592 mAudioFlinger->removeNotificationClient(mPid);
3593 }
3594}
3595
3596// ----------------------------------------------------------------------------
3597
3598AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
3599 : BnAudioTrack(),
3600 mTrack(track)
3601{
3602}
3603
3604AudioFlinger::TrackHandle::~TrackHandle() {
3605 // just stop the track on deletion, associated resources
3606 // will be freed from the main thread once all pending buffers have
3607 // been played. Unless it's not in the active track list, in which
3608 // case we free everything now...
3609 mTrack->destroy();
3610}
3611
3612status_t AudioFlinger::TrackHandle::start() {
3613 return mTrack->start();
3614}
3615
3616void AudioFlinger::TrackHandle::stop() {
3617 mTrack->stop();
3618}
3619
3620void AudioFlinger::TrackHandle::flush() {
3621 mTrack->flush();
3622}
3623
3624void AudioFlinger::TrackHandle::mute(bool e) {
3625 mTrack->mute(e);
3626}
3627
3628void AudioFlinger::TrackHandle::pause() {
3629 mTrack->pause();
3630}
3631
3632void AudioFlinger::TrackHandle::setVolume(float left, float right) {
3633 mTrack->setVolume(left, right);
3634}
3635
3636sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
3637 return mTrack->getCblk();
3638}
3639
3640status_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId)
3641{
3642 return mTrack->attachAuxEffect(EffectId);
3643}
3644
3645status_t AudioFlinger::TrackHandle::onTransact(
3646 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
3647{
3648 return BnAudioTrack::onTransact(code, data, reply, flags);
3649}
3650
3651// ----------------------------------------------------------------------------
3652
3653sp<IAudioRecord> AudioFlinger::openRecord(
3654 pid_t pid,
3655 int input,
3656 uint32_t sampleRate,
3657 int format,
3658 int channelCount,
3659 int frameCount,
3660 uint32_t flags,
3661 int *sessionId,
3662 status_t *status)
3663{
3664 sp<RecordThread::RecordTrack> recordTrack;
3665 sp<RecordHandle> recordHandle;
3666 sp<Client> client;
3667 wp<Client> wclient;
3668 status_t lStatus;
3669 RecordThread *thread;
3670 size_t inFrameCount;
3671 int lSessionId;
3672
3673 // check calling permissions
3674 if (!recordingAllowed()) {
3675 lStatus = PERMISSION_DENIED;
3676 goto Exit;
3677 }
3678
3679 // add client to list
3680 { // scope for mLock
3681 Mutex::Autolock _l(mLock);
3682 thread = checkRecordThread_l(input);
3683 if (thread == NULL) {
3684 lStatus = BAD_VALUE;
3685 goto Exit;
3686 }
3687
3688 wclient = mClients.valueFor(pid);
3689 if (wclient != NULL) {
3690 client = wclient.promote();
3691 } else {
3692 client = new Client(this, pid);
3693 mClients.add(pid, client);
3694 }
3695
3696 // If no audio session id is provided, create one here
Eric Laurentde070132010-07-13 04:45:46 -07003697 if (sessionId != NULL && *sessionId != AudioSystem::SESSION_OUTPUT_MIX) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07003698 lSessionId = *sessionId;
3699 } else {
3700 lSessionId = nextUniqueId();
3701 if (sessionId != NULL) {
3702 *sessionId = lSessionId;
3703 }
3704 }
3705 // create new record track. The record track uses one track in mHardwareMixerThread by convention.
3706 recordTrack = new RecordThread::RecordTrack(thread, client, sampleRate,
3707 format, channelCount, frameCount, flags, lSessionId);
3708 }
3709 if (recordTrack->getCblk() == NULL) {
3710 // remove local strong reference to Client before deleting the RecordTrack so that the Client
3711 // destructor is called by the TrackBase destructor with mLock held
3712 client.clear();
3713 recordTrack.clear();
3714 lStatus = NO_MEMORY;
3715 goto Exit;
3716 }
3717
3718 // return to handle to client
3719 recordHandle = new RecordHandle(recordTrack);
3720 lStatus = NO_ERROR;
3721
3722Exit:
3723 if (status) {
3724 *status = lStatus;
3725 }
3726 return recordHandle;
3727}
3728
3729// ----------------------------------------------------------------------------
3730
3731AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
3732 : BnAudioRecord(),
3733 mRecordTrack(recordTrack)
3734{
3735}
3736
3737AudioFlinger::RecordHandle::~RecordHandle() {
3738 stop();
3739}
3740
3741status_t AudioFlinger::RecordHandle::start() {
3742 LOGV("RecordHandle::start()");
3743 return mRecordTrack->start();
3744}
3745
3746void AudioFlinger::RecordHandle::stop() {
3747 LOGV("RecordHandle::stop()");
3748 mRecordTrack->stop();
3749}
3750
3751sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
3752 return mRecordTrack->getCblk();
3753}
3754
3755status_t AudioFlinger::RecordHandle::onTransact(
3756 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
3757{
3758 return BnAudioRecord::onTransact(code, data, reply, flags);
3759}
3760
3761// ----------------------------------------------------------------------------
3762
3763AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioStreamIn *input, uint32_t sampleRate, uint32_t channels, int id) :
3764 ThreadBase(audioFlinger, id),
3765 mInput(input), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0)
3766{
3767 mReqChannelCount = AudioSystem::popCount(channels);
3768 mReqSampleRate = sampleRate;
3769 readInputParameters();
3770}
3771
3772
3773AudioFlinger::RecordThread::~RecordThread()
3774{
3775 delete[] mRsmpInBuffer;
3776 if (mResampler != 0) {
3777 delete mResampler;
3778 delete[] mRsmpOutBuffer;
3779 }
3780}
3781
3782void AudioFlinger::RecordThread::onFirstRef()
3783{
3784 const size_t SIZE = 256;
3785 char buffer[SIZE];
3786
3787 snprintf(buffer, SIZE, "Record Thread %p", this);
3788
3789 run(buffer, PRIORITY_URGENT_AUDIO);
3790}
3791
3792bool AudioFlinger::RecordThread::threadLoop()
3793{
3794 AudioBufferProvider::Buffer buffer;
3795 sp<RecordTrack> activeTrack;
3796
3797 // start recording
3798 while (!exitPending()) {
3799
3800 processConfigEvents();
3801
3802 { // scope for mLock
3803 Mutex::Autolock _l(mLock);
3804 checkForNewParameters_l();
3805 if (mActiveTrack == 0 && mConfigEvents.isEmpty()) {
3806 if (!mStandby) {
3807 mInput->standby();
3808 mStandby = true;
3809 }
3810
3811 if (exitPending()) break;
3812
3813 LOGV("RecordThread: loop stopping");
3814 // go to sleep
3815 mWaitWorkCV.wait(mLock);
3816 LOGV("RecordThread: loop starting");
3817 continue;
3818 }
3819 if (mActiveTrack != 0) {
3820 if (mActiveTrack->mState == TrackBase::PAUSING) {
3821 if (!mStandby) {
3822 mInput->standby();
3823 mStandby = true;
3824 }
3825 mActiveTrack.clear();
3826 mStartStopCond.broadcast();
3827 } else if (mActiveTrack->mState == TrackBase::RESUMING) {
3828 if (mReqChannelCount != mActiveTrack->channelCount()) {
3829 mActiveTrack.clear();
3830 mStartStopCond.broadcast();
3831 } else if (mBytesRead != 0) {
3832 // record start succeeds only if first read from audio input
3833 // succeeds
3834 if (mBytesRead > 0) {
3835 mActiveTrack->mState = TrackBase::ACTIVE;
3836 } else {
3837 mActiveTrack.clear();
3838 }
3839 mStartStopCond.broadcast();
3840 }
3841 mStandby = false;
3842 }
3843 }
3844 }
3845
3846 if (mActiveTrack != 0) {
3847 if (mActiveTrack->mState != TrackBase::ACTIVE &&
3848 mActiveTrack->mState != TrackBase::RESUMING) {
3849 usleep(5000);
3850 continue;
3851 }
3852 buffer.frameCount = mFrameCount;
3853 if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
3854 size_t framesOut = buffer.frameCount;
3855 if (mResampler == 0) {
3856 // no resampling
3857 while (framesOut) {
3858 size_t framesIn = mFrameCount - mRsmpInIndex;
3859 if (framesIn) {
3860 int8_t *src = (int8_t *)mRsmpInBuffer + mRsmpInIndex * mFrameSize;
3861 int8_t *dst = buffer.i8 + (buffer.frameCount - framesOut) * mActiveTrack->mCblk->frameSize;
3862 if (framesIn > framesOut)
3863 framesIn = framesOut;
3864 mRsmpInIndex += framesIn;
3865 framesOut -= framesIn;
3866 if ((int)mChannelCount == mReqChannelCount ||
3867 mFormat != AudioSystem::PCM_16_BIT) {
3868 memcpy(dst, src, framesIn * mFrameSize);
3869 } else {
3870 int16_t *src16 = (int16_t *)src;
3871 int16_t *dst16 = (int16_t *)dst;
3872 if (mChannelCount == 1) {
3873 while (framesIn--) {
3874 *dst16++ = *src16;
3875 *dst16++ = *src16++;
3876 }
3877 } else {
3878 while (framesIn--) {
3879 *dst16++ = (int16_t)(((int32_t)*src16 + (int32_t)*(src16 + 1)) >> 1);
3880 src16 += 2;
3881 }
3882 }
3883 }
3884 }
3885 if (framesOut && mFrameCount == mRsmpInIndex) {
3886 if (framesOut == mFrameCount &&
3887 ((int)mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) {
3888 mBytesRead = mInput->read(buffer.raw, mInputBytes);
3889 framesOut = 0;
3890 } else {
3891 mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
3892 mRsmpInIndex = 0;
3893 }
3894 if (mBytesRead < 0) {
3895 LOGE("Error reading audio input");
3896 if (mActiveTrack->mState == TrackBase::ACTIVE) {
3897 // Force input into standby so that it tries to
3898 // recover at next read attempt
3899 mInput->standby();
3900 usleep(5000);
3901 }
3902 mRsmpInIndex = mFrameCount;
3903 framesOut = 0;
3904 buffer.frameCount = 0;
3905 }
3906 }
3907 }
3908 } else {
3909 // resampling
3910
3911 memset(mRsmpOutBuffer, 0, framesOut * 2 * sizeof(int32_t));
3912 // alter output frame count as if we were expecting stereo samples
3913 if (mChannelCount == 1 && mReqChannelCount == 1) {
3914 framesOut >>= 1;
3915 }
3916 mResampler->resample(mRsmpOutBuffer, framesOut, this);
3917 // ditherAndClamp() works as long as all buffers returned by mActiveTrack->getNextBuffer()
3918 // are 32 bit aligned which should be always true.
3919 if (mChannelCount == 2 && mReqChannelCount == 1) {
3920 AudioMixer::ditherAndClamp(mRsmpOutBuffer, mRsmpOutBuffer, framesOut);
3921 // the resampler always outputs stereo samples: do post stereo to mono conversion
3922 int16_t *src = (int16_t *)mRsmpOutBuffer;
3923 int16_t *dst = buffer.i16;
3924 while (framesOut--) {
3925 *dst++ = (int16_t)(((int32_t)*src + (int32_t)*(src + 1)) >> 1);
3926 src += 2;
3927 }
3928 } else {
3929 AudioMixer::ditherAndClamp((int32_t *)buffer.raw, mRsmpOutBuffer, framesOut);
3930 }
3931
3932 }
3933 mActiveTrack->releaseBuffer(&buffer);
3934 mActiveTrack->overflow();
3935 }
3936 // client isn't retrieving buffers fast enough
3937 else {
3938 if (!mActiveTrack->setOverflow())
3939 LOGW("RecordThread: buffer overflow");
3940 // Release the processor for a while before asking for a new buffer.
3941 // This will give the application more chance to read from the buffer and
3942 // clear the overflow.
3943 usleep(5000);
3944 }
3945 }
3946 }
3947
3948 if (!mStandby) {
3949 mInput->standby();
3950 }
3951 mActiveTrack.clear();
3952
3953 mStartStopCond.broadcast();
3954
3955 LOGV("RecordThread %p exiting", this);
3956 return false;
3957}
3958
3959status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack)
3960{
3961 LOGV("RecordThread::start");
3962 sp <ThreadBase> strongMe = this;
3963 status_t status = NO_ERROR;
3964 {
3965 AutoMutex lock(&mLock);
3966 if (mActiveTrack != 0) {
3967 if (recordTrack != mActiveTrack.get()) {
3968 status = -EBUSY;
3969 } else if (mActiveTrack->mState == TrackBase::PAUSING) {
3970 mActiveTrack->mState = TrackBase::ACTIVE;
3971 }
3972 return status;
3973 }
3974
3975 recordTrack->mState = TrackBase::IDLE;
3976 mActiveTrack = recordTrack;
3977 mLock.unlock();
3978 status_t status = AudioSystem::startInput(mId);
3979 mLock.lock();
3980 if (status != NO_ERROR) {
3981 mActiveTrack.clear();
3982 return status;
3983 }
3984 mActiveTrack->mState = TrackBase::RESUMING;
3985 mRsmpInIndex = mFrameCount;
3986 mBytesRead = 0;
3987 // signal thread to start
3988 LOGV("Signal record thread");
3989 mWaitWorkCV.signal();
3990 // do not wait for mStartStopCond if exiting
3991 if (mExiting) {
3992 mActiveTrack.clear();
3993 status = INVALID_OPERATION;
3994 goto startError;
3995 }
3996 mStartStopCond.wait(mLock);
3997 if (mActiveTrack == 0) {
3998 LOGV("Record failed to start");
3999 status = BAD_VALUE;
4000 goto startError;
4001 }
4002 LOGV("Record started OK");
4003 return status;
4004 }
4005startError:
4006 AudioSystem::stopInput(mId);
4007 return status;
4008}
4009
4010void AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
4011 LOGV("RecordThread::stop");
4012 sp <ThreadBase> strongMe = this;
4013 {
4014 AutoMutex lock(&mLock);
4015 if (mActiveTrack != 0 && recordTrack == mActiveTrack.get()) {
4016 mActiveTrack->mState = TrackBase::PAUSING;
4017 // do not wait for mStartStopCond if exiting
4018 if (mExiting) {
4019 return;
4020 }
4021 mStartStopCond.wait(mLock);
4022 // if we have been restarted, recordTrack == mActiveTrack.get() here
4023 if (mActiveTrack == 0 || recordTrack != mActiveTrack.get()) {
4024 mLock.unlock();
4025 AudioSystem::stopInput(mId);
4026 mLock.lock();
4027 LOGV("Record stopped OK");
4028 }
4029 }
4030 }
4031}
4032
4033status_t AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args)
4034{
4035 const size_t SIZE = 256;
4036 char buffer[SIZE];
4037 String8 result;
4038 pid_t pid = 0;
4039
4040 snprintf(buffer, SIZE, "\nInput thread %p internals\n", this);
4041 result.append(buffer);
4042
4043 if (mActiveTrack != 0) {
4044 result.append("Active Track:\n");
4045 result.append(" Clien Fmt Chn Session Buf S SRate Serv User\n");
4046 mActiveTrack->dump(buffer, SIZE);
4047 result.append(buffer);
4048
4049 snprintf(buffer, SIZE, "In index: %d\n", mRsmpInIndex);
4050 result.append(buffer);
4051 snprintf(buffer, SIZE, "In size: %d\n", mInputBytes);
4052 result.append(buffer);
4053 snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != 0));
4054 result.append(buffer);
4055 snprintf(buffer, SIZE, "Out channel count: %d\n", mReqChannelCount);
4056 result.append(buffer);
4057 snprintf(buffer, SIZE, "Out sample rate: %d\n", mReqSampleRate);
4058 result.append(buffer);
4059
4060
4061 } else {
4062 result.append("No record client\n");
4063 }
4064 write(fd, result.string(), result.size());
4065
4066 dumpBase(fd, args);
4067
4068 return NO_ERROR;
4069}
4070
4071status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer* buffer)
4072{
4073 size_t framesReq = buffer->frameCount;
4074 size_t framesReady = mFrameCount - mRsmpInIndex;
4075 int channelCount;
4076
4077 if (framesReady == 0) {
4078 mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
4079 if (mBytesRead < 0) {
4080 LOGE("RecordThread::getNextBuffer() Error reading audio input");
4081 if (mActiveTrack->mState == TrackBase::ACTIVE) {
4082 // Force input into standby so that it tries to
4083 // recover at next read attempt
4084 mInput->standby();
4085 usleep(5000);
4086 }
4087 buffer->raw = 0;
4088 buffer->frameCount = 0;
4089 return NOT_ENOUGH_DATA;
4090 }
4091 mRsmpInIndex = 0;
4092 framesReady = mFrameCount;
4093 }
4094
4095 if (framesReq > framesReady) {
4096 framesReq = framesReady;
4097 }
4098
4099 if (mChannelCount == 1 && mReqChannelCount == 2) {
4100 channelCount = 1;
4101 } else {
4102 channelCount = 2;
4103 }
4104 buffer->raw = mRsmpInBuffer + mRsmpInIndex * channelCount;
4105 buffer->frameCount = framesReq;
4106 return NO_ERROR;
4107}
4108
4109void AudioFlinger::RecordThread::releaseBuffer(AudioBufferProvider::Buffer* buffer)
4110{
4111 mRsmpInIndex += buffer->frameCount;
4112 buffer->frameCount = 0;
4113}
4114
4115bool AudioFlinger::RecordThread::checkForNewParameters_l()
4116{
4117 bool reconfig = false;
4118
4119 while (!mNewParameters.isEmpty()) {
4120 status_t status = NO_ERROR;
4121 String8 keyValuePair = mNewParameters[0];
4122 AudioParameter param = AudioParameter(keyValuePair);
4123 int value;
4124 int reqFormat = mFormat;
4125 int reqSamplingRate = mReqSampleRate;
4126 int reqChannelCount = mReqChannelCount;
4127
4128 if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
4129 reqSamplingRate = value;
4130 reconfig = true;
4131 }
4132 if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
4133 reqFormat = value;
4134 reconfig = true;
4135 }
4136 if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
4137 reqChannelCount = AudioSystem::popCount(value);
4138 reconfig = true;
4139 }
4140 if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
4141 // do not accept frame count changes if tracks are open as the track buffer
4142 // size depends on frame count and correct behavior would not be garantied
4143 // if frame count is changed after track creation
4144 if (mActiveTrack != 0) {
4145 status = INVALID_OPERATION;
4146 } else {
4147 reconfig = true;
4148 }
4149 }
4150 if (status == NO_ERROR) {
4151 status = mInput->setParameters(keyValuePair);
4152 if (status == INVALID_OPERATION) {
4153 mInput->standby();
4154 status = mInput->setParameters(keyValuePair);
4155 }
4156 if (reconfig) {
4157 if (status == BAD_VALUE &&
4158 reqFormat == mInput->format() && reqFormat == AudioSystem::PCM_16_BIT &&
4159 ((int)mInput->sampleRate() <= 2 * reqSamplingRate) &&
4160 (AudioSystem::popCount(mInput->channels()) < 3) && (reqChannelCount < 3)) {
4161 status = NO_ERROR;
4162 }
4163 if (status == NO_ERROR) {
4164 readInputParameters();
4165 sendConfigEvent_l(AudioSystem::INPUT_CONFIG_CHANGED);
4166 }
4167 }
4168 }
4169
4170 mNewParameters.removeAt(0);
4171
4172 mParamStatus = status;
4173 mParamCond.signal();
4174 mWaitWorkCV.wait(mLock);
4175 }
4176 return reconfig;
4177}
4178
4179String8 AudioFlinger::RecordThread::getParameters(const String8& keys)
4180{
4181 return mInput->getParameters(keys);
4182}
4183
4184void AudioFlinger::RecordThread::audioConfigChanged_l(int event, int param) {
4185 AudioSystem::OutputDescriptor desc;
4186 void *param2 = 0;
4187
4188 switch (event) {
4189 case AudioSystem::INPUT_OPENED:
4190 case AudioSystem::INPUT_CONFIG_CHANGED:
4191 desc.channels = mChannels;
4192 desc.samplingRate = mSampleRate;
4193 desc.format = mFormat;
4194 desc.frameCount = mFrameCount;
4195 desc.latency = 0;
4196 param2 = &desc;
4197 break;
4198
4199 case AudioSystem::INPUT_CLOSED:
4200 default:
4201 break;
4202 }
4203 mAudioFlinger->audioConfigChanged_l(event, mId, param2);
4204}
4205
4206void AudioFlinger::RecordThread::readInputParameters()
4207{
4208 if (mRsmpInBuffer) delete mRsmpInBuffer;
4209 if (mRsmpOutBuffer) delete mRsmpOutBuffer;
4210 if (mResampler) delete mResampler;
4211 mResampler = 0;
4212
4213 mSampleRate = mInput->sampleRate();
4214 mChannels = mInput->channels();
4215 mChannelCount = (uint16_t)AudioSystem::popCount(mChannels);
4216 mFormat = mInput->format();
4217 mFrameSize = (uint16_t)mInput->frameSize();
4218 mInputBytes = mInput->bufferSize();
4219 mFrameCount = mInputBytes / mFrameSize;
4220 mRsmpInBuffer = new int16_t[mFrameCount * mChannelCount];
4221
4222 if (mSampleRate != mReqSampleRate && mChannelCount < 3 && mReqChannelCount < 3)
4223 {
4224 int channelCount;
4225 // optmization: if mono to mono, use the resampler in stereo to stereo mode to avoid
4226 // stereo to mono post process as the resampler always outputs stereo.
4227 if (mChannelCount == 1 && mReqChannelCount == 2) {
4228 channelCount = 1;
4229 } else {
4230 channelCount = 2;
4231 }
4232 mResampler = AudioResampler::create(16, channelCount, mReqSampleRate);
4233 mResampler->setSampleRate(mSampleRate);
4234 mResampler->setVolume(AudioMixer::UNITY_GAIN, AudioMixer::UNITY_GAIN);
4235 mRsmpOutBuffer = new int32_t[mFrameCount * 2];
4236
4237 // optmization: if mono to mono, alter input frame count as if we were inputing stereo samples
4238 if (mChannelCount == 1 && mReqChannelCount == 1) {
4239 mFrameCount >>= 1;
4240 }
4241
4242 }
4243 mRsmpInIndex = mFrameCount;
4244}
4245
4246unsigned int AudioFlinger::RecordThread::getInputFramesLost()
4247{
4248 return mInput->getInputFramesLost();
4249}
4250
4251// ----------------------------------------------------------------------------
4252
4253int AudioFlinger::openOutput(uint32_t *pDevices,
4254 uint32_t *pSamplingRate,
4255 uint32_t *pFormat,
4256 uint32_t *pChannels,
4257 uint32_t *pLatencyMs,
4258 uint32_t flags)
4259{
4260 status_t status;
4261 PlaybackThread *thread = NULL;
4262 mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
4263 uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
4264 uint32_t format = pFormat ? *pFormat : 0;
4265 uint32_t channels = pChannels ? *pChannels : 0;
4266 uint32_t latency = pLatencyMs ? *pLatencyMs : 0;
4267
4268 LOGV("openOutput(), Device %x, SamplingRate %d, Format %d, Channels %x, flags %x",
4269 pDevices ? *pDevices : 0,
4270 samplingRate,
4271 format,
4272 channels,
4273 flags);
4274
4275 if (pDevices == NULL || *pDevices == 0) {
4276 return 0;
4277 }
4278 Mutex::Autolock _l(mLock);
4279
4280 AudioStreamOut *output = mAudioHardware->openOutputStream(*pDevices,
4281 (int *)&format,
4282 &channels,
4283 &samplingRate,
4284 &status);
4285 LOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d",
4286 output,
4287 samplingRate,
4288 format,
4289 channels,
4290 status);
4291
4292 mHardwareStatus = AUDIO_HW_IDLE;
4293 if (output != 0) {
4294 int id = nextUniqueId();
4295 if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
4296 (format != AudioSystem::PCM_16_BIT) ||
4297 (channels != AudioSystem::CHANNEL_OUT_STEREO)) {
4298 thread = new DirectOutputThread(this, output, id, *pDevices);
4299 LOGV("openOutput() created direct output: ID %d thread %p", id, thread);
4300 } else {
4301 thread = new MixerThread(this, output, id, *pDevices);
4302 LOGV("openOutput() created mixer output: ID %d thread %p", id, thread);
4303
4304#ifdef LVMX
4305 unsigned bitsPerSample =
4306 (format == AudioSystem::PCM_16_BIT) ? 16 :
4307 ((format == AudioSystem::PCM_8_BIT) ? 8 : 0);
4308 unsigned channelCount = (channels == AudioSystem::CHANNEL_OUT_STEREO) ? 2 : 1;
4309 int audioOutputType = LifeVibes::threadIdToAudioOutputType(thread->id());
4310
4311 LifeVibes::init_aot(audioOutputType, samplingRate, bitsPerSample, channelCount);
4312 LifeVibes::setDevice(audioOutputType, *pDevices);
4313#endif
4314
4315 }
4316 mPlaybackThreads.add(id, thread);
4317
4318 if (pSamplingRate) *pSamplingRate = samplingRate;
4319 if (pFormat) *pFormat = format;
4320 if (pChannels) *pChannels = channels;
4321 if (pLatencyMs) *pLatencyMs = thread->latency();
4322
4323 // notify client processes of the new output creation
4324 thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);
4325 return id;
4326 }
4327
4328 return 0;
4329}
4330
4331int AudioFlinger::openDuplicateOutput(int output1, int output2)
4332{
4333 Mutex::Autolock _l(mLock);
4334 MixerThread *thread1 = checkMixerThread_l(output1);
4335 MixerThread *thread2 = checkMixerThread_l(output2);
4336
4337 if (thread1 == NULL || thread2 == NULL) {
4338 LOGW("openDuplicateOutput() wrong output mixer type for output %d or %d", output1, output2);
4339 return 0;
4340 }
4341
4342 int id = nextUniqueId();
4343 DuplicatingThread *thread = new DuplicatingThread(this, thread1, id);
4344 thread->addOutputTrack(thread2);
4345 mPlaybackThreads.add(id, thread);
4346 // notify client processes of the new output creation
4347 thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);
4348 return id;
4349}
4350
4351status_t AudioFlinger::closeOutput(int output)
4352{
4353 // keep strong reference on the playback thread so that
4354 // it is not destroyed while exit() is executed
4355 sp <PlaybackThread> thread;
4356 {
4357 Mutex::Autolock _l(mLock);
4358 thread = checkPlaybackThread_l(output);
4359 if (thread == NULL) {
4360 return BAD_VALUE;
4361 }
4362
4363 LOGV("closeOutput() %d", output);
4364
4365 if (thread->type() == PlaybackThread::MIXER) {
4366 for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
4367 if (mPlaybackThreads.valueAt(i)->type() == PlaybackThread::DUPLICATING) {
4368 DuplicatingThread *dupThread = (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
4369 dupThread->removeOutputTrack((MixerThread *)thread.get());
4370 }
4371 }
4372 }
4373 void *param2 = 0;
4374 audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, param2);
4375 mPlaybackThreads.removeItem(output);
4376 }
4377 thread->exit();
4378
4379 if (thread->type() != PlaybackThread::DUPLICATING) {
4380 mAudioHardware->closeOutputStream(thread->getOutput());
4381 }
4382 return NO_ERROR;
4383}
4384
4385status_t AudioFlinger::suspendOutput(int output)
4386{
4387 Mutex::Autolock _l(mLock);
4388 PlaybackThread *thread = checkPlaybackThread_l(output);
4389
4390 if (thread == NULL) {
4391 return BAD_VALUE;
4392 }
4393
4394 LOGV("suspendOutput() %d", output);
4395 thread->suspend();
4396
4397 return NO_ERROR;
4398}
4399
4400status_t AudioFlinger::restoreOutput(int output)
4401{
4402 Mutex::Autolock _l(mLock);
4403 PlaybackThread *thread = checkPlaybackThread_l(output);
4404
4405 if (thread == NULL) {
4406 return BAD_VALUE;
4407 }
4408
4409 LOGV("restoreOutput() %d", output);
4410
4411 thread->restore();
4412
4413 return NO_ERROR;
4414}
4415
4416int AudioFlinger::openInput(uint32_t *pDevices,
4417 uint32_t *pSamplingRate,
4418 uint32_t *pFormat,
4419 uint32_t *pChannels,
4420 uint32_t acoustics)
4421{
4422 status_t status;
4423 RecordThread *thread = NULL;
4424 uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
4425 uint32_t format = pFormat ? *pFormat : 0;
4426 uint32_t channels = pChannels ? *pChannels : 0;
4427 uint32_t reqSamplingRate = samplingRate;
4428 uint32_t reqFormat = format;
4429 uint32_t reqChannels = channels;
4430
4431 if (pDevices == NULL || *pDevices == 0) {
4432 return 0;
4433 }
4434 Mutex::Autolock _l(mLock);
4435
4436 AudioStreamIn *input = mAudioHardware->openInputStream(*pDevices,
4437 (int *)&format,
4438 &channels,
4439 &samplingRate,
4440 &status,
4441 (AudioSystem::audio_in_acoustics)acoustics);
4442 LOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, acoustics %x, status %d",
4443 input,
4444 samplingRate,
4445 format,
4446 channels,
4447 acoustics,
4448 status);
4449
4450 // If the input could not be opened with the requested parameters and we can handle the conversion internally,
4451 // try to open again with the proposed parameters. The AudioFlinger can resample the input and do mono to stereo
4452 // or stereo to mono conversions on 16 bit PCM inputs.
4453 if (input == 0 && status == BAD_VALUE &&
4454 reqFormat == format && format == AudioSystem::PCM_16_BIT &&
4455 (samplingRate <= 2 * reqSamplingRate) &&
4456 (AudioSystem::popCount(channels) < 3) && (AudioSystem::popCount(reqChannels) < 3)) {
4457 LOGV("openInput() reopening with proposed sampling rate and channels");
4458 input = mAudioHardware->openInputStream(*pDevices,
4459 (int *)&format,
4460 &channels,
4461 &samplingRate,
4462 &status,
4463 (AudioSystem::audio_in_acoustics)acoustics);
4464 }
4465
4466 if (input != 0) {
4467 int id = nextUniqueId();
4468 // Start record thread
4469 thread = new RecordThread(this, input, reqSamplingRate, reqChannels, id);
4470 mRecordThreads.add(id, thread);
4471 LOGV("openInput() created record thread: ID %d thread %p", id, thread);
4472 if (pSamplingRate) *pSamplingRate = reqSamplingRate;
4473 if (pFormat) *pFormat = format;
4474 if (pChannels) *pChannels = reqChannels;
4475
4476 input->standby();
4477
4478 // notify client processes of the new input creation
4479 thread->audioConfigChanged_l(AudioSystem::INPUT_OPENED);
4480 return id;
4481 }
4482
4483 return 0;
4484}
4485
4486status_t AudioFlinger::closeInput(int input)
4487{
4488 // keep strong reference on the record thread so that
4489 // it is not destroyed while exit() is executed
4490 sp <RecordThread> thread;
4491 {
4492 Mutex::Autolock _l(mLock);
4493 thread = checkRecordThread_l(input);
4494 if (thread == NULL) {
4495 return BAD_VALUE;
4496 }
4497
4498 LOGV("closeInput() %d", input);
4499 void *param2 = 0;
4500 audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, param2);
4501 mRecordThreads.removeItem(input);
4502 }
4503 thread->exit();
4504
4505 mAudioHardware->closeInputStream(thread->getInput());
4506
4507 return NO_ERROR;
4508}
4509
4510status_t AudioFlinger::setStreamOutput(uint32_t stream, int output)
4511{
4512 Mutex::Autolock _l(mLock);
4513 MixerThread *dstThread = checkMixerThread_l(output);
4514 if (dstThread == NULL) {
4515 LOGW("setStreamOutput() bad output id %d", output);
4516 return BAD_VALUE;
4517 }
4518
4519 LOGV("setStreamOutput() stream %d to output %d", stream, output);
4520 audioConfigChanged_l(AudioSystem::STREAM_CONFIG_CHANGED, output, &stream);
4521
4522 for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
4523 PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
4524 if (thread != dstThread &&
4525 thread->type() != PlaybackThread::DIRECT) {
4526 MixerThread *srcThread = (MixerThread *)thread;
4527 srcThread->invalidateTracks(stream);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004528 }
Eric Laurentde070132010-07-13 04:45:46 -07004529 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07004530
4531 return NO_ERROR;
4532}
4533
4534
4535int AudioFlinger::newAudioSessionId()
4536{
4537 return nextUniqueId();
4538}
4539
4540// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
4541AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(int output) const
4542{
4543 PlaybackThread *thread = NULL;
4544 if (mPlaybackThreads.indexOfKey(output) >= 0) {
4545 thread = (PlaybackThread *)mPlaybackThreads.valueFor(output).get();
4546 }
4547 return thread;
4548}
4549
4550// checkMixerThread_l() must be called with AudioFlinger::mLock held
4551AudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(int output) const
4552{
4553 PlaybackThread *thread = checkPlaybackThread_l(output);
4554 if (thread != NULL) {
4555 if (thread->type() == PlaybackThread::DIRECT) {
4556 thread = NULL;
4557 }
4558 }
4559 return (MixerThread *)thread;
4560}
4561
4562// checkRecordThread_l() must be called with AudioFlinger::mLock held
4563AudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(int input) const
4564{
4565 RecordThread *thread = NULL;
4566 if (mRecordThreads.indexOfKey(input) >= 0) {
4567 thread = (RecordThread *)mRecordThreads.valueFor(input).get();
4568 }
4569 return thread;
4570}
4571
4572int AudioFlinger::nextUniqueId()
4573{
4574 return android_atomic_inc(&mNextUniqueId);
4575}
4576
4577// ----------------------------------------------------------------------------
4578// Effect management
4579// ----------------------------------------------------------------------------
4580
4581
4582status_t AudioFlinger::loadEffectLibrary(const char *libPath, int *handle)
4583{
Eric Laurentde070132010-07-13 04:45:46 -07004584 // check calling permissions
4585 if (!settingsAllowed()) {
4586 return PERMISSION_DENIED;
4587 }
4588 // only allow libraries loaded from /system/lib/soundfx for now
4589 if (strncmp(gEffectLibPath, libPath, strlen(gEffectLibPath)) != 0) {
4590 return PERMISSION_DENIED;
4591 }
4592
Mathias Agopian65ab4712010-07-14 17:59:35 -07004593 Mutex::Autolock _l(mLock);
4594 return EffectLoadLibrary(libPath, handle);
4595}
4596
4597status_t AudioFlinger::unloadEffectLibrary(int handle)
4598{
Eric Laurentde070132010-07-13 04:45:46 -07004599 // check calling permissions
4600 if (!settingsAllowed()) {
4601 return PERMISSION_DENIED;
4602 }
4603
Mathias Agopian65ab4712010-07-14 17:59:35 -07004604 Mutex::Autolock _l(mLock);
4605 return EffectUnloadLibrary(handle);
4606}
4607
4608status_t AudioFlinger::queryNumberEffects(uint32_t *numEffects)
4609{
4610 Mutex::Autolock _l(mLock);
4611 return EffectQueryNumberEffects(numEffects);
4612}
4613
4614status_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor)
4615{
4616 Mutex::Autolock _l(mLock);
4617 return EffectQueryEffect(index, descriptor);
4618}
4619
4620status_t AudioFlinger::getEffectDescriptor(effect_uuid_t *pUuid, effect_descriptor_t *descriptor)
4621{
4622 Mutex::Autolock _l(mLock);
4623 return EffectGetDescriptor(pUuid, descriptor);
4624}
4625
4626
4627// this UUID must match the one defined in media/libeffects/EffectVisualizer.cpp
4628static const effect_uuid_t VISUALIZATION_UUID_ =
4629 {0xd069d9e0, 0x8329, 0x11df, 0x9168, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
4630
4631sp<IEffect> AudioFlinger::createEffect(pid_t pid,
4632 effect_descriptor_t *pDesc,
4633 const sp<IEffectClient>& effectClient,
4634 int32_t priority,
4635 int output,
4636 int sessionId,
4637 status_t *status,
4638 int *id,
4639 int *enabled)
4640{
4641 status_t lStatus = NO_ERROR;
4642 sp<EffectHandle> handle;
4643 effect_interface_t itfe;
4644 effect_descriptor_t desc;
4645 sp<Client> client;
4646 wp<Client> wclient;
4647
Eric Laurentde070132010-07-13 04:45:46 -07004648 LOGV("createEffect pid %d, client %p, priority %d, sessionId %d, output %d",
4649 pid, effectClient.get(), priority, sessionId, output);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004650
4651 if (pDesc == NULL) {
4652 lStatus = BAD_VALUE;
4653 goto Exit;
4654 }
4655
4656 {
4657 Mutex::Autolock _l(mLock);
4658
4659 // check recording permission for visualizer
4660 if (memcmp(&pDesc->type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0 ||
4661 memcmp(&pDesc->uuid, &VISUALIZATION_UUID_, sizeof(effect_uuid_t)) == 0) {
4662 if (!recordingAllowed()) {
4663 lStatus = PERMISSION_DENIED;
4664 goto Exit;
4665 }
4666 }
4667
4668 if (!EffectIsNullUuid(&pDesc->uuid)) {
4669 // if uuid is specified, request effect descriptor
4670 lStatus = EffectGetDescriptor(&pDesc->uuid, &desc);
4671 if (lStatus < 0) {
4672 LOGW("createEffect() error %d from EffectGetDescriptor", lStatus);
4673 goto Exit;
4674 }
4675 } else {
4676 // if uuid is not specified, look for an available implementation
4677 // of the required type in effect factory
4678 if (EffectIsNullUuid(&pDesc->type)) {
4679 LOGW("createEffect() no effect type");
4680 lStatus = BAD_VALUE;
4681 goto Exit;
4682 }
4683 uint32_t numEffects = 0;
4684 effect_descriptor_t d;
4685 bool found = false;
4686
4687 lStatus = EffectQueryNumberEffects(&numEffects);
4688 if (lStatus < 0) {
4689 LOGW("createEffect() error %d from EffectQueryNumberEffects", lStatus);
4690 goto Exit;
4691 }
4692 for (uint32_t i = 0; i < numEffects; i++) {
4693 lStatus = EffectQueryEffect(i, &desc);
4694 if (lStatus < 0) {
4695 LOGW("createEffect() error %d from EffectQueryEffect", lStatus);
4696 continue;
4697 }
4698 if (memcmp(&desc.type, &pDesc->type, sizeof(effect_uuid_t)) == 0) {
4699 // If matching type found save effect descriptor. If the session is
4700 // 0 and the effect is not auxiliary, continue enumeration in case
4701 // an auxiliary version of this effect type is available
4702 found = true;
4703 memcpy(&d, &desc, sizeof(effect_descriptor_t));
Eric Laurentde070132010-07-13 04:45:46 -07004704 if (sessionId != AudioSystem::SESSION_OUTPUT_MIX ||
Mathias Agopian65ab4712010-07-14 17:59:35 -07004705 (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
4706 break;
4707 }
4708 }
4709 }
4710 if (!found) {
4711 lStatus = BAD_VALUE;
4712 LOGW("createEffect() effect not found");
4713 goto Exit;
4714 }
4715 // For same effect type, chose auxiliary version over insert version if
4716 // connect to output mix (Compliance to OpenSL ES)
Eric Laurentde070132010-07-13 04:45:46 -07004717 if (sessionId == AudioSystem::SESSION_OUTPUT_MIX &&
Mathias Agopian65ab4712010-07-14 17:59:35 -07004718 (d.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_AUXILIARY) {
4719 memcpy(&desc, &d, sizeof(effect_descriptor_t));
4720 }
4721 }
4722
4723 // Do not allow auxiliary effects on a session different from 0 (output mix)
Eric Laurentde070132010-07-13 04:45:46 -07004724 if (sessionId != AudioSystem::SESSION_OUTPUT_MIX &&
Mathias Agopian65ab4712010-07-14 17:59:35 -07004725 (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
4726 lStatus = INVALID_OPERATION;
4727 goto Exit;
4728 }
4729
Eric Laurentde070132010-07-13 04:45:46 -07004730 // Session AudioSystem::SESSION_OUTPUT_STAGE is reserved for output stage effects
4731 // that can only be created by audio policy manager (running in same process)
4732 if (sessionId == AudioSystem::SESSION_OUTPUT_STAGE &&
Eric Laurente0aed6d2010-09-10 17:44:44 -07004733 getpid() != pid) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07004734 lStatus = INVALID_OPERATION;
4735 goto Exit;
4736 }
4737
4738 // return effect descriptor
4739 memcpy(pDesc, &desc, sizeof(effect_descriptor_t));
4740
4741 // If output is not specified try to find a matching audio session ID in one of the
4742 // output threads.
4743 // TODO: allow attachment of effect to inputs
4744 if (output == 0) {
Eric Laurentde070132010-07-13 04:45:46 -07004745 if (sessionId == AudioSystem::SESSION_OUTPUT_STAGE) {
4746 // output must be specified by AudioPolicyManager when using session
4747 // AudioSystem::SESSION_OUTPUT_STAGE
4748 lStatus = BAD_VALUE;
4749 goto Exit;
4750 } else if (sessionId == AudioSystem::SESSION_OUTPUT_MIX) {
4751 output = AudioSystem::getOutputForEffect(&desc);
4752 LOGV("createEffect() got output %d for effect %s", output, desc.name);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004753 } else {
4754 // look for the thread where the specified audio session is present
4755 for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
Eric Laurent39e94f82010-07-28 01:32:47 -07004756 if (mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07004757 output = mPlaybackThreads.keyAt(i);
4758 break;
4759 }
4760 }
Eric Laurent39e94f82010-07-28 01:32:47 -07004761 // If no output thread contains the requested session ID, default to
4762 // first output. The effect chain will be moved to the correct output
4763 // thread when a track with the same session ID is created
4764 if (output == 0 && mPlaybackThreads.size()) {
4765 output = mPlaybackThreads.keyAt(0);
4766 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07004767 }
4768 }
4769 PlaybackThread *thread = checkPlaybackThread_l(output);
4770 if (thread == NULL) {
Eric Laurentde070132010-07-13 04:45:46 -07004771 LOGE("createEffect() unknown output thread");
Mathias Agopian65ab4712010-07-14 17:59:35 -07004772 lStatus = BAD_VALUE;
4773 goto Exit;
4774 }
4775
4776 wclient = mClients.valueFor(pid);
4777
4778 if (wclient != NULL) {
4779 client = wclient.promote();
4780 } else {
4781 client = new Client(this, pid);
4782 mClients.add(pid, client);
4783 }
4784
4785 // create effect on selected output trhead
Eric Laurentde070132010-07-13 04:45:46 -07004786 handle = thread->createEffect_l(client, effectClient, priority, sessionId,
4787 &desc, enabled, &lStatus);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004788 if (handle != 0 && id != NULL) {
4789 *id = handle->id();
4790 }
4791 }
4792
4793Exit:
4794 if(status) {
4795 *status = lStatus;
4796 }
4797 return handle;
4798}
4799
Eric Laurentde070132010-07-13 04:45:46 -07004800status_t AudioFlinger::moveEffects(int session, int srcOutput, int dstOutput)
4801{
4802 LOGV("moveEffects() session %d, srcOutput %d, dstOutput %d",
4803 session, srcOutput, dstOutput);
4804 Mutex::Autolock _l(mLock);
4805 if (srcOutput == dstOutput) {
4806 LOGW("moveEffects() same dst and src outputs %d", dstOutput);
4807 return NO_ERROR;
Mathias Agopian65ab4712010-07-14 17:59:35 -07004808 }
Eric Laurentde070132010-07-13 04:45:46 -07004809 PlaybackThread *srcThread = checkPlaybackThread_l(srcOutput);
4810 if (srcThread == NULL) {
4811 LOGW("moveEffects() bad srcOutput %d", srcOutput);
4812 return BAD_VALUE;
Mathias Agopian65ab4712010-07-14 17:59:35 -07004813 }
Eric Laurentde070132010-07-13 04:45:46 -07004814 PlaybackThread *dstThread = checkPlaybackThread_l(dstOutput);
4815 if (dstThread == NULL) {
4816 LOGW("moveEffects() bad dstOutput %d", dstOutput);
4817 return BAD_VALUE;
4818 }
4819
4820 Mutex::Autolock _dl(dstThread->mLock);
4821 Mutex::Autolock _sl(srcThread->mLock);
Eric Laurent39e94f82010-07-28 01:32:47 -07004822 moveEffectChain_l(session, srcThread, dstThread, false);
Eric Laurentde070132010-07-13 04:45:46 -07004823
Mathias Agopian65ab4712010-07-14 17:59:35 -07004824 return NO_ERROR;
4825}
4826
Eric Laurentde070132010-07-13 04:45:46 -07004827// moveEffectChain_l mustbe called with both srcThread and dstThread mLocks held
4828status_t AudioFlinger::moveEffectChain_l(int session,
4829 AudioFlinger::PlaybackThread *srcThread,
Eric Laurent39e94f82010-07-28 01:32:47 -07004830 AudioFlinger::PlaybackThread *dstThread,
4831 bool reRegister)
Eric Laurentde070132010-07-13 04:45:46 -07004832{
4833 LOGV("moveEffectChain_l() session %d from thread %p to thread %p",
4834 session, srcThread, dstThread);
4835
4836 sp<EffectChain> chain = srcThread->getEffectChain_l(session);
4837 if (chain == 0) {
4838 LOGW("moveEffectChain_l() effect chain for session %d not on source thread %p",
4839 session, srcThread);
4840 return INVALID_OPERATION;
4841 }
4842
Eric Laurent39e94f82010-07-28 01:32:47 -07004843 // remove chain first. This is useful only if reconfiguring effect chain on same output thread,
Eric Laurentde070132010-07-13 04:45:46 -07004844 // so that a new chain is created with correct parameters when first effect is added. This is
4845 // otherwise unecessary as removeEffect_l() will remove the chain when last effect is
4846 // removed.
4847 srcThread->removeEffectChain_l(chain);
4848
4849 // transfer all effects one by one so that new effect chain is created on new thread with
4850 // correct buffer sizes and audio parameters and effect engines reconfigured accordingly
Eric Laurent39e94f82010-07-28 01:32:47 -07004851 int dstOutput = dstThread->id();
4852 sp<EffectChain> dstChain;
4853 uint32_t strategy;
Eric Laurentde070132010-07-13 04:45:46 -07004854 sp<EffectModule> effect = chain->getEffectFromId_l(0);
4855 while (effect != 0) {
4856 srcThread->removeEffect_l(effect);
4857 dstThread->addEffect_l(effect);
Eric Laurent39e94f82010-07-28 01:32:47 -07004858 // if the move request is not received from audio policy manager, the effect must be
4859 // re-registered with the new strategy and output
4860 if (dstChain == 0) {
4861 dstChain = effect->chain().promote();
4862 if (dstChain == 0) {
4863 LOGW("moveEffectChain_l() cannot get chain from effect %p", effect.get());
4864 srcThread->addEffect_l(effect);
4865 return NO_INIT;
4866 }
4867 strategy = dstChain->strategy();
4868 }
4869 if (reRegister) {
4870 AudioSystem::unregisterEffect(effect->id());
4871 AudioSystem::registerEffect(&effect->desc(),
4872 dstOutput,
4873 strategy,
4874 session,
4875 effect->id());
4876 }
Eric Laurentde070132010-07-13 04:45:46 -07004877 effect = chain->getEffectFromId_l(0);
4878 }
4879
4880 return NO_ERROR;
Mathias Agopian65ab4712010-07-14 17:59:35 -07004881}
4882
4883// PlaybackThread::createEffect_l() must be called with AudioFlinger::mLock held
4884sp<AudioFlinger::EffectHandle> AudioFlinger::PlaybackThread::createEffect_l(
4885 const sp<AudioFlinger::Client>& client,
4886 const sp<IEffectClient>& effectClient,
4887 int32_t priority,
4888 int sessionId,
4889 effect_descriptor_t *desc,
4890 int *enabled,
4891 status_t *status
4892 )
4893{
4894 sp<EffectModule> effect;
4895 sp<EffectHandle> handle;
4896 status_t lStatus;
4897 sp<Track> track;
4898 sp<EffectChain> chain;
Eric Laurentde070132010-07-13 04:45:46 -07004899 bool chainCreated = false;
Mathias Agopian65ab4712010-07-14 17:59:35 -07004900 bool effectCreated = false;
4901 bool effectRegistered = false;
4902
4903 if (mOutput == 0) {
4904 LOGW("createEffect_l() Audio driver not initialized.");
4905 lStatus = NO_INIT;
4906 goto Exit;
4907 }
4908
4909 // Do not allow auxiliary effect on session other than 0
4910 if ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY &&
Eric Laurentde070132010-07-13 04:45:46 -07004911 sessionId != AudioSystem::SESSION_OUTPUT_MIX) {
4912 LOGW("createEffect_l() Cannot add auxiliary effect %s to session %d",
4913 desc->name, sessionId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004914 lStatus = BAD_VALUE;
4915 goto Exit;
4916 }
4917
4918 // Do not allow effects with session ID 0 on direct output or duplicating threads
4919 // TODO: add rule for hw accelerated effects on direct outputs with non PCM format
Eric Laurentde070132010-07-13 04:45:46 -07004920 if (sessionId == AudioSystem::SESSION_OUTPUT_MIX && mType != MIXER) {
4921 LOGW("createEffect_l() Cannot add auxiliary effect %s to session %d",
4922 desc->name, sessionId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004923 lStatus = BAD_VALUE;
4924 goto Exit;
4925 }
4926
4927 LOGV("createEffect_l() thread %p effect %s on session %d", this, desc->name, sessionId);
4928
4929 { // scope for mLock
4930 Mutex::Autolock _l(mLock);
4931
4932 // check for existing effect chain with the requested audio session
4933 chain = getEffectChain_l(sessionId);
4934 if (chain == 0) {
4935 // create a new chain for this session
4936 LOGV("createEffect_l() new effect chain for session %d", sessionId);
4937 chain = new EffectChain(this, sessionId);
4938 addEffectChain_l(chain);
Eric Laurentde070132010-07-13 04:45:46 -07004939 chain->setStrategy(getStrategyForSession_l(sessionId));
4940 chainCreated = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -07004941 } else {
Eric Laurentcab11242010-07-15 12:50:15 -07004942 effect = chain->getEffectFromDesc_l(desc);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004943 }
4944
4945 LOGV("createEffect_l() got effect %p on chain %p", effect == 0 ? 0 : effect.get(), chain.get());
4946
4947 if (effect == 0) {
Eric Laurentde070132010-07-13 04:45:46 -07004948 int id = mAudioFlinger->nextUniqueId();
Mathias Agopian65ab4712010-07-14 17:59:35 -07004949 // Check CPU and memory usage
Eric Laurentde070132010-07-13 04:45:46 -07004950 lStatus = AudioSystem::registerEffect(desc, mId, chain->strategy(), sessionId, id);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004951 if (lStatus != NO_ERROR) {
4952 goto Exit;
4953 }
4954 effectRegistered = true;
4955 // create a new effect module if none present in the chain
Eric Laurentde070132010-07-13 04:45:46 -07004956 effect = new EffectModule(this, chain, desc, id, sessionId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004957 lStatus = effect->status();
4958 if (lStatus != NO_ERROR) {
4959 goto Exit;
4960 }
Eric Laurentcab11242010-07-15 12:50:15 -07004961 lStatus = chain->addEffect_l(effect);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004962 if (lStatus != NO_ERROR) {
4963 goto Exit;
4964 }
4965 effectCreated = true;
4966
4967 effect->setDevice(mDevice);
4968 effect->setMode(mAudioFlinger->getMode());
4969 }
4970 // create effect handle and connect it to effect module
4971 handle = new EffectHandle(effect, client, effectClient, priority);
4972 lStatus = effect->addHandle(handle);
4973 if (enabled) {
4974 *enabled = (int)effect->isEnabled();
4975 }
4976 }
4977
4978Exit:
4979 if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
Eric Laurentde070132010-07-13 04:45:46 -07004980 Mutex::Autolock _l(mLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004981 if (effectCreated) {
Eric Laurentde070132010-07-13 04:45:46 -07004982 chain->removeEffect_l(effect);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004983 }
4984 if (effectRegistered) {
Eric Laurentde070132010-07-13 04:45:46 -07004985 AudioSystem::unregisterEffect(effect->id());
4986 }
4987 if (chainCreated) {
4988 removeEffectChain_l(chain);
Mathias Agopian65ab4712010-07-14 17:59:35 -07004989 }
4990 handle.clear();
4991 }
4992
4993 if(status) {
4994 *status = lStatus;
4995 }
4996 return handle;
4997}
4998
Eric Laurentde070132010-07-13 04:45:46 -07004999// PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and
5000// PlaybackThread::mLock held
5001status_t AudioFlinger::PlaybackThread::addEffect_l(const sp<EffectModule>& effect)
5002{
5003 // check for existing effect chain with the requested audio session
5004 int sessionId = effect->sessionId();
5005 sp<EffectChain> chain = getEffectChain_l(sessionId);
5006 bool chainCreated = false;
5007
5008 if (chain == 0) {
5009 // create a new chain for this session
5010 LOGV("addEffect_l() new effect chain for session %d", sessionId);
5011 chain = new EffectChain(this, sessionId);
5012 addEffectChain_l(chain);
5013 chain->setStrategy(getStrategyForSession_l(sessionId));
5014 chainCreated = true;
5015 }
5016 LOGV("addEffect_l() %p chain %p effect %p", this, chain.get(), effect.get());
5017
5018 if (chain->getEffectFromId_l(effect->id()) != 0) {
5019 LOGW("addEffect_l() %p effect %s already present in chain %p",
5020 this, effect->desc().name, chain.get());
5021 return BAD_VALUE;
5022 }
5023
5024 status_t status = chain->addEffect_l(effect);
5025 if (status != NO_ERROR) {
5026 if (chainCreated) {
5027 removeEffectChain_l(chain);
5028 }
5029 return status;
5030 }
5031
5032 effect->setDevice(mDevice);
5033 effect->setMode(mAudioFlinger->getMode());
5034 return NO_ERROR;
5035}
5036
5037void AudioFlinger::PlaybackThread::removeEffect_l(const sp<EffectModule>& effect) {
5038
5039 LOGV("removeEffect_l() %p effect %p", this, effect.get());
Mathias Agopian65ab4712010-07-14 17:59:35 -07005040 effect_descriptor_t desc = effect->desc();
Eric Laurentde070132010-07-13 04:45:46 -07005041 if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
5042 detachAuxEffect_l(effect->id());
5043 }
5044
5045 sp<EffectChain> chain = effect->chain().promote();
5046 if (chain != 0) {
5047 // remove effect chain if removing last effect
5048 if (chain->removeEffect_l(effect) == 0) {
5049 removeEffectChain_l(chain);
5050 }
5051 } else {
5052 LOGW("removeEffect_l() %p cannot promote chain for effect %p", this, effect.get());
5053 }
5054}
5055
5056void AudioFlinger::PlaybackThread::disconnectEffect(const sp<EffectModule>& effect,
5057 const wp<EffectHandle>& handle) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07005058 Mutex::Autolock _l(mLock);
Eric Laurentde070132010-07-13 04:45:46 -07005059 LOGV("disconnectEffect() %p effect %p", this, effect.get());
Mathias Agopian65ab4712010-07-14 17:59:35 -07005060 // delete the effect module if removing last handle on it
5061 if (effect->removeHandle(handle) == 0) {
Eric Laurentde070132010-07-13 04:45:46 -07005062 removeEffect_l(effect);
5063 AudioSystem::unregisterEffect(effect->id());
Mathias Agopian65ab4712010-07-14 17:59:35 -07005064 }
5065}
5066
5067status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& chain)
5068{
5069 int session = chain->sessionId();
5070 int16_t *buffer = mMixBuffer;
5071 bool ownsBuffer = false;
5072
5073 LOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session);
5074 if (session > 0) {
5075 // Only one effect chain can be present in direct output thread and it uses
5076 // the mix buffer as input
5077 if (mType != DIRECT) {
5078 size_t numSamples = mFrameCount * mChannelCount;
5079 buffer = new int16_t[numSamples];
5080 memset(buffer, 0, numSamples * sizeof(int16_t));
5081 LOGV("addEffectChain_l() creating new input buffer %p session %d", buffer, session);
5082 ownsBuffer = true;
5083 }
5084
5085 // Attach all tracks with same session ID to this chain.
5086 for (size_t i = 0; i < mTracks.size(); ++i) {
5087 sp<Track> track = mTracks[i];
5088 if (session == track->sessionId()) {
5089 LOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p", track.get(), buffer);
5090 track->setMainBuffer(buffer);
5091 }
5092 }
5093
5094 // indicate all active tracks in the chain
5095 for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) {
5096 sp<Track> track = mActiveTracks[i].promote();
5097 if (track == 0) continue;
5098 if (session == track->sessionId()) {
5099 LOGV("addEffectChain_l() activating track %p on session %d", track.get(), session);
5100 chain->startTrack();
5101 }
5102 }
5103 }
5104
5105 chain->setInBuffer(buffer, ownsBuffer);
5106 chain->setOutBuffer(mMixBuffer);
Eric Laurentde070132010-07-13 04:45:46 -07005107 // Effect chain for session AudioSystem::SESSION_OUTPUT_STAGE is inserted at end of effect
5108 // chains list in order to be processed last as it contains output stage effects
5109 // Effect chain for session AudioSystem::SESSION_OUTPUT_MIX is inserted before
5110 // session AudioSystem::SESSION_OUTPUT_STAGE to be processed
Mathias Agopian65ab4712010-07-14 17:59:35 -07005111 // after track specific effects and before output stage
Eric Laurentde070132010-07-13 04:45:46 -07005112 // It is therefore mandatory that AudioSystem::SESSION_OUTPUT_MIX == 0 and
5113 // that AudioSystem::SESSION_OUTPUT_STAGE < AudioSystem::SESSION_OUTPUT_MIX
5114 // Effect chain for other sessions are inserted at beginning of effect
5115 // chains list to be processed before output mix effects. Relative order between other
5116 // sessions is not important
Mathias Agopian65ab4712010-07-14 17:59:35 -07005117 size_t size = mEffectChains.size();
5118 size_t i = 0;
5119 for (i = 0; i < size; i++) {
5120 if (mEffectChains[i]->sessionId() < session) break;
5121 }
5122 mEffectChains.insertAt(chain, i);
5123
5124 return NO_ERROR;
5125}
5126
5127size_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<EffectChain>& chain)
5128{
5129 int session = chain->sessionId();
5130
5131 LOGV("removeEffectChain_l() %p from thread %p for session %d", chain.get(), this, session);
5132
5133 for (size_t i = 0; i < mEffectChains.size(); i++) {
5134 if (chain == mEffectChains[i]) {
5135 mEffectChains.removeAt(i);
5136 // detach all tracks with same session ID from this chain
5137 for (size_t i = 0; i < mTracks.size(); ++i) {
5138 sp<Track> track = mTracks[i];
5139 if (session == track->sessionId()) {
5140 track->setMainBuffer(mMixBuffer);
5141 }
5142 }
Eric Laurentde070132010-07-13 04:45:46 -07005143 break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07005144 }
5145 }
5146 return mEffectChains.size();
5147}
5148
Eric Laurentde070132010-07-13 04:45:46 -07005149void AudioFlinger::PlaybackThread::lockEffectChains_l(
5150 Vector<sp <AudioFlinger::EffectChain> >& effectChains)
Mathias Agopian65ab4712010-07-14 17:59:35 -07005151{
Eric Laurentde070132010-07-13 04:45:46 -07005152 effectChains = mEffectChains;
Mathias Agopian65ab4712010-07-14 17:59:35 -07005153 for (size_t i = 0; i < mEffectChains.size(); i++) {
5154 mEffectChains[i]->lock();
5155 }
5156}
5157
Eric Laurentde070132010-07-13 04:45:46 -07005158void AudioFlinger::PlaybackThread::unlockEffectChains(
5159 Vector<sp <AudioFlinger::EffectChain> >& effectChains)
Mathias Agopian65ab4712010-07-14 17:59:35 -07005160{
Eric Laurentde070132010-07-13 04:45:46 -07005161 for (size_t i = 0; i < effectChains.size(); i++) {
5162 effectChains[i]->unlock();
Mathias Agopian65ab4712010-07-14 17:59:35 -07005163 }
5164}
5165
Eric Laurentde070132010-07-13 04:45:46 -07005166
Mathias Agopian65ab4712010-07-14 17:59:35 -07005167sp<AudioFlinger::EffectModule> AudioFlinger::PlaybackThread::getEffect_l(int sessionId, int effectId)
5168{
5169 sp<EffectModule> effect;
5170
5171 sp<EffectChain> chain = getEffectChain_l(sessionId);
5172 if (chain != 0) {
Eric Laurentcab11242010-07-15 12:50:15 -07005173 effect = chain->getEffectFromId_l(effectId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005174 }
5175 return effect;
5176}
5177
Eric Laurentde070132010-07-13 04:45:46 -07005178status_t AudioFlinger::PlaybackThread::attachAuxEffect(
5179 const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId)
Mathias Agopian65ab4712010-07-14 17:59:35 -07005180{
5181 Mutex::Autolock _l(mLock);
5182 return attachAuxEffect_l(track, EffectId);
5183}
5184
Eric Laurentde070132010-07-13 04:45:46 -07005185status_t AudioFlinger::PlaybackThread::attachAuxEffect_l(
5186 const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId)
Mathias Agopian65ab4712010-07-14 17:59:35 -07005187{
5188 status_t status = NO_ERROR;
5189
5190 if (EffectId == 0) {
5191 track->setAuxBuffer(0, NULL);
5192 } else {
Eric Laurentde070132010-07-13 04:45:46 -07005193 // Auxiliary effects are always in audio session AudioSystem::SESSION_OUTPUT_MIX
5194 sp<EffectModule> effect = getEffect_l(AudioSystem::SESSION_OUTPUT_MIX, EffectId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005195 if (effect != 0) {
5196 if ((effect->desc().flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
5197 track->setAuxBuffer(EffectId, (int32_t *)effect->inBuffer());
5198 } else {
5199 status = INVALID_OPERATION;
5200 }
5201 } else {
5202 status = BAD_VALUE;
5203 }
5204 }
5205 return status;
5206}
5207
5208void AudioFlinger::PlaybackThread::detachAuxEffect_l(int effectId)
5209{
5210 for (size_t i = 0; i < mTracks.size(); ++i) {
5211 sp<Track> track = mTracks[i];
5212 if (track->auxEffectId() == effectId) {
5213 attachAuxEffect_l(track, 0);
5214 }
5215 }
5216}
5217
5218// ----------------------------------------------------------------------------
5219// EffectModule implementation
5220// ----------------------------------------------------------------------------
5221
5222#undef LOG_TAG
5223#define LOG_TAG "AudioFlinger::EffectModule"
5224
5225AudioFlinger::EffectModule::EffectModule(const wp<ThreadBase>& wThread,
5226 const wp<AudioFlinger::EffectChain>& chain,
5227 effect_descriptor_t *desc,
5228 int id,
5229 int sessionId)
5230 : mThread(wThread), mChain(chain), mId(id), mSessionId(sessionId), mEffectInterface(NULL),
5231 mStatus(NO_INIT), mState(IDLE)
5232{
5233 LOGV("Constructor %p", this);
5234 int lStatus;
5235 sp<ThreadBase> thread = mThread.promote();
5236 if (thread == 0) {
5237 return;
5238 }
5239 PlaybackThread *p = (PlaybackThread *)thread.get();
5240
5241 memcpy(&mDescriptor, desc, sizeof(effect_descriptor_t));
5242
5243 // create effect engine from effect factory
5244 mStatus = EffectCreate(&desc->uuid, sessionId, p->id(), &mEffectInterface);
5245
5246 if (mStatus != NO_ERROR) {
5247 return;
5248 }
5249 lStatus = init();
5250 if (lStatus < 0) {
5251 mStatus = lStatus;
5252 goto Error;
5253 }
5254
5255 LOGV("Constructor success name %s, Interface %p", mDescriptor.name, mEffectInterface);
5256 return;
5257Error:
5258 EffectRelease(mEffectInterface);
5259 mEffectInterface = NULL;
5260 LOGV("Constructor Error %d", mStatus);
5261}
5262
5263AudioFlinger::EffectModule::~EffectModule()
5264{
5265 LOGV("Destructor %p", this);
5266 if (mEffectInterface != NULL) {
5267 // release effect engine
5268 EffectRelease(mEffectInterface);
5269 }
5270}
5271
5272status_t AudioFlinger::EffectModule::addHandle(sp<EffectHandle>& handle)
5273{
5274 status_t status;
5275
5276 Mutex::Autolock _l(mLock);
5277 // First handle in mHandles has highest priority and controls the effect module
5278 int priority = handle->priority();
5279 size_t size = mHandles.size();
5280 sp<EffectHandle> h;
5281 size_t i;
5282 for (i = 0; i < size; i++) {
5283 h = mHandles[i].promote();
5284 if (h == 0) continue;
5285 if (h->priority() <= priority) break;
5286 }
5287 // if inserted in first place, move effect control from previous owner to this handle
5288 if (i == 0) {
5289 if (h != 0) {
5290 h->setControl(false, true);
5291 }
5292 handle->setControl(true, false);
5293 status = NO_ERROR;
5294 } else {
5295 status = ALREADY_EXISTS;
5296 }
5297 mHandles.insertAt(handle, i);
5298 return status;
5299}
5300
5301size_t AudioFlinger::EffectModule::removeHandle(const wp<EffectHandle>& handle)
5302{
5303 Mutex::Autolock _l(mLock);
5304 size_t size = mHandles.size();
5305 size_t i;
5306 for (i = 0; i < size; i++) {
5307 if (mHandles[i] == handle) break;
5308 }
5309 if (i == size) {
5310 return size;
5311 }
5312 mHandles.removeAt(i);
5313 size = mHandles.size();
5314 // if removed from first place, move effect control from this handle to next in line
5315 if (i == 0 && size != 0) {
5316 sp<EffectHandle> h = mHandles[0].promote();
5317 if (h != 0) {
5318 h->setControl(true, true);
5319 }
5320 }
5321
5322 return size;
5323}
5324
5325void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle)
5326{
5327 // keep a strong reference on this EffectModule to avoid calling the
5328 // destructor before we exit
5329 sp<EffectModule> keep(this);
5330 {
5331 sp<ThreadBase> thread = mThread.promote();
5332 if (thread != 0) {
5333 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
5334 playbackThread->disconnectEffect(keep, handle);
5335 }
5336 }
5337}
5338
5339void AudioFlinger::EffectModule::updateState() {
5340 Mutex::Autolock _l(mLock);
5341
5342 switch (mState) {
5343 case RESTART:
5344 reset_l();
5345 // FALL THROUGH
5346
5347 case STARTING:
5348 // clear auxiliary effect input buffer for next accumulation
5349 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
5350 memset(mConfig.inputCfg.buffer.raw,
5351 0,
5352 mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
5353 }
5354 start_l();
5355 mState = ACTIVE;
5356 break;
5357 case STOPPING:
5358 stop_l();
5359 mDisableWaitCnt = mMaxDisableWaitCnt;
5360 mState = STOPPED;
5361 break;
5362 case STOPPED:
5363 // mDisableWaitCnt is forced to 1 by process() when the engine indicates the end of the
5364 // turn off sequence.
5365 if (--mDisableWaitCnt == 0) {
5366 reset_l();
5367 mState = IDLE;
5368 }
5369 break;
5370 default: //IDLE , ACTIVE
5371 break;
5372 }
5373}
5374
5375void AudioFlinger::EffectModule::process()
5376{
5377 Mutex::Autolock _l(mLock);
5378
5379 if (mEffectInterface == NULL ||
5380 mConfig.inputCfg.buffer.raw == NULL ||
5381 mConfig.outputCfg.buffer.raw == NULL) {
5382 return;
5383 }
5384
Eric Laurent8f45bd72010-08-31 13:50:07 -07005385 if (isProcessEnabled()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07005386 // do 32 bit to 16 bit conversion for auxiliary effect input buffer
5387 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
5388 AudioMixer::ditherAndClamp(mConfig.inputCfg.buffer.s32,
5389 mConfig.inputCfg.buffer.s32,
Eric Laurentde070132010-07-13 04:45:46 -07005390 mConfig.inputCfg.buffer.frameCount/2);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005391 }
5392
5393 // do the actual processing in the effect engine
5394 int ret = (*mEffectInterface)->process(mEffectInterface,
5395 &mConfig.inputCfg.buffer,
5396 &mConfig.outputCfg.buffer);
5397
5398 // force transition to IDLE state when engine is ready
5399 if (mState == STOPPED && ret == -ENODATA) {
5400 mDisableWaitCnt = 1;
5401 }
5402
5403 // clear auxiliary effect input buffer for next accumulation
5404 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
5405 memset(mConfig.inputCfg.buffer.raw, 0, mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
5406 }
5407 } else if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT &&
5408 mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw){
5409 // If an insert effect is idle and input buffer is different from output buffer, copy input to
5410 // output
5411 sp<EffectChain> chain = mChain.promote();
5412 if (chain != 0 && chain->activeTracks() != 0) {
5413 size_t size = mConfig.inputCfg.buffer.frameCount * sizeof(int16_t);
5414 if (mConfig.inputCfg.channels == CHANNEL_STEREO) {
5415 size *= 2;
5416 }
5417 memcpy(mConfig.outputCfg.buffer.raw, mConfig.inputCfg.buffer.raw, size);
5418 }
5419 }
5420}
5421
5422void AudioFlinger::EffectModule::reset_l()
5423{
5424 if (mEffectInterface == NULL) {
5425 return;
5426 }
5427 (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_RESET, 0, NULL, 0, NULL);
5428}
5429
5430status_t AudioFlinger::EffectModule::configure()
5431{
5432 uint32_t channels;
5433 if (mEffectInterface == NULL) {
5434 return NO_INIT;
5435 }
5436
5437 sp<ThreadBase> thread = mThread.promote();
5438 if (thread == 0) {
5439 return DEAD_OBJECT;
5440 }
5441
5442 // TODO: handle configuration of effects replacing track process
5443 if (thread->channelCount() == 1) {
5444 channels = CHANNEL_MONO;
5445 } else {
5446 channels = CHANNEL_STEREO;
5447 }
5448
5449 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
5450 mConfig.inputCfg.channels = CHANNEL_MONO;
5451 } else {
5452 mConfig.inputCfg.channels = channels;
5453 }
5454 mConfig.outputCfg.channels = channels;
5455 mConfig.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
5456 mConfig.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
5457 mConfig.inputCfg.samplingRate = thread->sampleRate();
5458 mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate;
5459 mConfig.inputCfg.bufferProvider.cookie = NULL;
5460 mConfig.inputCfg.bufferProvider.getBuffer = NULL;
5461 mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
5462 mConfig.outputCfg.bufferProvider.cookie = NULL;
5463 mConfig.outputCfg.bufferProvider.getBuffer = NULL;
5464 mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
5465 mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
5466 // Insert effect:
Eric Laurentde070132010-07-13 04:45:46 -07005467 // - in session AudioSystem::SESSION_OUTPUT_MIX or AudioSystem::SESSION_OUTPUT_STAGE,
5468 // always overwrites output buffer: input buffer == output buffer
Mathias Agopian65ab4712010-07-14 17:59:35 -07005469 // - in other sessions:
5470 // last effect in the chain accumulates in output buffer: input buffer != output buffer
5471 // other effect: overwrites output buffer: input buffer == output buffer
5472 // Auxiliary effect:
5473 // accumulates in output buffer: input buffer != output buffer
5474 // Therefore: accumulate <=> input buffer != output buffer
5475 if (mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
5476 mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
5477 } else {
5478 mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
5479 }
5480 mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
5481 mConfig.outputCfg.mask = EFFECT_CONFIG_ALL;
5482 mConfig.inputCfg.buffer.frameCount = thread->frameCount();
5483 mConfig.outputCfg.buffer.frameCount = mConfig.inputCfg.buffer.frameCount;
5484
Eric Laurentde070132010-07-13 04:45:46 -07005485 LOGV("configure() %p thread %p buffer %p framecount %d",
5486 this, thread.get(), mConfig.inputCfg.buffer.raw, mConfig.inputCfg.buffer.frameCount);
5487
Mathias Agopian65ab4712010-07-14 17:59:35 -07005488 status_t cmdStatus;
Eric Laurent25f43952010-07-28 05:40:18 -07005489 uint32_t size = sizeof(int);
5490 status_t status = (*mEffectInterface)->command(mEffectInterface,
5491 EFFECT_CMD_CONFIGURE,
5492 sizeof(effect_config_t),
5493 &mConfig,
5494 &size,
5495 &cmdStatus);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005496 if (status == 0) {
5497 status = cmdStatus;
5498 }
5499
5500 mMaxDisableWaitCnt = (MAX_DISABLE_TIME_MS * mConfig.outputCfg.samplingRate) /
5501 (1000 * mConfig.outputCfg.buffer.frameCount);
5502
5503 return status;
5504}
5505
5506status_t AudioFlinger::EffectModule::init()
5507{
5508 Mutex::Autolock _l(mLock);
5509 if (mEffectInterface == NULL) {
5510 return NO_INIT;
5511 }
5512 status_t cmdStatus;
Eric Laurent25f43952010-07-28 05:40:18 -07005513 uint32_t size = sizeof(status_t);
5514 status_t status = (*mEffectInterface)->command(mEffectInterface,
5515 EFFECT_CMD_INIT,
5516 0,
5517 NULL,
5518 &size,
5519 &cmdStatus);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005520 if (status == 0) {
5521 status = cmdStatus;
5522 }
5523 return status;
5524}
5525
5526status_t AudioFlinger::EffectModule::start_l()
5527{
5528 if (mEffectInterface == NULL) {
5529 return NO_INIT;
5530 }
5531 status_t cmdStatus;
Eric Laurent25f43952010-07-28 05:40:18 -07005532 uint32_t size = sizeof(status_t);
5533 status_t status = (*mEffectInterface)->command(mEffectInterface,
5534 EFFECT_CMD_ENABLE,
5535 0,
5536 NULL,
5537 &size,
5538 &cmdStatus);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005539 if (status == 0) {
5540 status = cmdStatus;
5541 }
5542 return status;
5543}
5544
5545status_t AudioFlinger::EffectModule::stop_l()
5546{
5547 if (mEffectInterface == NULL) {
5548 return NO_INIT;
5549 }
5550 status_t cmdStatus;
Eric Laurent25f43952010-07-28 05:40:18 -07005551 uint32_t size = sizeof(status_t);
5552 status_t status = (*mEffectInterface)->command(mEffectInterface,
5553 EFFECT_CMD_DISABLE,
5554 0,
5555 NULL,
5556 &size,
5557 &cmdStatus);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005558 if (status == 0) {
5559 status = cmdStatus;
5560 }
5561 return status;
5562}
5563
Eric Laurent25f43952010-07-28 05:40:18 -07005564status_t AudioFlinger::EffectModule::command(uint32_t cmdCode,
5565 uint32_t cmdSize,
5566 void *pCmdData,
5567 uint32_t *replySize,
5568 void *pReplyData)
Mathias Agopian65ab4712010-07-14 17:59:35 -07005569{
5570 Mutex::Autolock _l(mLock);
5571// LOGV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface);
5572
5573 if (mEffectInterface == NULL) {
5574 return NO_INIT;
5575 }
Eric Laurent25f43952010-07-28 05:40:18 -07005576 status_t status = (*mEffectInterface)->command(mEffectInterface,
5577 cmdCode,
5578 cmdSize,
5579 pCmdData,
5580 replySize,
5581 pReplyData);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005582 if (cmdCode != EFFECT_CMD_GET_PARAM && status == NO_ERROR) {
Eric Laurent25f43952010-07-28 05:40:18 -07005583 uint32_t size = (replySize == NULL) ? 0 : *replySize;
Mathias Agopian65ab4712010-07-14 17:59:35 -07005584 for (size_t i = 1; i < mHandles.size(); i++) {
5585 sp<EffectHandle> h = mHandles[i].promote();
5586 if (h != 0) {
5587 h->commandExecuted(cmdCode, cmdSize, pCmdData, size, pReplyData);
5588 }
5589 }
5590 }
5591 return status;
5592}
5593
5594status_t AudioFlinger::EffectModule::setEnabled(bool enabled)
5595{
5596 Mutex::Autolock _l(mLock);
5597 LOGV("setEnabled %p enabled %d", this, enabled);
5598
5599 if (enabled != isEnabled()) {
5600 switch (mState) {
5601 // going from disabled to enabled
5602 case IDLE:
5603 mState = STARTING;
5604 break;
5605 case STOPPED:
5606 mState = RESTART;
5607 break;
5608 case STOPPING:
5609 mState = ACTIVE;
5610 break;
5611
5612 // going from enabled to disabled
5613 case RESTART:
Eric Laurent8f45bd72010-08-31 13:50:07 -07005614 mState = STOPPED;
5615 break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07005616 case STARTING:
5617 mState = IDLE;
5618 break;
5619 case ACTIVE:
5620 mState = STOPPING;
5621 break;
5622 }
5623 for (size_t i = 1; i < mHandles.size(); i++) {
5624 sp<EffectHandle> h = mHandles[i].promote();
5625 if (h != 0) {
5626 h->setEnabled(enabled);
5627 }
5628 }
5629 }
5630 return NO_ERROR;
5631}
5632
5633bool AudioFlinger::EffectModule::isEnabled()
5634{
5635 switch (mState) {
5636 case RESTART:
5637 case STARTING:
5638 case ACTIVE:
5639 return true;
5640 case IDLE:
5641 case STOPPING:
5642 case STOPPED:
5643 default:
5644 return false;
5645 }
5646}
5647
Eric Laurent8f45bd72010-08-31 13:50:07 -07005648bool AudioFlinger::EffectModule::isProcessEnabled()
5649{
5650 switch (mState) {
5651 case RESTART:
5652 case ACTIVE:
5653 case STOPPING:
5654 case STOPPED:
5655 return true;
5656 case IDLE:
5657 case STARTING:
5658 default:
5659 return false;
5660 }
5661}
5662
Mathias Agopian65ab4712010-07-14 17:59:35 -07005663status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
5664{
5665 Mutex::Autolock _l(mLock);
5666 status_t status = NO_ERROR;
5667
5668 // Send volume indication if EFFECT_FLAG_VOLUME_IND is set and read back altered volume
5669 // if controller flag is set (Note that controller == TRUE => EFFECT_FLAG_VOLUME_CTRL set)
Eric Laurent8f45bd72010-08-31 13:50:07 -07005670 if (isProcessEnabled() &&
Eric Laurentf997cab2010-07-19 06:24:46 -07005671 ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
5672 (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07005673 status_t cmdStatus;
5674 uint32_t volume[2];
5675 uint32_t *pVolume = NULL;
Eric Laurent25f43952010-07-28 05:40:18 -07005676 uint32_t size = sizeof(volume);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005677 volume[0] = *left;
5678 volume[1] = *right;
5679 if (controller) {
5680 pVolume = volume;
5681 }
Eric Laurent25f43952010-07-28 05:40:18 -07005682 status = (*mEffectInterface)->command(mEffectInterface,
5683 EFFECT_CMD_SET_VOLUME,
5684 size,
5685 volume,
5686 &size,
5687 pVolume);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005688 if (controller && status == NO_ERROR && size == sizeof(volume)) {
5689 *left = volume[0];
5690 *right = volume[1];
5691 }
5692 }
5693 return status;
5694}
5695
5696status_t AudioFlinger::EffectModule::setDevice(uint32_t device)
5697{
5698 Mutex::Autolock _l(mLock);
5699 status_t status = NO_ERROR;
5700 if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
5701 // convert device bit field from AudioSystem to EffectApi format.
5702 device = deviceAudioSystemToEffectApi(device);
5703 if (device == 0) {
5704 return BAD_VALUE;
5705 }
5706 status_t cmdStatus;
Eric Laurent25f43952010-07-28 05:40:18 -07005707 uint32_t size = sizeof(status_t);
5708 status = (*mEffectInterface)->command(mEffectInterface,
5709 EFFECT_CMD_SET_DEVICE,
5710 sizeof(uint32_t),
5711 &device,
5712 &size,
5713 &cmdStatus);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005714 if (status == NO_ERROR) {
5715 status = cmdStatus;
5716 }
5717 }
5718 return status;
5719}
5720
5721status_t AudioFlinger::EffectModule::setMode(uint32_t mode)
5722{
5723 Mutex::Autolock _l(mLock);
5724 status_t status = NO_ERROR;
5725 if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_MODE_MASK) == EFFECT_FLAG_AUDIO_MODE_IND) {
5726 // convert audio mode from AudioSystem to EffectApi format.
5727 int effectMode = modeAudioSystemToEffectApi(mode);
5728 if (effectMode < 0) {
5729 return BAD_VALUE;
5730 }
5731 status_t cmdStatus;
Eric Laurent25f43952010-07-28 05:40:18 -07005732 uint32_t size = sizeof(status_t);
5733 status = (*mEffectInterface)->command(mEffectInterface,
5734 EFFECT_CMD_SET_AUDIO_MODE,
5735 sizeof(int),
5736 &effectMode,
5737 &size,
5738 &cmdStatus);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005739 if (status == NO_ERROR) {
5740 status = cmdStatus;
5741 }
5742 }
5743 return status;
5744}
5745
5746// update this table when AudioSystem::audio_devices or audio_device_e (in EffectApi.h) are modified
5747const uint32_t AudioFlinger::EffectModule::sDeviceConvTable[] = {
5748 DEVICE_EARPIECE, // AudioSystem::DEVICE_OUT_EARPIECE
5749 DEVICE_SPEAKER, // AudioSystem::DEVICE_OUT_SPEAKER
5750 DEVICE_WIRED_HEADSET, // case AudioSystem::DEVICE_OUT_WIRED_HEADSET
5751 DEVICE_WIRED_HEADPHONE, // AudioSystem::DEVICE_OUT_WIRED_HEADPHONE
5752 DEVICE_BLUETOOTH_SCO, // AudioSystem::DEVICE_OUT_BLUETOOTH_SCO
5753 DEVICE_BLUETOOTH_SCO_HEADSET, // AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET
5754 DEVICE_BLUETOOTH_SCO_CARKIT, // AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT
5755 DEVICE_BLUETOOTH_A2DP, // AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP
5756 DEVICE_BLUETOOTH_A2DP_HEADPHONES, // AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES
5757 DEVICE_BLUETOOTH_A2DP_SPEAKER, // AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
5758 DEVICE_AUX_DIGITAL // AudioSystem::DEVICE_OUT_AUX_DIGITAL
5759};
5760
5761uint32_t AudioFlinger::EffectModule::deviceAudioSystemToEffectApi(uint32_t device)
5762{
5763 uint32_t deviceOut = 0;
5764 while (device) {
5765 const uint32_t i = 31 - __builtin_clz(device);
5766 device &= ~(1 << i);
5767 if (i >= sizeof(sDeviceConvTable)/sizeof(uint32_t)) {
5768 LOGE("device convertion error for AudioSystem device 0x%08x", device);
5769 return 0;
5770 }
5771 deviceOut |= (uint32_t)sDeviceConvTable[i];
5772 }
5773 return deviceOut;
5774}
5775
5776// update this table when AudioSystem::audio_mode or audio_mode_e (in EffectApi.h) are modified
5777const uint32_t AudioFlinger::EffectModule::sModeConvTable[] = {
5778 AUDIO_MODE_NORMAL, // AudioSystem::MODE_NORMAL
5779 AUDIO_MODE_RINGTONE, // AudioSystem::MODE_RINGTONE
5780 AUDIO_MODE_IN_CALL // AudioSystem::MODE_IN_CALL
5781};
5782
5783int AudioFlinger::EffectModule::modeAudioSystemToEffectApi(uint32_t mode)
5784{
5785 int modeOut = -1;
5786 if (mode < sizeof(sModeConvTable) / sizeof(uint32_t)) {
5787 modeOut = (int)sModeConvTable[mode];
5788 }
5789 return modeOut;
5790}
5791
5792status_t AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
5793{
5794 const size_t SIZE = 256;
5795 char buffer[SIZE];
5796 String8 result;
5797
5798 snprintf(buffer, SIZE, "\tEffect ID %d:\n", mId);
5799 result.append(buffer);
5800
5801 bool locked = tryLock(mLock);
5802 // failed to lock - AudioFlinger is probably deadlocked
5803 if (!locked) {
5804 result.append("\t\tCould not lock Fx mutex:\n");
5805 }
5806
5807 result.append("\t\tSession Status State Engine:\n");
5808 snprintf(buffer, SIZE, "\t\t%05d %03d %03d 0x%08x\n",
5809 mSessionId, mStatus, mState, (uint32_t)mEffectInterface);
5810 result.append(buffer);
5811
5812 result.append("\t\tDescriptor:\n");
5813 snprintf(buffer, SIZE, "\t\t- UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
5814 mDescriptor.uuid.timeLow, mDescriptor.uuid.timeMid, mDescriptor.uuid.timeHiAndVersion,
5815 mDescriptor.uuid.clockSeq, mDescriptor.uuid.node[0], mDescriptor.uuid.node[1],mDescriptor.uuid.node[2],
5816 mDescriptor.uuid.node[3],mDescriptor.uuid.node[4],mDescriptor.uuid.node[5]);
5817 result.append(buffer);
5818 snprintf(buffer, SIZE, "\t\t- TYPE: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
5819 mDescriptor.type.timeLow, mDescriptor.type.timeMid, mDescriptor.type.timeHiAndVersion,
5820 mDescriptor.type.clockSeq, mDescriptor.type.node[0], mDescriptor.type.node[1],mDescriptor.type.node[2],
5821 mDescriptor.type.node[3],mDescriptor.type.node[4],mDescriptor.type.node[5]);
5822 result.append(buffer);
5823 snprintf(buffer, SIZE, "\t\t- apiVersion: %04X\n\t\t- flags: %08X\n",
5824 mDescriptor.apiVersion,
5825 mDescriptor.flags);
5826 result.append(buffer);
5827 snprintf(buffer, SIZE, "\t\t- name: %s\n",
5828 mDescriptor.name);
5829 result.append(buffer);
5830 snprintf(buffer, SIZE, "\t\t- implementor: %s\n",
5831 mDescriptor.implementor);
5832 result.append(buffer);
5833
5834 result.append("\t\t- Input configuration:\n");
5835 result.append("\t\t\tBuffer Frames Smp rate Channels Format\n");
5836 snprintf(buffer, SIZE, "\t\t\t0x%08x %05d %05d %08x %d\n",
5837 (uint32_t)mConfig.inputCfg.buffer.raw,
5838 mConfig.inputCfg.buffer.frameCount,
5839 mConfig.inputCfg.samplingRate,
5840 mConfig.inputCfg.channels,
5841 mConfig.inputCfg.format);
5842 result.append(buffer);
5843
5844 result.append("\t\t- Output configuration:\n");
5845 result.append("\t\t\tBuffer Frames Smp rate Channels Format\n");
5846 snprintf(buffer, SIZE, "\t\t\t0x%08x %05d %05d %08x %d\n",
5847 (uint32_t)mConfig.outputCfg.buffer.raw,
5848 mConfig.outputCfg.buffer.frameCount,
5849 mConfig.outputCfg.samplingRate,
5850 mConfig.outputCfg.channels,
5851 mConfig.outputCfg.format);
5852 result.append(buffer);
5853
5854 snprintf(buffer, SIZE, "\t\t%d Clients:\n", mHandles.size());
5855 result.append(buffer);
5856 result.append("\t\t\tPid Priority Ctrl Locked client server\n");
5857 for (size_t i = 0; i < mHandles.size(); ++i) {
5858 sp<EffectHandle> handle = mHandles[i].promote();
5859 if (handle != 0) {
5860 handle->dump(buffer, SIZE);
5861 result.append(buffer);
5862 }
5863 }
5864
5865 result.append("\n");
5866
5867 write(fd, result.string(), result.length());
5868
5869 if (locked) {
5870 mLock.unlock();
5871 }
5872
5873 return NO_ERROR;
5874}
5875
5876// ----------------------------------------------------------------------------
5877// EffectHandle implementation
5878// ----------------------------------------------------------------------------
5879
5880#undef LOG_TAG
5881#define LOG_TAG "AudioFlinger::EffectHandle"
5882
5883AudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect,
5884 const sp<AudioFlinger::Client>& client,
5885 const sp<IEffectClient>& effectClient,
5886 int32_t priority)
5887 : BnEffect(),
5888 mEffect(effect), mEffectClient(effectClient), mClient(client), mPriority(priority), mHasControl(false)
5889{
5890 LOGV("constructor %p", this);
5891
5892 int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
5893 mCblkMemory = client->heap()->allocate(EFFECT_PARAM_BUFFER_SIZE + bufOffset);
5894 if (mCblkMemory != 0) {
5895 mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->pointer());
5896
5897 if (mCblk) {
5898 new(mCblk) effect_param_cblk_t();
5899 mBuffer = (uint8_t *)mCblk + bufOffset;
5900 }
5901 } else {
5902 LOGE("not enough memory for Effect size=%u", EFFECT_PARAM_BUFFER_SIZE + sizeof(effect_param_cblk_t));
5903 return;
5904 }
5905}
5906
5907AudioFlinger::EffectHandle::~EffectHandle()
5908{
5909 LOGV("Destructor %p", this);
5910 disconnect();
5911}
5912
5913status_t AudioFlinger::EffectHandle::enable()
5914{
5915 if (!mHasControl) return INVALID_OPERATION;
5916 if (mEffect == 0) return DEAD_OBJECT;
5917
5918 return mEffect->setEnabled(true);
5919}
5920
5921status_t AudioFlinger::EffectHandle::disable()
5922{
5923 if (!mHasControl) return INVALID_OPERATION;
5924 if (mEffect == NULL) return DEAD_OBJECT;
5925
5926 return mEffect->setEnabled(false);
5927}
5928
5929void AudioFlinger::EffectHandle::disconnect()
5930{
5931 if (mEffect == 0) {
5932 return;
5933 }
5934 mEffect->disconnect(this);
5935 // release sp on module => module destructor can be called now
5936 mEffect.clear();
5937 if (mCblk) {
5938 mCblk->~effect_param_cblk_t(); // destroy our shared-structure.
5939 }
5940 mCblkMemory.clear(); // and free the shared memory
5941 if (mClient != 0) {
5942 Mutex::Autolock _l(mClient->audioFlinger()->mLock);
5943 mClient.clear();
5944 }
5945}
5946
Eric Laurent25f43952010-07-28 05:40:18 -07005947status_t AudioFlinger::EffectHandle::command(uint32_t cmdCode,
5948 uint32_t cmdSize,
5949 void *pCmdData,
5950 uint32_t *replySize,
5951 void *pReplyData)
Mathias Agopian65ab4712010-07-14 17:59:35 -07005952{
Eric Laurent25f43952010-07-28 05:40:18 -07005953// LOGV("command(), cmdCode: %d, mHasControl: %d, mEffect: %p",
5954// cmdCode, mHasControl, (mEffect == 0) ? 0 : mEffect.get());
Mathias Agopian65ab4712010-07-14 17:59:35 -07005955
5956 // only get parameter command is permitted for applications not controlling the effect
5957 if (!mHasControl && cmdCode != EFFECT_CMD_GET_PARAM) {
5958 return INVALID_OPERATION;
5959 }
5960 if (mEffect == 0) return DEAD_OBJECT;
5961
5962 // handle commands that are not forwarded transparently to effect engine
5963 if (cmdCode == EFFECT_CMD_SET_PARAM_COMMIT) {
5964 // No need to trylock() here as this function is executed in the binder thread serving a particular client process:
5965 // no risk to block the whole media server process or mixer threads is we are stuck here
5966 Mutex::Autolock _l(mCblk->lock);
5967 if (mCblk->clientIndex > EFFECT_PARAM_BUFFER_SIZE ||
5968 mCblk->serverIndex > EFFECT_PARAM_BUFFER_SIZE) {
5969 mCblk->serverIndex = 0;
5970 mCblk->clientIndex = 0;
5971 return BAD_VALUE;
5972 }
5973 status_t status = NO_ERROR;
5974 while (mCblk->serverIndex < mCblk->clientIndex) {
5975 int reply;
Eric Laurent25f43952010-07-28 05:40:18 -07005976 uint32_t rsize = sizeof(int);
Mathias Agopian65ab4712010-07-14 17:59:35 -07005977 int *p = (int *)(mBuffer + mCblk->serverIndex);
5978 int size = *p++;
5979 if (((uint8_t *)p + size) > mBuffer + mCblk->clientIndex) {
5980 LOGW("command(): invalid parameter block size");
5981 break;
5982 }
5983 effect_param_t *param = (effect_param_t *)p;
5984 if (param->psize == 0 || param->vsize == 0) {
5985 LOGW("command(): null parameter or value size");
5986 mCblk->serverIndex += size;
5987 continue;
5988 }
Eric Laurent25f43952010-07-28 05:40:18 -07005989 uint32_t psize = sizeof(effect_param_t) +
5990 ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
5991 param->vsize;
5992 status_t ret = mEffect->command(EFFECT_CMD_SET_PARAM,
5993 psize,
5994 p,
5995 &rsize,
5996 &reply);
Eric Laurentaeae3de2010-09-02 11:56:55 -07005997 // stop at first error encountered
5998 if (ret != NO_ERROR) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07005999 status = ret;
Eric Laurentaeae3de2010-09-02 11:56:55 -07006000 *(int *)pReplyData = reply;
6001 break;
6002 } else if (reply != NO_ERROR) {
6003 *(int *)pReplyData = reply;
6004 break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07006005 }
6006 mCblk->serverIndex += size;
6007 }
6008 mCblk->serverIndex = 0;
6009 mCblk->clientIndex = 0;
6010 return status;
6011 } else if (cmdCode == EFFECT_CMD_ENABLE) {
Eric Laurentaeae3de2010-09-02 11:56:55 -07006012 *(int *)pReplyData = NO_ERROR;
Mathias Agopian65ab4712010-07-14 17:59:35 -07006013 return enable();
6014 } else if (cmdCode == EFFECT_CMD_DISABLE) {
Eric Laurentaeae3de2010-09-02 11:56:55 -07006015 *(int *)pReplyData = NO_ERROR;
Mathias Agopian65ab4712010-07-14 17:59:35 -07006016 return disable();
6017 }
6018
6019 return mEffect->command(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
6020}
6021
6022sp<IMemory> AudioFlinger::EffectHandle::getCblk() const {
6023 return mCblkMemory;
6024}
6025
6026void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal)
6027{
6028 LOGV("setControl %p control %d", this, hasControl);
6029
6030 mHasControl = hasControl;
6031 if (signal && mEffectClient != 0) {
6032 mEffectClient->controlStatusChanged(hasControl);
6033 }
6034}
6035
Eric Laurent25f43952010-07-28 05:40:18 -07006036void AudioFlinger::EffectHandle::commandExecuted(uint32_t cmdCode,
6037 uint32_t cmdSize,
6038 void *pCmdData,
6039 uint32_t replySize,
6040 void *pReplyData)
Mathias Agopian65ab4712010-07-14 17:59:35 -07006041{
6042 if (mEffectClient != 0) {
6043 mEffectClient->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
6044 }
6045}
6046
6047
6048
6049void AudioFlinger::EffectHandle::setEnabled(bool enabled)
6050{
6051 if (mEffectClient != 0) {
6052 mEffectClient->enableStatusChanged(enabled);
6053 }
6054}
6055
6056status_t AudioFlinger::EffectHandle::onTransact(
6057 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
6058{
6059 return BnEffect::onTransact(code, data, reply, flags);
6060}
6061
6062
6063void AudioFlinger::EffectHandle::dump(char* buffer, size_t size)
6064{
6065 bool locked = tryLock(mCblk->lock);
6066
6067 snprintf(buffer, size, "\t\t\t%05d %05d %01u %01u %05u %05u\n",
6068 (mClient == NULL) ? getpid() : mClient->pid(),
6069 mPriority,
6070 mHasControl,
6071 !locked,
6072 mCblk->clientIndex,
6073 mCblk->serverIndex
6074 );
6075
6076 if (locked) {
6077 mCblk->lock.unlock();
6078 }
6079}
6080
6081#undef LOG_TAG
6082#define LOG_TAG "AudioFlinger::EffectChain"
6083
6084AudioFlinger::EffectChain::EffectChain(const wp<ThreadBase>& wThread,
6085 int sessionId)
Eric Laurentcab11242010-07-15 12:50:15 -07006086 : mThread(wThread), mSessionId(sessionId), mActiveTrackCnt(0), mOwnInBuffer(false),
Eric Laurent8569f0d2010-07-29 23:43:43 -07006087 mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
6088 mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX)
Mathias Agopian65ab4712010-07-14 17:59:35 -07006089{
Eric Laurentde070132010-07-13 04:45:46 -07006090 mStrategy = AudioSystem::getStrategyForStream(AudioSystem::MUSIC);
Mathias Agopian65ab4712010-07-14 17:59:35 -07006091}
6092
6093AudioFlinger::EffectChain::~EffectChain()
6094{
6095 if (mOwnInBuffer) {
6096 delete mInBuffer;
6097 }
6098
6099}
6100
Eric Laurentcab11242010-07-15 12:50:15 -07006101// getEffectFromDesc_l() must be called with PlaybackThread::mLock held
6102sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(effect_descriptor_t *descriptor)
Mathias Agopian65ab4712010-07-14 17:59:35 -07006103{
6104 sp<EffectModule> effect;
6105 size_t size = mEffects.size();
6106
6107 for (size_t i = 0; i < size; i++) {
6108 if (memcmp(&mEffects[i]->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) == 0) {
6109 effect = mEffects[i];
6110 break;
6111 }
6112 }
6113 return effect;
6114}
6115
Eric Laurentcab11242010-07-15 12:50:15 -07006116// getEffectFromId_l() must be called with PlaybackThread::mLock held
6117sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id)
Mathias Agopian65ab4712010-07-14 17:59:35 -07006118{
6119 sp<EffectModule> effect;
6120 size_t size = mEffects.size();
6121
6122 for (size_t i = 0; i < size; i++) {
Eric Laurentde070132010-07-13 04:45:46 -07006123 // by convention, return first effect if id provided is 0 (0 is never a valid id)
6124 if (id == 0 || mEffects[i]->id() == id) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07006125 effect = mEffects[i];
6126 break;
6127 }
6128 }
6129 return effect;
6130}
6131
6132// Must be called with EffectChain::mLock locked
6133void AudioFlinger::EffectChain::process_l()
6134{
6135 size_t size = mEffects.size();
6136 for (size_t i = 0; i < size; i++) {
6137 mEffects[i]->process();
6138 }
6139 for (size_t i = 0; i < size; i++) {
6140 mEffects[i]->updateState();
6141 }
6142 // if no track is active, input buffer must be cleared here as the mixer process
6143 // will not do it
6144 if (mSessionId > 0 && activeTracks() == 0) {
6145 sp<ThreadBase> thread = mThread.promote();
6146 if (thread != 0) {
6147 size_t numSamples = thread->frameCount() * thread->channelCount();
6148 memset(mInBuffer, 0, numSamples * sizeof(int16_t));
6149 }
6150 }
6151}
6152
Eric Laurentcab11242010-07-15 12:50:15 -07006153// addEffect_l() must be called with PlaybackThread::mLock held
Eric Laurentde070132010-07-13 04:45:46 -07006154status_t AudioFlinger::EffectChain::addEffect_l(const sp<EffectModule>& effect)
Mathias Agopian65ab4712010-07-14 17:59:35 -07006155{
6156 effect_descriptor_t desc = effect->desc();
6157 uint32_t insertPref = desc.flags & EFFECT_FLAG_INSERT_MASK;
6158
6159 Mutex::Autolock _l(mLock);
Eric Laurentde070132010-07-13 04:45:46 -07006160 effect->setChain(this);
6161 sp<ThreadBase> thread = mThread.promote();
6162 if (thread == 0) {
6163 return NO_INIT;
6164 }
6165 effect->setThread(thread);
Mathias Agopian65ab4712010-07-14 17:59:35 -07006166
6167 if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
6168 // Auxiliary effects are inserted at the beginning of mEffects vector as
6169 // they are processed first and accumulated in chain input buffer
6170 mEffects.insertAt(effect, 0);
Eric Laurentde070132010-07-13 04:45:46 -07006171
Mathias Agopian65ab4712010-07-14 17:59:35 -07006172 // the input buffer for auxiliary effect contains mono samples in
6173 // 32 bit format. This is to avoid saturation in AudoMixer
6174 // accumulation stage. Saturation is done in EffectModule::process() before
6175 // calling the process in effect engine
6176 size_t numSamples = thread->frameCount();
6177 int32_t *buffer = new int32_t[numSamples];
6178 memset(buffer, 0, numSamples * sizeof(int32_t));
6179 effect->setInBuffer((int16_t *)buffer);
6180 // auxiliary effects output samples to chain input buffer for further processing
6181 // by insert effects
6182 effect->setOutBuffer(mInBuffer);
6183 } else {
6184 // Insert effects are inserted at the end of mEffects vector as they are processed
6185 // after track and auxiliary effects.
6186 // Insert effect order as a function of indicated preference:
6187 // if EFFECT_FLAG_INSERT_EXCLUSIVE, insert in first position or reject if
6188 // another effect is present
6189 // else if EFFECT_FLAG_INSERT_FIRST, insert in first position or after the
6190 // last effect claiming first position
6191 // else if EFFECT_FLAG_INSERT_LAST, insert in last position or before the
6192 // first effect claiming last position
6193 // else if EFFECT_FLAG_INSERT_ANY insert after first or before last
6194 // Reject insertion if an effect with EFFECT_FLAG_INSERT_EXCLUSIVE is
6195 // already present
6196
6197 int size = (int)mEffects.size();
6198 int idx_insert = size;
6199 int idx_insert_first = -1;
6200 int idx_insert_last = -1;
6201
6202 for (int i = 0; i < size; i++) {
6203 effect_descriptor_t d = mEffects[i]->desc();
6204 uint32_t iMode = d.flags & EFFECT_FLAG_TYPE_MASK;
6205 uint32_t iPref = d.flags & EFFECT_FLAG_INSERT_MASK;
6206 if (iMode == EFFECT_FLAG_TYPE_INSERT) {
6207 // check invalid effect chaining combinations
6208 if (insertPref == EFFECT_FLAG_INSERT_EXCLUSIVE ||
6209 iPref == EFFECT_FLAG_INSERT_EXCLUSIVE) {
Eric Laurentcab11242010-07-15 12:50:15 -07006210 LOGW("addEffect_l() could not insert effect %s: exclusive conflict with %s", desc.name, d.name);
Mathias Agopian65ab4712010-07-14 17:59:35 -07006211 return INVALID_OPERATION;
6212 }
6213 // remember position of first insert effect and by default
6214 // select this as insert position for new effect
6215 if (idx_insert == size) {
6216 idx_insert = i;
6217 }
6218 // remember position of last insert effect claiming
6219 // first position
6220 if (iPref == EFFECT_FLAG_INSERT_FIRST) {
6221 idx_insert_first = i;
6222 }
6223 // remember position of first insert effect claiming
6224 // last position
6225 if (iPref == EFFECT_FLAG_INSERT_LAST &&
6226 idx_insert_last == -1) {
6227 idx_insert_last = i;
6228 }
6229 }
6230 }
6231
6232 // modify idx_insert from first position if needed
6233 if (insertPref == EFFECT_FLAG_INSERT_LAST) {
6234 if (idx_insert_last != -1) {
6235 idx_insert = idx_insert_last;
6236 } else {
6237 idx_insert = size;
6238 }
6239 } else {
6240 if (idx_insert_first != -1) {
6241 idx_insert = idx_insert_first + 1;
6242 }
6243 }
6244
6245 // always read samples from chain input buffer
6246 effect->setInBuffer(mInBuffer);
6247
6248 // if last effect in the chain, output samples to chain
6249 // output buffer, otherwise to chain input buffer
6250 if (idx_insert == size) {
6251 if (idx_insert != 0) {
6252 mEffects[idx_insert-1]->setOutBuffer(mInBuffer);
6253 mEffects[idx_insert-1]->configure();
6254 }
6255 effect->setOutBuffer(mOutBuffer);
6256 } else {
6257 effect->setOutBuffer(mInBuffer);
6258 }
6259 mEffects.insertAt(effect, idx_insert);
Mathias Agopian65ab4712010-07-14 17:59:35 -07006260
Eric Laurentcab11242010-07-15 12:50:15 -07006261 LOGV("addEffect_l() effect %p, added in chain %p at rank %d", effect.get(), this, idx_insert);
Mathias Agopian65ab4712010-07-14 17:59:35 -07006262 }
6263 effect->configure();
6264 return NO_ERROR;
6265}
6266
Eric Laurentcab11242010-07-15 12:50:15 -07006267// removeEffect_l() must be called with PlaybackThread::mLock held
6268size_t AudioFlinger::EffectChain::removeEffect_l(const sp<EffectModule>& effect)
Mathias Agopian65ab4712010-07-14 17:59:35 -07006269{
6270 Mutex::Autolock _l(mLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -07006271 int size = (int)mEffects.size();
6272 int i;
6273 uint32_t type = effect->desc().flags & EFFECT_FLAG_TYPE_MASK;
6274
6275 for (i = 0; i < size; i++) {
6276 if (effect == mEffects[i]) {
6277 if (type == EFFECT_FLAG_TYPE_AUXILIARY) {
6278 delete[] effect->inBuffer();
6279 } else {
6280 if (i == size - 1 && i != 0) {
6281 mEffects[i - 1]->setOutBuffer(mOutBuffer);
6282 mEffects[i - 1]->configure();
6283 }
6284 }
6285 mEffects.removeAt(i);
Eric Laurentcab11242010-07-15 12:50:15 -07006286 LOGV("removeEffect_l() effect %p, removed from chain %p at rank %d", effect.get(), this, i);
Mathias Agopian65ab4712010-07-14 17:59:35 -07006287 break;
6288 }
6289 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07006290
6291 return mEffects.size();
6292}
6293
Eric Laurentcab11242010-07-15 12:50:15 -07006294// setDevice_l() must be called with PlaybackThread::mLock held
6295void AudioFlinger::EffectChain::setDevice_l(uint32_t device)
Mathias Agopian65ab4712010-07-14 17:59:35 -07006296{
6297 size_t size = mEffects.size();
6298 for (size_t i = 0; i < size; i++) {
6299 mEffects[i]->setDevice(device);
6300 }
6301}
6302
Eric Laurentcab11242010-07-15 12:50:15 -07006303// setMode_l() must be called with PlaybackThread::mLock held
6304void AudioFlinger::EffectChain::setMode_l(uint32_t mode)
Mathias Agopian65ab4712010-07-14 17:59:35 -07006305{
6306 size_t size = mEffects.size();
6307 for (size_t i = 0; i < size; i++) {
6308 mEffects[i]->setMode(mode);
6309 }
6310}
6311
Eric Laurentcab11242010-07-15 12:50:15 -07006312// setVolume_l() must be called with PlaybackThread::mLock held
6313bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right)
Mathias Agopian65ab4712010-07-14 17:59:35 -07006314{
6315 uint32_t newLeft = *left;
6316 uint32_t newRight = *right;
6317 bool hasControl = false;
Eric Laurentcab11242010-07-15 12:50:15 -07006318 int ctrlIdx = -1;
6319 size_t size = mEffects.size();
Mathias Agopian65ab4712010-07-14 17:59:35 -07006320
Eric Laurentcab11242010-07-15 12:50:15 -07006321 // first update volume controller
6322 for (size_t i = size; i > 0; i--) {
Eric Laurent8f45bd72010-08-31 13:50:07 -07006323 if (mEffects[i - 1]->isProcessEnabled() &&
Eric Laurentcab11242010-07-15 12:50:15 -07006324 (mEffects[i - 1]->desc().flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL) {
6325 ctrlIdx = i - 1;
Eric Laurentf997cab2010-07-19 06:24:46 -07006326 hasControl = true;
Eric Laurentcab11242010-07-15 12:50:15 -07006327 break;
6328 }
6329 }
6330
6331 if (ctrlIdx == mVolumeCtrlIdx && *left == mLeftVolume && *right == mRightVolume) {
Eric Laurentf997cab2010-07-19 06:24:46 -07006332 if (hasControl) {
6333 *left = mNewLeftVolume;
6334 *right = mNewRightVolume;
6335 }
6336 return hasControl;
Eric Laurentcab11242010-07-15 12:50:15 -07006337 }
6338
6339 mVolumeCtrlIdx = ctrlIdx;
Eric Laurentf997cab2010-07-19 06:24:46 -07006340 mLeftVolume = newLeft;
6341 mRightVolume = newRight;
Eric Laurentcab11242010-07-15 12:50:15 -07006342
6343 // second get volume update from volume controller
6344 if (ctrlIdx >= 0) {
6345 mEffects[ctrlIdx]->setVolume(&newLeft, &newRight, true);
Eric Laurentf997cab2010-07-19 06:24:46 -07006346 mNewLeftVolume = newLeft;
6347 mNewRightVolume = newRight;
Mathias Agopian65ab4712010-07-14 17:59:35 -07006348 }
6349 // then indicate volume to all other effects in chain.
6350 // Pass altered volume to effects before volume controller
6351 // and requested volume to effects after controller
6352 uint32_t lVol = newLeft;
6353 uint32_t rVol = newRight;
Eric Laurentcab11242010-07-15 12:50:15 -07006354
Mathias Agopian65ab4712010-07-14 17:59:35 -07006355 for (size_t i = 0; i < size; i++) {
Eric Laurentcab11242010-07-15 12:50:15 -07006356 if ((int)i == ctrlIdx) continue;
6357 // this also works for ctrlIdx == -1 when there is no volume controller
6358 if ((int)i > ctrlIdx) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07006359 lVol = *left;
6360 rVol = *right;
6361 }
6362 mEffects[i]->setVolume(&lVol, &rVol, false);
6363 }
6364 *left = newLeft;
6365 *right = newRight;
6366
6367 return hasControl;
6368}
6369
Mathias Agopian65ab4712010-07-14 17:59:35 -07006370status_t AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args)
6371{
6372 const size_t SIZE = 256;
6373 char buffer[SIZE];
6374 String8 result;
6375
6376 snprintf(buffer, SIZE, "Effects for session %d:\n", mSessionId);
6377 result.append(buffer);
6378
6379 bool locked = tryLock(mLock);
6380 // failed to lock - AudioFlinger is probably deadlocked
6381 if (!locked) {
6382 result.append("\tCould not lock mutex:\n");
6383 }
6384
Eric Laurentcab11242010-07-15 12:50:15 -07006385 result.append("\tNum fx In buffer Out buffer Active tracks:\n");
6386 snprintf(buffer, SIZE, "\t%02d 0x%08x 0x%08x %d\n",
Mathias Agopian65ab4712010-07-14 17:59:35 -07006387 mEffects.size(),
6388 (uint32_t)mInBuffer,
6389 (uint32_t)mOutBuffer,
Mathias Agopian65ab4712010-07-14 17:59:35 -07006390 mActiveTrackCnt);
6391 result.append(buffer);
6392 write(fd, result.string(), result.size());
6393
6394 for (size_t i = 0; i < mEffects.size(); ++i) {
6395 sp<EffectModule> effect = mEffects[i];
6396 if (effect != 0) {
6397 effect->dump(fd, args);
6398 }
6399 }
6400
6401 if (locked) {
6402 mLock.unlock();
6403 }
6404
6405 return NO_ERROR;
6406}
6407
6408#undef LOG_TAG
6409#define LOG_TAG "AudioFlinger"
6410
6411// ----------------------------------------------------------------------------
6412
6413status_t AudioFlinger::onTransact(
6414 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
6415{
6416 return BnAudioFlinger::onTransact(code, data, reply, flags);
6417}
6418
Mathias Agopian65ab4712010-07-14 17:59:35 -07006419}; // namespace android