AudioRecord.cpp revision 9c5fdd83f9b9f49be35107971feb33528d60b945
1aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)/*
2aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)**
3aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** Copyright 2008, The Android Open Source Project
4aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)**
5aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** Licensed under the Apache License, Version 2.0 (the "License");
6aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** you may not use this file except in compliance with the License.
7aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** You may obtain a copy of the License at
8aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)**
9aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)**     http://www.apache.org/licenses/LICENSE-2.0
10aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)**
11aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** Unless required by applicable law or agreed to in writing, software
12aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** distributed under the License is distributed on an "AS IS" BASIS,
13aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** See the License for the specific language governing permissions and
15aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** limitations under the License.
16aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)*/
17aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
18aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)//#define LOG_NDEBUG 0
19aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)#define LOG_TAG "AudioRecord"
20aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
21aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)#include <sys/resource.h>
22cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)#include <sys/types.h>
23cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)
24cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)#include <binder/IPCThreadState.h>
25cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)#include <cutils/atomic.h>
26cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)#include <cutils/compiler.h>
27cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)#include <media/AudioRecord.h>
28cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)#include <media/AudioSystem.h>
29aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)#include <system/audio.h>
30aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)#include <utils/Log.h>
31aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
32aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)#include <private/media/AudioTrackShared.h>
33aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
34aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)namespace android {
35aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)// ---------------------------------------------------------------------------
36aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
37aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)// static
380dd72dc2dac5ee57fd597f172e5015650312a700Ignacio Sollastatus_t AudioRecord::getMinFrameCount(
390dd72dc2dac5ee57fd597f172e5015650312a700Ignacio Solla        int* frameCount,
40aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        uint32_t sampleRate,
41aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        audio_format_t format,
42aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        audio_channel_mask_t channelMask)
43074f227d175b9e70783dc939555ee89005642977Selim Gurun{
44aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    if (frameCount == NULL) return BAD_VALUE;
45aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
46aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    // default to 0 in case of error
47aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    *frameCount = 0;
48aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
4961afed696a71ff0a288916a9319461cd880375e2Ben Murdoch    size_t size = 0;
50aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    if (AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size)
51aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)            != NO_ERROR) {
5261afed696a71ff0a288916a9319461cd880375e2Ben Murdoch        ALOGE("AudioSystem could not query the input buffer size.");
53aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        return NO_INIT;
54aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    }
55aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
5673e77f9db2815cf820a6753e2d532557cfc5b9a2Torne (Richard Coles)    if (size == 0) {
5773e77f9db2815cf820a6753e2d532557cfc5b9a2Torne (Richard Coles)        ALOGE("Unsupported configuration: sampleRate %d, format %d, channelMask %#x",
5873e77f9db2815cf820a6753e2d532557cfc5b9a2Torne (Richard Coles)            sampleRate, format, channelMask);
59aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        return BAD_VALUE;
60aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    }
61aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
62aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    // We double the size of input buffer for ping pong use of record buffer.
63aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    size <<= 1;
64e7088bc41cfbeb3eca02b1347c61cb21e37203b4Ying Wang
65e7088bc41cfbeb3eca02b1347c61cb21e37203b4Ying Wang    if (audio_is_linear_pcm(format)) {
66e7088bc41cfbeb3eca02b1347c61cb21e37203b4Ying Wang        int channelCount = popcount(channelMask);
67aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        size /= channelCount * audio_bytes_per_sample(format);
68aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    }
69aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
70aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    *frameCount = size;
71aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    return NO_ERROR;
72aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)}
73aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
74aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)// ---------------------------------------------------------------------------
75aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
76aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)AudioRecord::AudioRecord()
77aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    : mStatus(NO_INIT), mSessionId(0),
78aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)      mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
79aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles){
80aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)}
81aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
82aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)AudioRecord::AudioRecord(
83aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        audio_source_t inputSource,
84aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        uint32_t sampleRate,
85aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        audio_format_t format,
86aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        audio_channel_mask_t channelMask,
87aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        int frameCount,
88aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        callback_t cbf,
89aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        void* user,
90aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        int notificationFrames,
91aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)        int sessionId)
92aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    : mStatus(NO_INIT), mSessionId(0),
93aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)      mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
94aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles){
95aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)    mStatus = set(inputSource, sampleRate, format, channelMask,
96aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)            frameCount, cbf, user, notificationFrames, sessionId);
97aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)}
98aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)
99aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)AudioRecord::~AudioRecord()
100aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles){
101cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)    if (mStatus == NO_ERROR) {
102cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)        // 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        mAudioRecord.clear();
112        IPCThreadState::self()->flushCommands();
113        AudioSystem::releaseAudioSessionId(mSessionId);
114    }
115}
116
117status_t AudioRecord::set(
118        audio_source_t inputSource,
119        uint32_t sampleRate,
120        audio_format_t format,
121        audio_channel_mask_t channelMask,
122        int frameCount,
123        callback_t cbf,
124        void* user,
125        int notificationFrames,
126        bool threadCanCallJava,
127        int sessionId)
128{
129
130    ALOGV("set(): sampleRate %d, channelMask %#x, frameCount %d",sampleRate, channelMask,
131            frameCount);
132
133    AutoMutex lock(mLock);
134
135    if (mAudioRecord != 0) {
136        return INVALID_OPERATION;
137    }
138
139    if (inputSource == AUDIO_SOURCE_DEFAULT) {
140        inputSource = AUDIO_SOURCE_MIC;
141    }
142
143    if (sampleRate == 0) {
144        sampleRate = DEFAULT_SAMPLE_RATE;
145    }
146    // these below should probably come from the audioFlinger too...
147    if (format == AUDIO_FORMAT_DEFAULT) {
148        format = AUDIO_FORMAT_PCM_16_BIT;
149    }
150    // validate parameters
151    if (!audio_is_valid_format(format)) {
152        ALOGE("Invalid format");
153        return BAD_VALUE;
154    }
155
156    if (!audio_is_input_channel(channelMask)) {
157        return BAD_VALUE;
158    }
159
160    int channelCount = popcount(channelMask);
161
162    if (sessionId == 0 ) {
163        mSessionId = AudioSystem::newAudioSessionId();
164    } else {
165        mSessionId = sessionId;
166    }
167    ALOGV("set(): mSessionId %d", mSessionId);
168
169    audio_io_handle_t input = AudioSystem::getInput(inputSource,
170                                                    sampleRate,
171                                                    format,
172                                                    channelMask,
173                                                    mSessionId);
174    if (input == 0) {
175        ALOGE("Could not get audio input for record source %d", inputSource);
176        return BAD_VALUE;
177    }
178
179    // validate framecount
180    int minFrameCount = 0;
181    status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelMask);
182    if (status != NO_ERROR) {
183        return status;
184    }
185    ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
186
187    if (frameCount == 0) {
188        frameCount = minFrameCount;
189    } else if (frameCount < minFrameCount) {
190        return BAD_VALUE;
191    }
192
193    if (notificationFrames == 0) {
194        notificationFrames = frameCount/2;
195    }
196
197    // create the IAudioRecord
198    status = openRecord_l(sampleRate, format, channelMask,
199                        frameCount, input);
200    if (status != NO_ERROR) {
201        return status;
202    }
203
204    if (cbf != NULL) {
205        mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava);
206        mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
207    }
208
209    mStatus = NO_ERROR;
210
211    mFormat = format;
212    // Update buffer size in case it has been limited by AudioFlinger during track creation
213    mFrameCount = mCblk->frameCount;
214    mChannelCount = (uint8_t)channelCount;
215    mChannelMask = channelMask;
216    mActive = false;
217    mCbf = cbf;
218    mNotificationFrames = notificationFrames;
219    mRemainingFrames = notificationFrames;
220    mUserData = user;
221    // TODO: add audio hardware input latency here
222    mLatency = (1000*mFrameCount) / sampleRate;
223    mMarkerPosition = 0;
224    mMarkerReached = false;
225    mNewPosition = 0;
226    mUpdatePeriod = 0;
227    mInputSource = inputSource;
228    mInput = input;
229    AudioSystem::acquireAudioSessionId(mSessionId);
230
231    return NO_ERROR;
232}
233
234status_t AudioRecord::initCheck() const
235{
236    return mStatus;
237}
238
239// -------------------------------------------------------------------------
240
241uint32_t AudioRecord::latency() const
242{
243    return mLatency;
244}
245
246audio_format_t AudioRecord::format() const
247{
248    return mFormat;
249}
250
251int AudioRecord::channelCount() const
252{
253    return mChannelCount;
254}
255
256uint32_t AudioRecord::frameCount() const
257{
258    return mFrameCount;
259}
260
261size_t AudioRecord::frameSize() const
262{
263    if (audio_is_linear_pcm(mFormat)) {
264        return channelCount()*audio_bytes_per_sample(mFormat);
265    } else {
266        return sizeof(uint8_t);
267    }
268}
269
270audio_source_t AudioRecord::inputSource() const
271{
272    return mInputSource;
273}
274
275// -------------------------------------------------------------------------
276
277status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession)
278{
279    status_t ret = NO_ERROR;
280    sp<AudioRecordThread> t = mAudioRecordThread;
281
282    ALOGV("start, sync event %d trigger session %d", event, triggerSession);
283
284    AutoMutex lock(mLock);
285    // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
286    // while we are accessing the cblk
287    sp<IAudioRecord> audioRecord = mAudioRecord;
288    sp<IMemory> iMem = mCblkMemory;
289    audio_track_cblk_t* cblk = mCblk;
290
291    if (!mActive) {
292        mActive = true;
293
294        cblk->lock.lock();
295        if (!(cblk->flags & CBLK_INVALID)) {
296            cblk->lock.unlock();
297            ALOGV("mAudioRecord->start()");
298            ret = mAudioRecord->start(event, triggerSession);
299            cblk->lock.lock();
300            if (ret == DEAD_OBJECT) {
301                android_atomic_or(CBLK_INVALID, &cblk->flags);
302            }
303        }
304        if (cblk->flags & CBLK_INVALID) {
305            ret = restoreRecord_l(cblk);
306        }
307        cblk->lock.unlock();
308        if (ret == NO_ERROR) {
309            mNewPosition = cblk->user + mUpdatePeriod;
310            cblk->bufferTimeoutMs = (event == AudioSystem::SYNC_EVENT_NONE) ? MAX_RUN_TIMEOUT_MS :
311                                            AudioSystem::kSyncRecordStartTimeOutMs;
312            cblk->waitTimeMs = 0;
313            if (t != 0) {
314                t->resume();
315            } else {
316                mPreviousPriority = getpriority(PRIO_PROCESS, 0);
317                get_sched_policy(0, &mPreviousSchedulingGroup);
318                androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
319            }
320        } else {
321            mActive = false;
322        }
323    }
324
325    return ret;
326}
327
328void AudioRecord::stop()
329{
330    sp<AudioRecordThread> t = mAudioRecordThread;
331
332    ALOGV("stop");
333
334    AutoMutex lock(mLock);
335    if (mActive) {
336        mActive = false;
337        mCblk->cv.signal();
338        mAudioRecord->stop();
339        // the record head position will reset to 0, so if a marker is set, we need
340        // to activate it again
341        mMarkerReached = false;
342        if (t != 0) {
343            t->pause();
344        } else {
345            setpriority(PRIO_PROCESS, 0, mPreviousPriority);
346            set_sched_policy(0, mPreviousSchedulingGroup);
347        }
348    }
349}
350
351bool AudioRecord::stopped() const
352{
353    AutoMutex lock(mLock);
354    return !mActive;
355}
356
357uint32_t AudioRecord::getSampleRate() const
358{
359    return mCblk->sampleRate;
360}
361
362status_t AudioRecord::setMarkerPosition(uint32_t marker)
363{
364    if (mCbf == NULL) return INVALID_OPERATION;
365
366    AutoMutex lock(mLock);
367    mMarkerPosition = marker;
368    mMarkerReached = false;
369
370    return NO_ERROR;
371}
372
373status_t AudioRecord::getMarkerPosition(uint32_t *marker) const
374{
375    if (marker == NULL) return BAD_VALUE;
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) return INVALID_OPERATION;
386
387    uint32_t curPosition;
388    getPosition(&curPosition);
389
390    AutoMutex lock(mLock);
391    mNewPosition = curPosition + updatePeriod;
392    mUpdatePeriod = updatePeriod;
393
394    return NO_ERROR;
395}
396
397status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const
398{
399    if (updatePeriod == NULL) return BAD_VALUE;
400
401    AutoMutex lock(mLock);
402    *updatePeriod = mUpdatePeriod;
403
404    return NO_ERROR;
405}
406
407status_t AudioRecord::getPosition(uint32_t *position) const
408{
409    if (position == NULL) return BAD_VALUE;
410
411    AutoMutex lock(mLock);
412    *position = mCblk->user;
413
414    return NO_ERROR;
415}
416
417unsigned int AudioRecord::getInputFramesLost() const
418{
419    // no need to check mActive, because if inactive this will return 0, which is what we want
420    return AudioSystem::getInputFramesLost(mInput);
421}
422
423// -------------------------------------------------------------------------
424
425// must be called with mLock held
426status_t AudioRecord::openRecord_l(
427        uint32_t sampleRate,
428        audio_format_t format,
429        audio_channel_mask_t channelMask,
430        int frameCount,
431        audio_io_handle_t input)
432{
433    status_t status;
434    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
435    if (audioFlinger == 0) {
436        return NO_INIT;
437    }
438
439    pid_t tid = -1;
440    // FIXME see similar logic at AudioTrack
441
442    int originalSessionId = mSessionId;
443    sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input,
444                                                       sampleRate, format,
445                                                       channelMask,
446                                                       frameCount,
447                                                       IAudioFlinger::TRACK_DEFAULT,
448                                                       tid,
449                                                       &mSessionId,
450                                                       &status);
451    ALOGE_IF(originalSessionId != 0 && mSessionId != originalSessionId,
452            "session ID changed from %d to %d", originalSessionId, mSessionId);
453
454    if (record == 0) {
455        ALOGE("AudioFlinger could not create record track, status: %d", status);
456        return status;
457    }
458    sp<IMemory> cblk = record->getCblk();
459    if (cblk == 0) {
460        ALOGE("Could not get control block");
461        return NO_INIT;
462    }
463    mAudioRecord.clear();
464    mAudioRecord = record;
465    mCblkMemory.clear();
466    mCblkMemory = cblk;
467    mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
468    mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
469    android_atomic_and(~CBLK_DIRECTION, &mCblk->flags);
470    mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
471    mCblk->waitTimeMs = 0;
472    return NO_ERROR;
473}
474
475status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
476{
477    AutoMutex lock(mLock);
478    bool active;
479    status_t result = NO_ERROR;
480    audio_track_cblk_t* cblk = mCblk;
481    uint32_t framesReq = audioBuffer->frameCount;
482    uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;
483
484    audioBuffer->frameCount  = 0;
485    audioBuffer->size        = 0;
486
487    uint32_t framesReady = cblk->framesReady();
488
489    if (framesReady == 0) {
490        cblk->lock.lock();
491        goto start_loop_here;
492        while (framesReady == 0) {
493            active = mActive;
494            if (CC_UNLIKELY(!active)) {
495                cblk->lock.unlock();
496                return NO_MORE_BUFFERS;
497            }
498            if (CC_UNLIKELY(!waitCount)) {
499                cblk->lock.unlock();
500                return WOULD_BLOCK;
501            }
502            if (!(cblk->flags & CBLK_INVALID)) {
503                mLock.unlock();
504                result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
505                cblk->lock.unlock();
506                mLock.lock();
507                if (!mActive) {
508                    return status_t(STOPPED);
509                }
510                cblk->lock.lock();
511            }
512            if (cblk->flags & CBLK_INVALID) {
513                goto create_new_record;
514            }
515            if (CC_UNLIKELY(result != NO_ERROR)) {
516                cblk->waitTimeMs += waitTimeMs;
517                if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
518                    ALOGW(   "obtainBuffer timed out (is the CPU pegged?) "
519                            "user=%08x, server=%08x", cblk->user, cblk->server);
520                    cblk->lock.unlock();
521                    // callback thread or sync event hasn't changed
522                    result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
523                    cblk->lock.lock();
524                    if (result == DEAD_OBJECT) {
525                        android_atomic_or(CBLK_INVALID, &cblk->flags);
526create_new_record:
527                        result = AudioRecord::restoreRecord_l(cblk);
528                    }
529                    if (result != NO_ERROR) {
530                        ALOGW("obtainBuffer create Track error %d", result);
531                        cblk->lock.unlock();
532                        return result;
533                    }
534                    cblk->waitTimeMs = 0;
535                }
536                if (--waitCount == 0) {
537                    cblk->lock.unlock();
538                    return TIMED_OUT;
539                }
540            }
541            // read the server count again
542        start_loop_here:
543            framesReady = cblk->framesReady();
544        }
545        cblk->lock.unlock();
546    }
547
548    cblk->waitTimeMs = 0;
549    // reset time out to running value after obtaining a buffer
550    cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
551
552    if (framesReq > framesReady) {
553        framesReq = framesReady;
554    }
555
556    uint32_t u = cblk->user;
557    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
558
559    if (framesReq > bufferEnd - u) {
560        framesReq = bufferEnd - u;
561    }
562
563    audioBuffer->flags       = 0;
564    audioBuffer->channelCount= mChannelCount;
565    audioBuffer->format      = mFormat;
566    audioBuffer->frameCount  = framesReq;
567    audioBuffer->size        = framesReq*cblk->frameSize;
568    audioBuffer->raw         = (int8_t*)cblk->buffer(u);
569    active = mActive;
570    return active ? status_t(NO_ERROR) : status_t(STOPPED);
571}
572
573void AudioRecord::releaseBuffer(Buffer* audioBuffer)
574{
575    AutoMutex lock(mLock);
576    mCblk->stepUser(audioBuffer->frameCount);
577}
578
579audio_io_handle_t AudioRecord::getInput() const
580{
581    AutoMutex lock(mLock);
582    return mInput;
583}
584
585// must be called with mLock held
586audio_io_handle_t AudioRecord::getInput_l()
587{
588    mInput = AudioSystem::getInput(mInputSource,
589                                mCblk->sampleRate,
590                                mFormat,
591                                mChannelMask,
592                                mSessionId);
593    return mInput;
594}
595
596int AudioRecord::getSessionId() const
597{
598    // no lock needed because session ID doesn't change after first set()
599    return mSessionId;
600}
601
602// -------------------------------------------------------------------------
603
604ssize_t AudioRecord::read(void* buffer, size_t userSize)
605{
606    ssize_t read = 0;
607    Buffer audioBuffer;
608    int8_t *dst = static_cast<int8_t*>(buffer);
609
610    if (ssize_t(userSize) < 0) {
611        // sanity-check. user is most-likely passing an error code.
612        ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)",
613                buffer, userSize, userSize);
614        return BAD_VALUE;
615    }
616
617    mLock.lock();
618    // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
619    // while we are accessing the cblk
620    sp<IAudioRecord> audioRecord = mAudioRecord;
621    sp<IMemory> iMem = mCblkMemory;
622    mLock.unlock();
623
624    do {
625
626        audioBuffer.frameCount = userSize/frameSize();
627
628        // By using a wait count corresponding to twice the timeout period in
629        // obtainBuffer() we give a chance to recover once for a read timeout
630        // (if media_server crashed for instance) before returning a length of
631        // 0 bytes read to the client
632        status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS));
633        if (err < 0) {
634            // out of buffers, return #bytes written
635            if (err == status_t(NO_MORE_BUFFERS))
636                break;
637            if (err == status_t(TIMED_OUT))
638                err = 0;
639            return ssize_t(err);
640        }
641
642        size_t bytesRead = audioBuffer.size;
643        memcpy(dst, audioBuffer.i8, bytesRead);
644
645        dst += bytesRead;
646        userSize -= bytesRead;
647        read += bytesRead;
648
649        releaseBuffer(&audioBuffer);
650    } while (userSize);
651
652    return read;
653}
654
655// -------------------------------------------------------------------------
656
657bool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread)
658{
659    Buffer audioBuffer;
660    uint32_t frames = mRemainingFrames;
661    size_t readSize;
662
663    mLock.lock();
664    // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
665    // while we are accessing the cblk
666    sp<IAudioRecord> audioRecord = mAudioRecord;
667    sp<IMemory> iMem = mCblkMemory;
668    audio_track_cblk_t* cblk = mCblk;
669    bool active = mActive;
670    uint32_t markerPosition = mMarkerPosition;
671    uint32_t newPosition = mNewPosition;
672    uint32_t user = cblk->user;
673    // determine whether a marker callback will be needed, while locked
674    bool needMarker = !mMarkerReached && (mMarkerPosition > 0) && (user >= mMarkerPosition);
675    if (needMarker) {
676        mMarkerReached = true;
677    }
678    // determine the number of new position callback(s) that will be needed, while locked
679    uint32_t updatePeriod = mUpdatePeriod;
680    uint32_t needNewPos = updatePeriod > 0 && user >= newPosition ?
681            ((user - newPosition) / updatePeriod) + 1 : 0;
682    mNewPosition = newPosition + updatePeriod * needNewPos;
683    mLock.unlock();
684
685    // perform marker callback, while unlocked
686    if (needMarker) {
687        mCbf(EVENT_MARKER, mUserData, &markerPosition);
688    }
689
690    // perform new position callback(s), while unlocked
691    for (; needNewPos > 0; --needNewPos) {
692        uint32_t temp = newPosition;
693        mCbf(EVENT_NEW_POS, mUserData, &temp);
694        newPosition += updatePeriod;
695    }
696
697    do {
698        audioBuffer.frameCount = frames;
699        // Calling obtainBuffer() with a wait count of 1
700        // limits wait time to WAIT_PERIOD_MS. This prevents from being
701        // stuck here not being able to handle timed events (position, markers).
702        status_t err = obtainBuffer(&audioBuffer, 1);
703        if (err < NO_ERROR) {
704            if (err != TIMED_OUT) {
705                ALOGE_IF(err != status_t(NO_MORE_BUFFERS),
706                        "Error obtaining an audio buffer, giving up.");
707                return false;
708            }
709            break;
710        }
711        if (err == status_t(STOPPED)) return false;
712
713        size_t reqSize = audioBuffer.size;
714        mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
715        readSize = audioBuffer.size;
716
717        // Sanity check on returned size
718        if (ssize_t(readSize) <= 0) {
719            // The callback is done filling buffers
720            // Keep this thread going to handle timed events and
721            // still try to get more data in intervals of WAIT_PERIOD_MS
722            // but don't just loop and block the CPU, so wait
723            usleep(WAIT_PERIOD_MS*1000);
724            break;
725        }
726        if (readSize > reqSize) readSize = reqSize;
727
728        audioBuffer.size = readSize;
729        audioBuffer.frameCount = readSize/frameSize();
730        frames -= audioBuffer.frameCount;
731
732        releaseBuffer(&audioBuffer);
733
734    } while (frames);
735
736
737    // Manage overrun callback
738    if (active && (cblk->framesAvailable() == 0)) {
739        // The value of active is stale, but we are almost sure to be active here because
740        // otherwise we would have exited when obtainBuffer returned STOPPED earlier.
741        ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
742        if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) {
743            mCbf(EVENT_OVERRUN, mUserData, NULL);
744        }
745    }
746
747    if (frames == 0) {
748        mRemainingFrames = mNotificationFrames;
749    } else {
750        mRemainingFrames = frames;
751    }
752    return true;
753}
754
755// must be called with mLock and cblk.lock held. Callers must also hold strong references on
756// the IAudioRecord and IMemory in case they are recreated here.
757// If the IAudioRecord is successfully restored, the cblk pointer is updated
758status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk)
759{
760    status_t result;
761
762    if (!(android_atomic_or(CBLK_RESTORING, &cblk->flags) & CBLK_RESTORING)) {
763        ALOGW("dead IAudioRecord, creating a new one");
764        // signal old cblk condition so that other threads waiting for available buffers stop
765        // waiting now
766        cblk->cv.broadcast();
767        cblk->lock.unlock();
768
769        // if the new IAudioRecord is created, openRecord_l() will modify the
770        // following member variables: mAudioRecord, mCblkMemory and mCblk.
771        // It will also delete the strong references on previous IAudioRecord and IMemory
772        result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask,
773                mFrameCount, getInput_l());
774        if (result == NO_ERROR) {
775            // callback thread or sync event hasn't changed
776            result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
777        }
778        if (result != NO_ERROR) {
779            mActive = false;
780        }
781
782        // signal old cblk condition for other threads waiting for restore completion
783        android_atomic_or(CBLK_RESTORED, &cblk->flags);
784        cblk->cv.broadcast();
785    } else {
786        if (!(cblk->flags & CBLK_RESTORED)) {
787            ALOGW("dead IAudioRecord, waiting for a new one to be created");
788            mLock.unlock();
789            result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
790            cblk->lock.unlock();
791            mLock.lock();
792        } else {
793            ALOGW("dead IAudioRecord, already restored");
794            result = NO_ERROR;
795            cblk->lock.unlock();
796        }
797        if (result != NO_ERROR || !mActive) {
798            result = status_t(STOPPED);
799        }
800    }
801    ALOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
802        result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);
803
804    if (result == NO_ERROR) {
805        // from now on we switch to the newly created cblk
806        cblk = mCblk;
807    }
808    cblk->lock.lock();
809
810    ALOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result);
811
812    return result;
813}
814
815// =========================================================================
816
817AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava)
818    : Thread(bCanCallJava), mReceiver(receiver), mPaused(true)
819{
820}
821
822AudioRecord::AudioRecordThread::~AudioRecordThread()
823{
824}
825
826bool AudioRecord::AudioRecordThread::threadLoop()
827{
828    {
829        AutoMutex _l(mMyLock);
830        if (mPaused) {
831            mMyCond.wait(mMyLock);
832            // caller will check for exitPending()
833            return true;
834        }
835    }
836    if (!mReceiver.processAudioBuffer(this)) {
837        pause();
838    }
839    return true;
840}
841
842void AudioRecord::AudioRecordThread::requestExit()
843{
844    // must be in this order to avoid a race condition
845    Thread::requestExit();
846    resume();
847}
848
849void AudioRecord::AudioRecordThread::pause()
850{
851    AutoMutex _l(mMyLock);
852    mPaused = true;
853}
854
855void AudioRecord::AudioRecordThread::resume()
856{
857    AutoMutex _l(mMyLock);
858    if (mPaused) {
859        mPaused = false;
860        mMyCond.signal();
861    }
862}
863
864// -------------------------------------------------------------------------
865
866}; // namespace android
867