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