AudioRecord.cpp revision 15304d601cbf83be6519ca53e1a26b97d50d0192
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 <stdint.h>
22#include <sys/types.h>
23
24#include <sched.h>
25#include <sys/resource.h>
26
27#include <private/media/AudioTrackShared.h>
28
29#include <media/AudioSystem.h>
30#include <media/AudioRecord.h>
31#include <media/mediarecorder.h>
32
33#include <binder/IServiceManager.h>
34#include <utils/Log.h>
35#include <binder/Parcel.h>
36#include <binder/IPCThreadState.h>
37#include <utils/Timers.h>
38#include <cutils/atomic.h>
39
40#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
41#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
42
43namespace android {
44// ---------------------------------------------------------------------------
45
46// static
47status_t AudioRecord::getMinFrameCount(
48        int* frameCount,
49        uint32_t sampleRate,
50        int format,
51        int channelCount)
52{
53    size_t size = 0;
54    if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size)
55            != NO_ERROR) {
56        LOGE("AudioSystem could not query the input buffer size.");
57        return NO_INIT;
58    }
59
60    if (size == 0) {
61        LOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d",
62            sampleRate, format, channelCount);
63        return BAD_VALUE;
64    }
65
66    // We double the size of input buffer for ping pong use of record buffer.
67    size <<= 1;
68
69    if (AudioSystem::isLinearPCM(format)) {
70        size /= channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1);
71    }
72
73    *frameCount = size;
74    return NO_ERROR;
75}
76
77// ---------------------------------------------------------------------------
78
79AudioRecord::AudioRecord()
80    : mStatus(NO_INIT), mSessionId(0)
81{
82}
83
84AudioRecord::AudioRecord(
85        int inputSource,
86        uint32_t sampleRate,
87        int format,
88        uint32_t channels,
89        int frameCount,
90        uint32_t flags,
91        callback_t cbf,
92        void* user,
93        int notificationFrames,
94        int sessionId)
95    : mStatus(NO_INIT), mSessionId(0)
96{
97    mStatus = set(inputSource, sampleRate, format, channels,
98            frameCount, flags, cbf, user, notificationFrames, sessionId);
99}
100
101AudioRecord::~AudioRecord()
102{
103    if (mStatus == NO_ERROR) {
104        // Make sure that callback function exits in the case where
105        // it is looping on buffer empty condition in obtainBuffer().
106        // Otherwise the callback thread will never exit.
107        stop();
108        if (mClientRecordThread != 0) {
109            mClientRecordThread->requestExitAndWait();
110            mClientRecordThread.clear();
111        }
112        mAudioRecord.clear();
113        IPCThreadState::self()->flushCommands();
114    }
115}
116
117status_t AudioRecord::set(
118        int inputSource,
119        uint32_t sampleRate,
120        int format,
121        uint32_t channels,
122        int frameCount,
123        uint32_t flags,
124        callback_t cbf,
125        void* user,
126        int notificationFrames,
127        bool threadCanCallJava,
128        int sessionId)
129{
130
131    LOGV("set(): sampleRate %d, channels %d, frameCount %d",sampleRate, channels, frameCount);
132    if (mAudioRecord != 0) {
133        return INVALID_OPERATION;
134    }
135
136    if (inputSource == AUDIO_SOURCE_DEFAULT) {
137        inputSource = AUDIO_SOURCE_MIC;
138    }
139
140    if (sampleRate == 0) {
141        sampleRate = DEFAULT_SAMPLE_RATE;
142    }
143    // these below should probably come from the audioFlinger too...
144    if (format == 0) {
145        format = AudioSystem::PCM_16_BIT;
146    }
147    // validate parameters
148    if (!AudioSystem::isValidFormat(format)) {
149        LOGE("Invalid format");
150        return BAD_VALUE;
151    }
152
153    if (!AudioSystem::isInputChannel(channels)) {
154        return BAD_VALUE;
155    }
156
157    int channelCount = AudioSystem::popCount(channels);
158
159    audio_io_handle_t input = AudioSystem::getInput(inputSource,
160                                    sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags);
161    if (input == 0) {
162        LOGE("Could not get audio input for record source %d", inputSource);
163        return BAD_VALUE;
164    }
165
166    // validate framecount
167    int minFrameCount = 0;
168    status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelCount);
169    if (status != NO_ERROR) {
170        return status;
171    }
172    LOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
173
174    if (frameCount == 0) {
175        frameCount = minFrameCount;
176    } else if (frameCount < minFrameCount) {
177        return BAD_VALUE;
178    }
179
180    if (notificationFrames == 0) {
181        notificationFrames = frameCount/2;
182    }
183
184    mSessionId = sessionId;
185
186    // create the IAudioRecord
187    status = openRecord(sampleRate, format, channelCount,
188                        frameCount, flags, input);
189    if (status != NO_ERROR) {
190        return status;
191    }
192
193    if (cbf != 0) {
194        mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava);
195        if (mClientRecordThread == 0) {
196            return NO_INIT;
197        }
198    }
199
200    mStatus = NO_ERROR;
201
202    mFormat = format;
203    // Update buffer size in case it has been limited by AudioFlinger during track creation
204    mFrameCount = mCblk->frameCount;
205    mChannelCount = (uint8_t)channelCount;
206    mChannels = channels;
207    mActive = 0;
208    mCbf = cbf;
209    mNotificationFrames = notificationFrames;
210    mRemainingFrames = notificationFrames;
211    mUserData = user;
212    // TODO: add audio hardware input latency here
213    mLatency = (1000*mFrameCount) / sampleRate;
214    mMarkerPosition = 0;
215    mMarkerReached = false;
216    mNewPosition = 0;
217    mUpdatePeriod = 0;
218    mInputSource = (uint8_t)inputSource;
219    mFlags = flags;
220    mInput = input;
221
222    return NO_ERROR;
223}
224
225status_t AudioRecord::initCheck() const
226{
227    return mStatus;
228}
229
230// -------------------------------------------------------------------------
231
232uint32_t AudioRecord::latency() const
233{
234    return mLatency;
235}
236
237int AudioRecord::format() const
238{
239    return mFormat;
240}
241
242int AudioRecord::channelCount() const
243{
244    return mChannelCount;
245}
246
247uint32_t AudioRecord::frameCount() const
248{
249    return mFrameCount;
250}
251
252int AudioRecord::frameSize() const
253{
254    if (AudioSystem::isLinearPCM(mFormat)) {
255        return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t));
256    } else {
257        return sizeof(uint8_t);
258    }
259}
260
261int AudioRecord::inputSource() const
262{
263    return (int)mInputSource;
264}
265
266// -------------------------------------------------------------------------
267
268status_t AudioRecord::start()
269{
270    status_t ret = NO_ERROR;
271    sp<ClientRecordThread> t = mClientRecordThread;
272
273    LOGV("start");
274
275    if (t != 0) {
276        if (t->exitPending()) {
277            if (t->requestExitAndWait() == WOULD_BLOCK) {
278                LOGE("AudioRecord::start called from thread");
279                return WOULD_BLOCK;
280            }
281        }
282        t->mLock.lock();
283     }
284
285    if (android_atomic_or(1, &mActive) == 0) {
286        ret = mAudioRecord->start();
287        if (ret == DEAD_OBJECT) {
288            LOGV("start() dead IAudioRecord: creating a new one");
289            ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount,
290                    mFrameCount, mFlags, getInput());
291            if (ret == NO_ERROR) {
292                ret = mAudioRecord->start();
293            }
294        }
295        if (ret == NO_ERROR) {
296            mNewPosition = mCblk->user + mUpdatePeriod;
297            mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
298            mCblk->waitTimeMs = 0;
299            if (t != 0) {
300               t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
301            } else {
302                setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
303            }
304        } else {
305            LOGV("start() failed");
306            android_atomic_and(~1, &mActive);
307        }
308    }
309
310    if (t != 0) {
311        t->mLock.unlock();
312    }
313
314    return ret;
315}
316
317status_t AudioRecord::stop()
318{
319    sp<ClientRecordThread> t = mClientRecordThread;
320
321    LOGV("stop");
322
323    if (t != 0) {
324        t->mLock.lock();
325     }
326
327    if (android_atomic_and(~1, &mActive) == 1) {
328        mCblk->cv.signal();
329        mAudioRecord->stop();
330        // the record head position will reset to 0, so if a marker is set, we need
331        // to activate it again
332        mMarkerReached = false;
333        if (t != 0) {
334            t->requestExit();
335        } else {
336            setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
337        }
338    }
339
340    if (t != 0) {
341        t->mLock.unlock();
342    }
343
344    return NO_ERROR;
345}
346
347bool AudioRecord::stopped() const
348{
349    return !mActive;
350}
351
352uint32_t AudioRecord::getSampleRate()
353{
354    return mCblk->sampleRate;
355}
356
357status_t AudioRecord::setMarkerPosition(uint32_t marker)
358{
359    if (mCbf == 0) return INVALID_OPERATION;
360
361    mMarkerPosition = marker;
362    mMarkerReached = false;
363
364    return NO_ERROR;
365}
366
367status_t AudioRecord::getMarkerPosition(uint32_t *marker)
368{
369    if (marker == 0) return BAD_VALUE;
370
371    *marker = mMarkerPosition;
372
373    return NO_ERROR;
374}
375
376status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
377{
378    if (mCbf == 0) return INVALID_OPERATION;
379
380    uint32_t curPosition;
381    getPosition(&curPosition);
382    mNewPosition = curPosition + updatePeriod;
383    mUpdatePeriod = updatePeriod;
384
385    return NO_ERROR;
386}
387
388status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod)
389{
390    if (updatePeriod == 0) return BAD_VALUE;
391
392    *updatePeriod = mUpdatePeriod;
393
394    return NO_ERROR;
395}
396
397status_t AudioRecord::getPosition(uint32_t *position)
398{
399    if (position == 0) return BAD_VALUE;
400
401    *position = mCblk->user;
402
403    return NO_ERROR;
404}
405
406unsigned int AudioRecord::getInputFramesLost()
407{
408    if (mActive)
409        return AudioSystem::getInputFramesLost(mInput);
410    else
411        return 0;
412}
413
414// -------------------------------------------------------------------------
415
416status_t AudioRecord::openRecord(
417        uint32_t sampleRate,
418        int format,
419        int channelCount,
420        int frameCount,
421        uint32_t flags,
422        audio_io_handle_t input)
423{
424    status_t status;
425    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
426    if (audioFlinger == 0) {
427        return NO_INIT;
428    }
429
430    sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input,
431                                                       sampleRate, format,
432                                                       channelCount,
433                                                       frameCount,
434                                                       ((uint16_t)flags) << 16,
435                                                       &mSessionId,
436                                                       &status);
437    if (record == 0) {
438        LOGE("AudioFlinger could not create record track, status: %d", status);
439        return status;
440    }
441    sp<IMemory> cblk = record->getCblk();
442    if (cblk == 0) {
443        LOGE("Could not get control block");
444        return NO_INIT;
445    }
446    mAudioRecord.clear();
447    mAudioRecord = record;
448    mCblkMemory.clear();
449    mCblkMemory = cblk;
450    mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
451    mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
452    mCblk->flags &= ~CBLK_DIRECTION_MSK;
453    mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
454    mCblk->waitTimeMs = 0;
455    return NO_ERROR;
456}
457
458status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
459{
460    int active;
461    status_t result;
462    audio_track_cblk_t* cblk = mCblk;
463    uint32_t framesReq = audioBuffer->frameCount;
464    uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;
465
466    audioBuffer->frameCount  = 0;
467    audioBuffer->size        = 0;
468
469    uint32_t framesReady = cblk->framesReady();
470
471    if (framesReady == 0) {
472        cblk->lock.lock();
473        goto start_loop_here;
474        while (framesReady == 0) {
475            active = mActive;
476            if (UNLIKELY(!active)) {
477                cblk->lock.unlock();
478                return NO_MORE_BUFFERS;
479            }
480            if (UNLIKELY(!waitCount)) {
481                cblk->lock.unlock();
482                return WOULD_BLOCK;
483            }
484            result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
485            if (__builtin_expect(result!=NO_ERROR, false)) {
486                cblk->waitTimeMs += waitTimeMs;
487                if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
488                    LOGW(   "obtainBuffer timed out (is the CPU pegged?) "
489                            "user=%08x, server=%08x", cblk->user, cblk->server);
490                    cblk->lock.unlock();
491                    result = mAudioRecord->start();
492                    if (result == DEAD_OBJECT) {
493                        LOGW("obtainBuffer() dead IAudioRecord: creating a new one");
494                        result = openRecord(cblk->sampleRate, mFormat, mChannelCount,
495                                            mFrameCount, mFlags, getInput());
496                        if (result == NO_ERROR) {
497                            cblk = mCblk;
498                            mAudioRecord->start();
499                        }
500                    }
501                    cblk->lock.lock();
502                    cblk->waitTimeMs = 0;
503                }
504                if (--waitCount == 0) {
505                    cblk->lock.unlock();
506                    return TIMED_OUT;
507                }
508            }
509            // read the server count again
510        start_loop_here:
511            framesReady = cblk->framesReady();
512        }
513        cblk->lock.unlock();
514    }
515
516    cblk->waitTimeMs = 0;
517
518    if (framesReq > framesReady) {
519        framesReq = framesReady;
520    }
521
522    uint32_t u = cblk->user;
523    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
524
525    if (u + framesReq > bufferEnd) {
526        framesReq = bufferEnd - u;
527    }
528
529    audioBuffer->flags       = 0;
530    audioBuffer->channelCount= mChannelCount;
531    audioBuffer->format      = mFormat;
532    audioBuffer->frameCount  = framesReq;
533    audioBuffer->size        = framesReq*cblk->frameSize;
534    audioBuffer->raw         = (int8_t*)cblk->buffer(u);
535    active = mActive;
536    return active ? status_t(NO_ERROR) : status_t(STOPPED);
537}
538
539void AudioRecord::releaseBuffer(Buffer* audioBuffer)
540{
541    audio_track_cblk_t* cblk = mCblk;
542    cblk->stepUser(audioBuffer->frameCount);
543}
544
545audio_io_handle_t AudioRecord::getInput()
546{
547    mInput = AudioSystem::getInput(mInputSource,
548                                mCblk->sampleRate,
549                                mFormat, mChannels,
550                                (AudioSystem::audio_in_acoustics)mFlags);
551    return mInput;
552}
553
554int AudioRecord::getSessionId()
555{
556    return mSessionId;
557}
558
559// -------------------------------------------------------------------------
560
561ssize_t AudioRecord::read(void* buffer, size_t userSize)
562{
563    ssize_t read = 0;
564    Buffer audioBuffer;
565    int8_t *dst = static_cast<int8_t*>(buffer);
566
567    if (ssize_t(userSize) < 0) {
568        // sanity-check. user is most-likely passing an error code.
569        LOGE("AudioRecord::read(buffer=%p, size=%u (%d)",
570                buffer, userSize, userSize);
571        return BAD_VALUE;
572    }
573
574
575    do {
576
577        audioBuffer.frameCount = userSize/frameSize();
578
579        // By using a wait count corresponding to twice the timeout period in
580        // obtainBuffer() we give a chance to recover once for a read timeout
581        // (if media_server crashed for instance) before returning a length of
582        // 0 bytes read to the client
583        status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS));
584        if (err < 0) {
585            // out of buffers, return #bytes written
586            if (err == status_t(NO_MORE_BUFFERS))
587                break;
588            if (err == status_t(TIMED_OUT))
589                err = 0;
590            return ssize_t(err);
591        }
592
593        size_t bytesRead = audioBuffer.size;
594        memcpy(dst, audioBuffer.i8, bytesRead);
595
596        dst += bytesRead;
597        userSize -= bytesRead;
598        read += bytesRead;
599
600        releaseBuffer(&audioBuffer);
601    } while (userSize);
602
603    return read;
604}
605
606// -------------------------------------------------------------------------
607
608bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread)
609{
610    Buffer audioBuffer;
611    uint32_t frames = mRemainingFrames;
612    size_t readSize;
613
614    // Manage marker callback
615    if (!mMarkerReached && (mMarkerPosition > 0)) {
616        if (mCblk->user >= mMarkerPosition) {
617            mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
618            mMarkerReached = true;
619        }
620    }
621
622    // Manage new position callback
623    if (mUpdatePeriod > 0) {
624        while (mCblk->user >= mNewPosition) {
625            mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition);
626            mNewPosition += mUpdatePeriod;
627        }
628    }
629
630    do {
631        audioBuffer.frameCount = frames;
632        // Calling obtainBuffer() with a wait count of 1
633        // limits wait time to WAIT_PERIOD_MS. This prevents from being
634        // stuck here not being able to handle timed events (position, markers).
635        status_t err = obtainBuffer(&audioBuffer, 1);
636        if (err < NO_ERROR) {
637            if (err != TIMED_OUT) {
638                LOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up.");
639                return false;
640            }
641            break;
642        }
643        if (err == status_t(STOPPED)) return false;
644
645        size_t reqSize = audioBuffer.size;
646        mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
647        readSize = audioBuffer.size;
648
649        // Sanity check on returned size
650        if (ssize_t(readSize) <= 0) {
651            // The callback is done filling buffers
652            // Keep this thread going to handle timed events and
653            // still try to get more data in intervals of WAIT_PERIOD_MS
654            // but don't just loop and block the CPU, so wait
655            usleep(WAIT_PERIOD_MS*1000);
656            break;
657        }
658        if (readSize > reqSize) readSize = reqSize;
659
660        audioBuffer.size = readSize;
661        audioBuffer.frameCount = readSize/frameSize();
662        frames -= audioBuffer.frameCount;
663
664        releaseBuffer(&audioBuffer);
665
666    } while (frames);
667
668
669    // Manage overrun callback
670    if (mActive && (mCblk->framesAvailable_l() == 0)) {
671        LOGV("Overrun user: %x, server: %x, flags %04x", mCblk->user, mCblk->server, mCblk->flags);
672        if ((mCblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) {
673            mCbf(EVENT_OVERRUN, mUserData, 0);
674            mCblk->flags |= CBLK_UNDERRUN_ON;
675        }
676    }
677
678    if (frames == 0) {
679        mRemainingFrames = mNotificationFrames;
680    } else {
681        mRemainingFrames = frames;
682    }
683    return true;
684}
685
686// =========================================================================
687
688AudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava)
689    : Thread(bCanCallJava), mReceiver(receiver)
690{
691}
692
693bool AudioRecord::ClientRecordThread::threadLoop()
694{
695    return mReceiver.processAudioBuffer(this);
696}
697
698// -------------------------------------------------------------------------
699
700}; // namespace android
701
702