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