1 /*
2 **
3 ** Copyright 2008, 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 //#define LOG_NDEBUG 0
19 #define LOG_TAG "AudioRecord"
20
21 #include <inttypes.h>
22 #include <sys/resource.h>
23
24 #include <binder/IPCThreadState.h>
25 #include <media/AudioRecord.h>
26 #include <utils/Log.h>
27 #include <private/media/AudioTrackShared.h>
28 #include <media/IAudioFlinger.h>
29
30 #define WAIT_PERIOD_MS 10
31
32 namespace android {
33 // ---------------------------------------------------------------------------
34
35 // static
getMinFrameCount(size_t * frameCount,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask)36 status_t AudioRecord::getMinFrameCount(
37 size_t* frameCount,
38 uint32_t sampleRate,
39 audio_format_t format,
40 audio_channel_mask_t channelMask)
41 {
42 if (frameCount == NULL) {
43 return BAD_VALUE;
44 }
45
46 size_t size;
47 status_t status = AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size);
48 if (status != NO_ERROR) {
49 ALOGE("AudioSystem could not query the input buffer size for sampleRate %u, format %#x, "
50 "channelMask %#x; status %d", sampleRate, format, channelMask, status);
51 return status;
52 }
53
54 // We double the size of input buffer for ping pong use of record buffer.
55 // Assumes audio_is_linear_pcm(format)
56 if ((*frameCount = (size * 2) / (audio_channel_count_from_in_mask(channelMask) *
57 audio_bytes_per_sample(format))) == 0) {
58 ALOGE("Unsupported configuration: sampleRate %u, format %#x, channelMask %#x",
59 sampleRate, format, channelMask);
60 return BAD_VALUE;
61 }
62
63 return NO_ERROR;
64 }
65
66 // ---------------------------------------------------------------------------
67
AudioRecord()68 AudioRecord::AudioRecord()
69 : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE),
70 mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
71 {
72 }
73
AudioRecord(audio_source_t inputSource,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,size_t frameCount,callback_t cbf,void * user,uint32_t notificationFrames,int sessionId,transfer_type transferType,audio_input_flags_t flags)74 AudioRecord::AudioRecord(
75 audio_source_t inputSource,
76 uint32_t sampleRate,
77 audio_format_t format,
78 audio_channel_mask_t channelMask,
79 size_t frameCount,
80 callback_t cbf,
81 void* user,
82 uint32_t notificationFrames,
83 int sessionId,
84 transfer_type transferType,
85 audio_input_flags_t flags)
86 : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE),
87 mPreviousPriority(ANDROID_PRIORITY_NORMAL),
88 mPreviousSchedulingGroup(SP_DEFAULT),
89 mProxy(NULL)
90 {
91 mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
92 notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags);
93 }
94
~AudioRecord()95 AudioRecord::~AudioRecord()
96 {
97 if (mStatus == NO_ERROR) {
98 // Make sure that callback function exits in the case where
99 // it is looping on buffer empty condition in obtainBuffer().
100 // Otherwise the callback thread will never exit.
101 stop();
102 if (mAudioRecordThread != 0) {
103 mProxy->interrupt();
104 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h
105 mAudioRecordThread->requestExitAndWait();
106 mAudioRecordThread.clear();
107 }
108 mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this);
109 mAudioRecord.clear();
110 mCblkMemory.clear();
111 mBufferMemory.clear();
112 IPCThreadState::self()->flushCommands();
113 AudioSystem::releaseAudioSessionId(mSessionId, -1);
114 }
115 }
116
set(audio_source_t inputSource,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,size_t frameCount,callback_t cbf,void * user,uint32_t notificationFrames,bool threadCanCallJava,int sessionId,transfer_type transferType,audio_input_flags_t flags)117 status_t AudioRecord::set(
118 audio_source_t inputSource,
119 uint32_t sampleRate,
120 audio_format_t format,
121 audio_channel_mask_t channelMask,
122 size_t frameCount,
123 callback_t cbf,
124 void* user,
125 uint32_t notificationFrames,
126 bool threadCanCallJava,
127 int sessionId,
128 transfer_type transferType,
129 audio_input_flags_t flags)
130 {
131 ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
132 "notificationFrames %u, sessionId %d, transferType %d, flags %#x",
133 inputSource, sampleRate, format, channelMask, frameCount, notificationFrames,
134 sessionId, transferType, flags);
135
136 switch (transferType) {
137 case TRANSFER_DEFAULT:
138 if (cbf == NULL || threadCanCallJava) {
139 transferType = TRANSFER_SYNC;
140 } else {
141 transferType = TRANSFER_CALLBACK;
142 }
143 break;
144 case TRANSFER_CALLBACK:
145 if (cbf == NULL) {
146 ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL");
147 return BAD_VALUE;
148 }
149 break;
150 case TRANSFER_OBTAIN:
151 case TRANSFER_SYNC:
152 break;
153 default:
154 ALOGE("Invalid transfer type %d", transferType);
155 return BAD_VALUE;
156 }
157 mTransfer = transferType;
158
159 AutoMutex lock(mLock);
160
161 // invariant that mAudioRecord != 0 is true only after set() returns successfully
162 if (mAudioRecord != 0) {
163 ALOGE("Track already in use");
164 return INVALID_OPERATION;
165 }
166
167 // handle default values first.
168 if (inputSource == AUDIO_SOURCE_DEFAULT) {
169 inputSource = AUDIO_SOURCE_MIC;
170 }
171 mInputSource = inputSource;
172
173 if (sampleRate == 0) {
174 ALOGE("Invalid sample rate %u", sampleRate);
175 return BAD_VALUE;
176 }
177 mSampleRate = sampleRate;
178
179 // these below should probably come from the audioFlinger too...
180 if (format == AUDIO_FORMAT_DEFAULT) {
181 format = AUDIO_FORMAT_PCM_16_BIT;
182 }
183
184 // validate parameters
185 if (!audio_is_valid_format(format)) {
186 ALOGE("Invalid format %#x", format);
187 return BAD_VALUE;
188 }
189 // Temporary restriction: AudioFlinger currently supports 16-bit PCM only
190 if (format != AUDIO_FORMAT_PCM_16_BIT) {
191 ALOGE("Format %#x is not supported", format);
192 return BAD_VALUE;
193 }
194 mFormat = format;
195
196 if (!audio_is_input_channel(channelMask)) {
197 ALOGE("Invalid channel mask %#x", channelMask);
198 return BAD_VALUE;
199 }
200 mChannelMask = channelMask;
201 uint32_t channelCount = audio_channel_count_from_in_mask(channelMask);
202 mChannelCount = channelCount;
203
204 if (audio_is_linear_pcm(format)) {
205 mFrameSize = channelCount * audio_bytes_per_sample(format);
206 } else {
207 mFrameSize = sizeof(uint8_t);
208 }
209
210 // mFrameCount is initialized in openRecord_l
211 mReqFrameCount = frameCount;
212
213 mNotificationFramesReq = notificationFrames;
214 // mNotificationFramesAct is initialized in openRecord_l
215
216 if (sessionId == AUDIO_SESSION_ALLOCATE) {
217 mSessionId = AudioSystem::newAudioUniqueId();
218 } else {
219 mSessionId = sessionId;
220 }
221 ALOGV("set(): mSessionId %d", mSessionId);
222
223 mFlags = flags;
224 mCbf = cbf;
225
226 if (cbf != NULL) {
227 mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava);
228 mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
229 }
230
231 // create the IAudioRecord
232 status_t status = openRecord_l(0 /*epoch*/);
233
234 if (status != NO_ERROR) {
235 if (mAudioRecordThread != 0) {
236 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h
237 mAudioRecordThread->requestExitAndWait();
238 mAudioRecordThread.clear();
239 }
240 return status;
241 }
242
243 mStatus = NO_ERROR;
244 mActive = false;
245 mUserData = user;
246 // TODO: add audio hardware input latency here
247 mLatency = (1000*mFrameCount) / sampleRate;
248 mMarkerPosition = 0;
249 mMarkerReached = false;
250 mNewPosition = 0;
251 mUpdatePeriod = 0;
252 AudioSystem::acquireAudioSessionId(mSessionId, -1);
253 mSequence = 1;
254 mObservedSequence = mSequence;
255 mInOverrun = false;
256
257 return NO_ERROR;
258 }
259
260 // -------------------------------------------------------------------------
261
start(AudioSystem::sync_event_t event,int triggerSession)262 status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession)
263 {
264 ALOGV("start, sync event %d trigger session %d", event, triggerSession);
265
266 AutoMutex lock(mLock);
267 if (mActive) {
268 return NO_ERROR;
269 }
270
271 // reset current position as seen by client to 0
272 mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition());
273 // force refresh of remaining frames by processAudioBuffer() as last
274 // read before stop could be partial.
275 mRefreshRemaining = true;
276
277 mNewPosition = mProxy->getPosition() + mUpdatePeriod;
278 int32_t flags = android_atomic_acquire_load(&mCblk->mFlags);
279
280 status_t status = NO_ERROR;
281 if (!(flags & CBLK_INVALID)) {
282 ALOGV("mAudioRecord->start()");
283 status = mAudioRecord->start(event, triggerSession);
284 if (status == DEAD_OBJECT) {
285 flags |= CBLK_INVALID;
286 }
287 }
288 if (flags & CBLK_INVALID) {
289 status = restoreRecord_l("start");
290 }
291
292 if (status != NO_ERROR) {
293 ALOGE("start() status %d", status);
294 } else {
295 mActive = true;
296 sp<AudioRecordThread> t = mAudioRecordThread;
297 if (t != 0) {
298 t->resume();
299 } else {
300 mPreviousPriority = getpriority(PRIO_PROCESS, 0);
301 get_sched_policy(0, &mPreviousSchedulingGroup);
302 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
303 }
304 }
305
306 return status;
307 }
308
stop()309 void AudioRecord::stop()
310 {
311 AutoMutex lock(mLock);
312 if (!mActive) {
313 return;
314 }
315
316 mActive = false;
317 mProxy->interrupt();
318 mAudioRecord->stop();
319 // the record head position will reset to 0, so if a marker is set, we need
320 // to activate it again
321 mMarkerReached = false;
322 sp<AudioRecordThread> t = mAudioRecordThread;
323 if (t != 0) {
324 t->pause();
325 } else {
326 setpriority(PRIO_PROCESS, 0, mPreviousPriority);
327 set_sched_policy(0, mPreviousSchedulingGroup);
328 }
329 }
330
stopped() const331 bool AudioRecord::stopped() const
332 {
333 AutoMutex lock(mLock);
334 return !mActive;
335 }
336
setMarkerPosition(uint32_t marker)337 status_t AudioRecord::setMarkerPosition(uint32_t marker)
338 {
339 // The only purpose of setting marker position is to get a callback
340 if (mCbf == NULL) {
341 return INVALID_OPERATION;
342 }
343
344 AutoMutex lock(mLock);
345 mMarkerPosition = marker;
346 mMarkerReached = false;
347
348 return NO_ERROR;
349 }
350
getMarkerPosition(uint32_t * marker) const351 status_t AudioRecord::getMarkerPosition(uint32_t *marker) const
352 {
353 if (marker == NULL) {
354 return BAD_VALUE;
355 }
356
357 AutoMutex lock(mLock);
358 *marker = mMarkerPosition;
359
360 return NO_ERROR;
361 }
362
setPositionUpdatePeriod(uint32_t updatePeriod)363 status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
364 {
365 // The only purpose of setting position update period is to get a callback
366 if (mCbf == NULL) {
367 return INVALID_OPERATION;
368 }
369
370 AutoMutex lock(mLock);
371 mNewPosition = mProxy->getPosition() + updatePeriod;
372 mUpdatePeriod = updatePeriod;
373
374 return NO_ERROR;
375 }
376
getPositionUpdatePeriod(uint32_t * updatePeriod) const377 status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const
378 {
379 if (updatePeriod == NULL) {
380 return BAD_VALUE;
381 }
382
383 AutoMutex lock(mLock);
384 *updatePeriod = mUpdatePeriod;
385
386 return NO_ERROR;
387 }
388
getPosition(uint32_t * position) const389 status_t AudioRecord::getPosition(uint32_t *position) const
390 {
391 if (position == NULL) {
392 return BAD_VALUE;
393 }
394
395 AutoMutex lock(mLock);
396 *position = mProxy->getPosition();
397
398 return NO_ERROR;
399 }
400
getInputFramesLost() const401 uint32_t AudioRecord::getInputFramesLost() const
402 {
403 // no need to check mActive, because if inactive this will return 0, which is what we want
404 return AudioSystem::getInputFramesLost(getInput());
405 }
406
407 // -------------------------------------------------------------------------
408
409 // must be called with mLock held
openRecord_l(size_t epoch)410 status_t AudioRecord::openRecord_l(size_t epoch)
411 {
412 status_t status;
413 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
414 if (audioFlinger == 0) {
415 ALOGE("Could not get audioflinger");
416 return NO_INIT;
417 }
418
419 // Fast tracks must be at the primary _output_ [sic] sampling rate,
420 // because there is currently no concept of a primary input sampling rate
421 uint32_t afSampleRate = AudioSystem::getPrimaryOutputSamplingRate();
422 if (afSampleRate == 0) {
423 ALOGW("getPrimaryOutputSamplingRate failed");
424 }
425
426 // Client can only express a preference for FAST. Server will perform additional tests.
427 if ((mFlags & AUDIO_INPUT_FLAG_FAST) && !(
428 // use case: callback transfer mode
429 (mTransfer == TRANSFER_CALLBACK) &&
430 // matching sample rate
431 (mSampleRate == afSampleRate))) {
432 ALOGW("AUDIO_INPUT_FLAG_FAST denied by client");
433 // once denied, do not request again if IAudioRecord is re-created
434 mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST);
435 }
436
437 IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT;
438
439 pid_t tid = -1;
440 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
441 trackFlags |= IAudioFlinger::TRACK_FAST;
442 if (mAudioRecordThread != 0) {
443 tid = mAudioRecordThread->getTid();
444 }
445 }
446
447 audio_io_handle_t input = AudioSystem::getInput(mInputSource, mSampleRate, mFormat,
448 mChannelMask, mSessionId, mFlags);
449 if (input == AUDIO_IO_HANDLE_NONE) {
450 ALOGE("Could not get audio input for record source %d, sample rate %u, format %#x, "
451 "channel mask %#x, session %d, flags %#x",
452 mInputSource, mSampleRate, mFormat, mChannelMask, mSessionId, mFlags);
453 return BAD_VALUE;
454 }
455 {
456 // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
457 // we must release it ourselves if anything goes wrong.
458
459 size_t frameCount = mReqFrameCount;
460 size_t temp = frameCount; // temp may be replaced by a revised value of frameCount,
461 // but we will still need the original value also
462 int originalSessionId = mSessionId;
463
464 // The notification frame count is the period between callbacks, as suggested by the server.
465 size_t notificationFrames = mNotificationFramesReq;
466
467 sp<IMemory> iMem; // for cblk
468 sp<IMemory> bufferMem;
469 sp<IAudioRecord> record = audioFlinger->openRecord(input,
470 mSampleRate, mFormat,
471 mChannelMask,
472 &temp,
473 &trackFlags,
474 tid,
475 &mSessionId,
476 ¬ificationFrames,
477 iMem,
478 bufferMem,
479 &status);
480 ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId,
481 "session ID changed from %d to %d", originalSessionId, mSessionId);
482
483 if (status != NO_ERROR) {
484 ALOGE("AudioFlinger could not create record track, status: %d", status);
485 goto release;
486 }
487 ALOG_ASSERT(record != 0);
488
489 // AudioFlinger now owns the reference to the I/O handle,
490 // so we are no longer responsible for releasing it.
491
492 if (iMem == 0) {
493 ALOGE("Could not get control block");
494 return NO_INIT;
495 }
496 void *iMemPointer = iMem->pointer();
497 if (iMemPointer == NULL) {
498 ALOGE("Could not get control block pointer");
499 return NO_INIT;
500 }
501 audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer);
502
503 // Starting address of buffers in shared memory.
504 // The buffers are either immediately after the control block,
505 // or in a separate area at discretion of server.
506 void *buffers;
507 if (bufferMem == 0) {
508 buffers = cblk + 1;
509 } else {
510 buffers = bufferMem->pointer();
511 if (buffers == NULL) {
512 ALOGE("Could not get buffer pointer");
513 return NO_INIT;
514 }
515 }
516
517 // invariant that mAudioRecord != 0 is true only after set() returns successfully
518 if (mAudioRecord != 0) {
519 mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this);
520 mDeathNotifier.clear();
521 }
522 mAudioRecord = record;
523 mCblkMemory = iMem;
524 mBufferMemory = bufferMem;
525 IPCThreadState::self()->flushCommands();
526
527 mCblk = cblk;
528 // note that temp is the (possibly revised) value of frameCount
529 if (temp < frameCount || (frameCount == 0 && temp == 0)) {
530 ALOGW("Requested frameCount %zu but received frameCount %zu", frameCount, temp);
531 }
532 frameCount = temp;
533
534 mAwaitBoost = false;
535 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
536 if (trackFlags & IAudioFlinger::TRACK_FAST) {
537 ALOGV("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu", frameCount);
538 mAwaitBoost = true;
539 } else {
540 ALOGV("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %zu", frameCount);
541 // once denied, do not request again if IAudioRecord is re-created
542 mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST);
543 }
544 }
545
546 // Make sure that application is notified with sufficient margin before overrun
547 if (notificationFrames == 0 || notificationFrames > frameCount) {
548 ALOGW("Received notificationFrames %zu for frameCount %zu", notificationFrames, frameCount);
549 }
550 mNotificationFramesAct = notificationFrames;
551
552 // We retain a copy of the I/O handle, but don't own the reference
553 mInput = input;
554 mRefreshRemaining = true;
555
556 mFrameCount = frameCount;
557 // If IAudioRecord is re-created, don't let the requested frameCount
558 // decrease. This can confuse clients that cache frameCount().
559 if (frameCount > mReqFrameCount) {
560 mReqFrameCount = frameCount;
561 }
562
563 // update proxy
564 mProxy = new AudioRecordClientProxy(cblk, buffers, mFrameCount, mFrameSize);
565 mProxy->setEpoch(epoch);
566 mProxy->setMinimum(mNotificationFramesAct);
567
568 mDeathNotifier = new DeathNotifier(this);
569 mAudioRecord->asBinder()->linkToDeath(mDeathNotifier, this);
570
571 return NO_ERROR;
572 }
573
574 release:
575 AudioSystem::releaseInput(input, (audio_session_t)mSessionId);
576 if (status == NO_ERROR) {
577 status = NO_INIT;
578 }
579 return status;
580 }
581
obtainBuffer(Buffer * audioBuffer,int32_t waitCount)582 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
583 {
584 if (audioBuffer == NULL) {
585 return BAD_VALUE;
586 }
587 if (mTransfer != TRANSFER_OBTAIN) {
588 audioBuffer->frameCount = 0;
589 audioBuffer->size = 0;
590 audioBuffer->raw = NULL;
591 return INVALID_OPERATION;
592 }
593
594 const struct timespec *requested;
595 struct timespec timeout;
596 if (waitCount == -1) {
597 requested = &ClientProxy::kForever;
598 } else if (waitCount == 0) {
599 requested = &ClientProxy::kNonBlocking;
600 } else if (waitCount > 0) {
601 long long ms = WAIT_PERIOD_MS * (long long) waitCount;
602 timeout.tv_sec = ms / 1000;
603 timeout.tv_nsec = (int) (ms % 1000) * 1000000;
604 requested = &timeout;
605 } else {
606 ALOGE("%s invalid waitCount %d", __func__, waitCount);
607 requested = NULL;
608 }
609 return obtainBuffer(audioBuffer, requested);
610 }
611
obtainBuffer(Buffer * audioBuffer,const struct timespec * requested,struct timespec * elapsed,size_t * nonContig)612 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *requested,
613 struct timespec *elapsed, size_t *nonContig)
614 {
615 // previous and new IAudioRecord sequence numbers are used to detect track re-creation
616 uint32_t oldSequence = 0;
617 uint32_t newSequence;
618
619 Proxy::Buffer buffer;
620 status_t status = NO_ERROR;
621
622 static const int32_t kMaxTries = 5;
623 int32_t tryCounter = kMaxTries;
624
625 do {
626 // obtainBuffer() is called with mutex unlocked, so keep extra references to these fields to
627 // keep them from going away if another thread re-creates the track during obtainBuffer()
628 sp<AudioRecordClientProxy> proxy;
629 sp<IMemory> iMem;
630 sp<IMemory> bufferMem;
631 {
632 // start of lock scope
633 AutoMutex lock(mLock);
634
635 newSequence = mSequence;
636 // did previous obtainBuffer() fail due to media server death or voluntary invalidation?
637 if (status == DEAD_OBJECT) {
638 // re-create track, unless someone else has already done so
639 if (newSequence == oldSequence) {
640 status = restoreRecord_l("obtainBuffer");
641 if (status != NO_ERROR) {
642 buffer.mFrameCount = 0;
643 buffer.mRaw = NULL;
644 buffer.mNonContig = 0;
645 break;
646 }
647 }
648 }
649 oldSequence = newSequence;
650
651 // Keep the extra references
652 proxy = mProxy;
653 iMem = mCblkMemory;
654 bufferMem = mBufferMemory;
655
656 // Non-blocking if track is stopped
657 if (!mActive) {
658 requested = &ClientProxy::kNonBlocking;
659 }
660
661 } // end of lock scope
662
663 buffer.mFrameCount = audioBuffer->frameCount;
664 // FIXME starts the requested timeout and elapsed over from scratch
665 status = proxy->obtainBuffer(&buffer, requested, elapsed);
666
667 } while ((status == DEAD_OBJECT) && (tryCounter-- > 0));
668
669 audioBuffer->frameCount = buffer.mFrameCount;
670 audioBuffer->size = buffer.mFrameCount * mFrameSize;
671 audioBuffer->raw = buffer.mRaw;
672 if (nonContig != NULL) {
673 *nonContig = buffer.mNonContig;
674 }
675 return status;
676 }
677
releaseBuffer(Buffer * audioBuffer)678 void AudioRecord::releaseBuffer(Buffer* audioBuffer)
679 {
680 // all TRANSFER_* are valid
681
682 size_t stepCount = audioBuffer->size / mFrameSize;
683 if (stepCount == 0) {
684 return;
685 }
686
687 Proxy::Buffer buffer;
688 buffer.mFrameCount = stepCount;
689 buffer.mRaw = audioBuffer->raw;
690
691 AutoMutex lock(mLock);
692 mInOverrun = false;
693 mProxy->releaseBuffer(&buffer);
694
695 // the server does not automatically disable recorder on overrun, so no need to restart
696 }
697
getInput() const698 audio_io_handle_t AudioRecord::getInput() const
699 {
700 AutoMutex lock(mLock);
701 return mInput;
702 }
703
704 // -------------------------------------------------------------------------
705
read(void * buffer,size_t userSize)706 ssize_t AudioRecord::read(void* buffer, size_t userSize)
707 {
708 if (mTransfer != TRANSFER_SYNC) {
709 return INVALID_OPERATION;
710 }
711
712 if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
713 // sanity-check. user is most-likely passing an error code, and it would
714 // make the return value ambiguous (actualSize vs error).
715 ALOGE("AudioRecord::read(buffer=%p, size=%zu (%zu)", buffer, userSize, userSize);
716 return BAD_VALUE;
717 }
718
719 ssize_t read = 0;
720 Buffer audioBuffer;
721
722 while (userSize >= mFrameSize) {
723 audioBuffer.frameCount = userSize / mFrameSize;
724
725 status_t err = obtainBuffer(&audioBuffer, &ClientProxy::kForever);
726 if (err < 0) {
727 if (read > 0) {
728 break;
729 }
730 return ssize_t(err);
731 }
732
733 size_t bytesRead = audioBuffer.size;
734 memcpy(buffer, audioBuffer.i8, bytesRead);
735 buffer = ((char *) buffer) + bytesRead;
736 userSize -= bytesRead;
737 read += bytesRead;
738
739 releaseBuffer(&audioBuffer);
740 }
741
742 return read;
743 }
744
745 // -------------------------------------------------------------------------
746
processAudioBuffer()747 nsecs_t AudioRecord::processAudioBuffer()
748 {
749 mLock.lock();
750 if (mAwaitBoost) {
751 mAwaitBoost = false;
752 mLock.unlock();
753 static const int32_t kMaxTries = 5;
754 int32_t tryCounter = kMaxTries;
755 uint32_t pollUs = 10000;
756 do {
757 int policy = sched_getscheduler(0);
758 if (policy == SCHED_FIFO || policy == SCHED_RR) {
759 break;
760 }
761 usleep(pollUs);
762 pollUs <<= 1;
763 } while (tryCounter-- > 0);
764 if (tryCounter < 0) {
765 ALOGE("did not receive expected priority boost on time");
766 }
767 // Run again immediately
768 return 0;
769 }
770
771 // Can only reference mCblk while locked
772 int32_t flags = android_atomic_and(~CBLK_OVERRUN, &mCblk->mFlags);
773
774 // Check for track invalidation
775 if (flags & CBLK_INVALID) {
776 (void) restoreRecord_l("processAudioBuffer");
777 mLock.unlock();
778 // Run again immediately, but with a new IAudioRecord
779 return 0;
780 }
781
782 bool active = mActive;
783
784 // Manage overrun callback, must be done under lock to avoid race with releaseBuffer()
785 bool newOverrun = false;
786 if (flags & CBLK_OVERRUN) {
787 if (!mInOverrun) {
788 mInOverrun = true;
789 newOverrun = true;
790 }
791 }
792
793 // Get current position of server
794 size_t position = mProxy->getPosition();
795
796 // Manage marker callback
797 bool markerReached = false;
798 size_t markerPosition = mMarkerPosition;
799 // FIXME fails for wraparound, need 64 bits
800 if (!mMarkerReached && (markerPosition > 0) && (position >= markerPosition)) {
801 mMarkerReached = markerReached = true;
802 }
803
804 // Determine the number of new position callback(s) that will be needed, while locked
805 size_t newPosCount = 0;
806 size_t newPosition = mNewPosition;
807 uint32_t updatePeriod = mUpdatePeriod;
808 // FIXME fails for wraparound, need 64 bits
809 if (updatePeriod > 0 && position >= newPosition) {
810 newPosCount = ((position - newPosition) / updatePeriod) + 1;
811 mNewPosition += updatePeriod * newPosCount;
812 }
813
814 // Cache other fields that will be needed soon
815 uint32_t notificationFrames = mNotificationFramesAct;
816 if (mRefreshRemaining) {
817 mRefreshRemaining = false;
818 mRemainingFrames = notificationFrames;
819 mRetryOnPartialBuffer = false;
820 }
821 size_t misalignment = mProxy->getMisalignment();
822 uint32_t sequence = mSequence;
823
824 // These fields don't need to be cached, because they are assigned only by set():
825 // mTransfer, mCbf, mUserData, mSampleRate, mFrameSize
826
827 mLock.unlock();
828
829 // perform callbacks while unlocked
830 if (newOverrun) {
831 mCbf(EVENT_OVERRUN, mUserData, NULL);
832 }
833 if (markerReached) {
834 mCbf(EVENT_MARKER, mUserData, &markerPosition);
835 }
836 while (newPosCount > 0) {
837 size_t temp = newPosition;
838 mCbf(EVENT_NEW_POS, mUserData, &temp);
839 newPosition += updatePeriod;
840 newPosCount--;
841 }
842 if (mObservedSequence != sequence) {
843 mObservedSequence = sequence;
844 mCbf(EVENT_NEW_IAUDIORECORD, mUserData, NULL);
845 }
846
847 // if inactive, then don't run me again until re-started
848 if (!active) {
849 return NS_INACTIVE;
850 }
851
852 // Compute the estimated time until the next timed event (position, markers)
853 uint32_t minFrames = ~0;
854 if (!markerReached && position < markerPosition) {
855 minFrames = markerPosition - position;
856 }
857 if (updatePeriod > 0 && updatePeriod < minFrames) {
858 minFrames = updatePeriod;
859 }
860
861 // If > 0, poll periodically to recover from a stuck server. A good value is 2.
862 static const uint32_t kPoll = 0;
863 if (kPoll > 0 && mTransfer == TRANSFER_CALLBACK && kPoll * notificationFrames < minFrames) {
864 minFrames = kPoll * notificationFrames;
865 }
866
867 // Convert frame units to time units
868 nsecs_t ns = NS_WHENEVER;
869 if (minFrames != (uint32_t) ~0) {
870 // This "fudge factor" avoids soaking CPU, and compensates for late progress by server
871 static const nsecs_t kFudgeNs = 10000000LL; // 10 ms
872 ns = ((minFrames * 1000000000LL) / mSampleRate) + kFudgeNs;
873 }
874
875 // If not supplying data by EVENT_MORE_DATA, then we're done
876 if (mTransfer != TRANSFER_CALLBACK) {
877 return ns;
878 }
879
880 struct timespec timeout;
881 const struct timespec *requested = &ClientProxy::kForever;
882 if (ns != NS_WHENEVER) {
883 timeout.tv_sec = ns / 1000000000LL;
884 timeout.tv_nsec = ns % 1000000000LL;
885 ALOGV("timeout %ld.%03d", timeout.tv_sec, (int) timeout.tv_nsec / 1000000);
886 requested = &timeout;
887 }
888
889 while (mRemainingFrames > 0) {
890
891 Buffer audioBuffer;
892 audioBuffer.frameCount = mRemainingFrames;
893 size_t nonContig;
894 status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig);
895 LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0),
896 "obtainBuffer() err=%d frameCount=%zu", err, audioBuffer.frameCount);
897 requested = &ClientProxy::kNonBlocking;
898 size_t avail = audioBuffer.frameCount + nonContig;
899 ALOGV("obtainBuffer(%u) returned %zu = %zu + %zu err %d",
900 mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err);
901 if (err != NO_ERROR) {
902 if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) {
903 break;
904 }
905 ALOGE("Error %d obtaining an audio buffer, giving up.", err);
906 return NS_NEVER;
907 }
908
909 if (mRetryOnPartialBuffer) {
910 mRetryOnPartialBuffer = false;
911 if (avail < mRemainingFrames) {
912 int64_t myns = ((mRemainingFrames - avail) *
913 1100000000LL) / mSampleRate;
914 if (ns < 0 || myns < ns) {
915 ns = myns;
916 }
917 return ns;
918 }
919 }
920
921 size_t reqSize = audioBuffer.size;
922 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
923 size_t readSize = audioBuffer.size;
924
925 // Sanity check on returned size
926 if (ssize_t(readSize) < 0 || readSize > reqSize) {
927 ALOGE("EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
928 reqSize, ssize_t(readSize));
929 return NS_NEVER;
930 }
931
932 if (readSize == 0) {
933 // The callback is done consuming buffers
934 // Keep this thread going to handle timed events and
935 // still try to provide more data in intervals of WAIT_PERIOD_MS
936 // but don't just loop and block the CPU, so wait
937 return WAIT_PERIOD_MS * 1000000LL;
938 }
939
940 size_t releasedFrames = readSize / mFrameSize;
941 audioBuffer.frameCount = releasedFrames;
942 mRemainingFrames -= releasedFrames;
943 if (misalignment >= releasedFrames) {
944 misalignment -= releasedFrames;
945 } else {
946 misalignment = 0;
947 }
948
949 releaseBuffer(&audioBuffer);
950
951 // FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer
952 // if callback doesn't like to accept the full chunk
953 if (readSize < reqSize) {
954 continue;
955 }
956
957 // There could be enough non-contiguous frames available to satisfy the remaining request
958 if (mRemainingFrames <= nonContig) {
959 continue;
960 }
961
962 #if 0
963 // This heuristic tries to collapse a series of EVENT_MORE_DATA that would total to a
964 // sum <= notificationFrames. It replaces that series by at most two EVENT_MORE_DATA
965 // that total to a sum == notificationFrames.
966 if (0 < misalignment && misalignment <= mRemainingFrames) {
967 mRemainingFrames = misalignment;
968 return (mRemainingFrames * 1100000000LL) / mSampleRate;
969 }
970 #endif
971
972 }
973 mRemainingFrames = notificationFrames;
974 mRetryOnPartialBuffer = true;
975
976 // A lot has transpired since ns was calculated, so run again immediately and re-calculate
977 return 0;
978 }
979
restoreRecord_l(const char * from)980 status_t AudioRecord::restoreRecord_l(const char *from)
981 {
982 ALOGW("dead IAudioRecord, creating a new one from %s()", from);
983 ++mSequence;
984 status_t result;
985
986 // if the new IAudioRecord is created, openRecord_l() will modify the
987 // following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory.
988 // It will also delete the strong references on previous IAudioRecord and IMemory
989 size_t position = mProxy->getPosition();
990 mNewPosition = position + mUpdatePeriod;
991 result = openRecord_l(position);
992 if (result == NO_ERROR) {
993 if (mActive) {
994 // callback thread or sync event hasn't changed
995 // FIXME this fails if we have a new AudioFlinger instance
996 result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
997 }
998 }
999 if (result != NO_ERROR) {
1000 ALOGW("restoreRecord_l() failed status %d", result);
1001 mActive = false;
1002 }
1003
1004 return result;
1005 }
1006
1007 // =========================================================================
1008
binderDied(const wp<IBinder> & who __unused)1009 void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused)
1010 {
1011 sp<AudioRecord> audioRecord = mAudioRecord.promote();
1012 if (audioRecord != 0) {
1013 AutoMutex lock(audioRecord->mLock);
1014 audioRecord->mProxy->binderDied();
1015 }
1016 }
1017
1018 // =========================================================================
1019
AudioRecordThread(AudioRecord & receiver,bool bCanCallJava)1020 AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava)
1021 : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL),
1022 mIgnoreNextPausedInt(false)
1023 {
1024 }
1025
~AudioRecordThread()1026 AudioRecord::AudioRecordThread::~AudioRecordThread()
1027 {
1028 }
1029
threadLoop()1030 bool AudioRecord::AudioRecordThread::threadLoop()
1031 {
1032 {
1033 AutoMutex _l(mMyLock);
1034 if (mPaused) {
1035 mMyCond.wait(mMyLock);
1036 // caller will check for exitPending()
1037 return true;
1038 }
1039 if (mIgnoreNextPausedInt) {
1040 mIgnoreNextPausedInt = false;
1041 mPausedInt = false;
1042 }
1043 if (mPausedInt) {
1044 if (mPausedNs > 0) {
1045 (void) mMyCond.waitRelative(mMyLock, mPausedNs);
1046 } else {
1047 mMyCond.wait(mMyLock);
1048 }
1049 mPausedInt = false;
1050 return true;
1051 }
1052 }
1053 nsecs_t ns = mReceiver.processAudioBuffer();
1054 switch (ns) {
1055 case 0:
1056 return true;
1057 case NS_INACTIVE:
1058 pauseInternal();
1059 return true;
1060 case NS_NEVER:
1061 return false;
1062 case NS_WHENEVER:
1063 // FIXME increase poll interval, or make event-driven
1064 ns = 1000000000LL;
1065 // fall through
1066 default:
1067 LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %" PRId64, ns);
1068 pauseInternal(ns);
1069 return true;
1070 }
1071 }
1072
requestExit()1073 void AudioRecord::AudioRecordThread::requestExit()
1074 {
1075 // must be in this order to avoid a race condition
1076 Thread::requestExit();
1077 resume();
1078 }
1079
pause()1080 void AudioRecord::AudioRecordThread::pause()
1081 {
1082 AutoMutex _l(mMyLock);
1083 mPaused = true;
1084 }
1085
resume()1086 void AudioRecord::AudioRecordThread::resume()
1087 {
1088 AutoMutex _l(mMyLock);
1089 mIgnoreNextPausedInt = true;
1090 if (mPaused || mPausedInt) {
1091 mPaused = false;
1092 mPausedInt = false;
1093 mMyCond.signal();
1094 }
1095 }
1096
pauseInternal(nsecs_t ns)1097 void AudioRecord::AudioRecordThread::pauseInternal(nsecs_t ns)
1098 {
1099 AutoMutex _l(mMyLock);
1100 mPausedInt = true;
1101 mPausedNs = ns;
1102 }
1103
1104 // -------------------------------------------------------------------------
1105
1106 }; // namespace android
1107