AudioRecord.cpp revision f5879c1448cc6aebc51b26d3ec2399d66144f8f4
189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/*
289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Copyright 2008, The Android Open Source Project
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** you may not use this file except in compliance with the License.
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** You may obtain a copy of the License at
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** See the License for the specific language governing permissions and
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** limitations under the License.
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project*/
1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//#define LOG_NDEBUG 0
1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LOG_TAG "AudioRecord"
2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <stdint.h>
2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/types.h>
2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sched.h>
2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/resource.h>
2689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <private/media/AudioTrackShared.h>
2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/AudioSystem.h>
3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/AudioRecord.h>
3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/IServiceManager.h>
3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Log.h>
3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/MemoryDealer.h>
3589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Parcel.h>
3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/IPCThreadState.h>
3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Timers.h>
3889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <cutils/atomic.h>
3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
4189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android {
4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ---------------------------------------------------------------------------
4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord()
4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    : mStatus(NO_INIT)
4989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
5089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
5189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
5289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord(
53f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent        int inputSource,
5489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t sampleRate,
5589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int format,
5689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int channelCount,
5789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int frameCount,
5889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t flags,
5989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        callback_t cbf,
6089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        void* user,
6189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int notificationFrames)
6289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    : mStatus(NO_INIT)
6389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
64f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent    mStatus = set(inputSource, sampleRate, format, channelCount,
6589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            frameCount, flags, cbf, user, notificationFrames);
6689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
6789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
6889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::~AudioRecord()
6989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
7089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mStatus == NO_ERROR) {
7189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Make sure that callback function exits in the case where
7289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // it is looping on buffer empty condition in obtainBuffer().
7389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Otherwise the callback thread will never exit.
7489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        stop();
7589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mClientRecordThread != 0) {
7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mClientRecordThread->requestExitAndWait();
7789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mClientRecordThread.clear();
7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mAudioRecord.clear();
8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        IPCThreadState::self()->flushCommands();
8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::set(
85f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent        int inputSource,
8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t sampleRate,
8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int format,
8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int channelCount,
8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int frameCount,
9089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t flags,
9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        callback_t cbf,
9289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        void* user,
9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int notificationFrames,
9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        bool threadCanCallJava)
9589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
9689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGV("set(): sampleRate %d, channelCount %d, frameCount %d",sampleRate, channelCount, frameCount);
981dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent    if (mAudioRecord != 0) {
9989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return INVALID_OPERATION;
10089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
10189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (audioFlinger == 0) {
10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return NO_INIT;
10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
107f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent    if (inputSource == DEFAULT_INPUT) {
108f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent        inputSource = MIC_INPUT;
10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (sampleRate == 0) {
11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        sampleRate = DEFAULT_SAMPLE_RATE;
11389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // these below should probably come from the audioFlinger too...
11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (format == 0) {
11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        format = AudioSystem::PCM_16_BIT;
11789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
11889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (channelCount == 0) {
11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        channelCount = 1;
12089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
12189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // validate parameters
12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (format != AudioSystem::PCM_16_BIT) {
12489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
12589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
12689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (channelCount != 1 && channelCount != 2) {
12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // validate framecount
13189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    size_t inputBuffSizeInBytes = -1;
13289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &inputBuffSizeInBytes)
13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            != NO_ERROR) {
13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        LOGE("AudioSystem could not query the input buffer size.");
13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return NO_INIT;
13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (inputBuffSizeInBytes == 0) {
13889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        LOGE("Recording parameters are not supported: sampleRate %d, channelCount %d, format %d",
13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            sampleRate, channelCount, format);
14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int frameSizeInBytes = channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1);
14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // We use 2* size of input buffer for ping pong use of record buffer.
14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int minFrameCount = 2 * inputBuffSizeInBytes / frameSizeInBytes;
14689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (frameCount == 0) {
14989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        frameCount = minFrameCount;
15089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (frameCount < minFrameCount) {
15189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
15289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (notificationFrames == 0) {
15589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        notificationFrames = frameCount/2;
15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
15789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // open record channel
15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t status;
160f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent    sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), inputSource,
16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                                       sampleRate, format,
16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                                       channelCount,
16389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                                       frameCount,
16489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                                       ((uint16_t)flags) << 16,
16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                                       &status);
16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (record == 0) {
16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        LOGE("AudioFlinger could not create record track, status: %d", status);
16889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return status;
16989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
17089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<IMemory> cblk = record->getCblk();
17189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (cblk == 0) {
17289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return NO_INIT;
17389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
17489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (cbf != 0) {
17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava);
17689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mClientRecordThread == 0) {
17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return NO_INIT;
17889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
17989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
18089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
18189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mStatus = NO_ERROR;
18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
18389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mAudioRecord = record;
18489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCblkMemory = cblk;
18589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
18689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
18789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCblk->out = 0;
18889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mSampleRate = sampleRate;
18989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mFormat = format;
19089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Update buffer size in case it has been limited by AudioFlinger during track creation
19189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mFrameCount = mCblk->frameCount;
19289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mChannelCount = channelCount;
19389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mActive = 0;
19489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCbf = cbf;
19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNotificationFrames = notificationFrames;
19689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mRemainingFrames = notificationFrames;
19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mUserData = user;
19889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // TODO: add audio hardware input latency here
19989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mLatency = (1000*mFrameCount) / mSampleRate;
20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mMarkerPosition = 0;
2017d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi    mMarkerReached = false;
20289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNewPosition = 0;
20389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mUpdatePeriod = 0;
204f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent    mInputSource = (uint8_t)inputSource;
20589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
20789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
20889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
20989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::initCheck() const
21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mStatus;
21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
21389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
21489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
21589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
21689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::latency() const
21789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
21889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mLatency;
21989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
22189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::sampleRate() const
22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
22389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mSampleRate;
22489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
22689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::format() const
22789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
22889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mFormat;
22989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::channelCount() const
23289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
23389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mChannelCount;
23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::frameCount() const
23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mFrameCount;
23989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::frameSize() const
24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t));
24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
246f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurentint AudioRecord::inputSource() const
247f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent{
248f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent    return (int)mInputSource;
249f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent}
250f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent
25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::start()
25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t ret = NO_ERROR;
25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<ClientRecordThread> t = mClientRecordThread;
25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGV("start");
25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
26089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (t != 0) {
26189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (t->exitPending()) {
26289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (t->requestExitAndWait() == WOULD_BLOCK) {
26389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                LOGE("AudioRecord::start called from thread");
26489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return WOULD_BLOCK;
26589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
26689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        t->mLock.lock();
26889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     }
26989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
27089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (android_atomic_or(1, &mActive) == 0) {
27189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mNewPosition = mCblk->user + mUpdatePeriod;
27289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mCblk->waitTimeMs = 0;
27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (t != 0) {
27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project           t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
27689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
27789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
27889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
27989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        ret = mAudioRecord->start();
28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (t != 0) {
28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        t->mLock.unlock();
28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return ret;
28789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
28889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
28989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::stop()
29089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
29189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<ClientRecordThread> t = mClientRecordThread;
29289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
29389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGV("stop");
29489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
29589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (t != 0) {
29689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        t->mLock.lock();
29789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     }
29889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
29989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (android_atomic_and(~1, &mActive) == 1) {
3001dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent        mCblk->cv.signal();
30189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mAudioRecord->stop();
3027d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi        // the record head position will reset to 0, so if a marker is set, we need
3037d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi        // to activate it again
3047d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi        mMarkerReached = false;
30589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (t != 0) {
30689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            t->requestExit();
30789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
30889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
30989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
31089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
31189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
31289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (t != 0) {
31389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        t->mLock.unlock();
31489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
31589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
31689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
31789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
31889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
31989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::stopped() const
32089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
32189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return !mActive;
32289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setMarkerPosition(uint32_t marker)
32589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mCbf == 0) return INVALID_OPERATION;
32789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mMarkerPosition = marker;
3297d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi    mMarkerReached = false;
33089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
33189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
33289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
33389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
33489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getMarkerPosition(uint32_t *marker)
33589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
33689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (marker == 0) return BAD_VALUE;
33789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
33889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *marker = mMarkerPosition;
33989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
34089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
34189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
34289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
34389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
34489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
34589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mCbf == 0) return INVALID_OPERATION;
34689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
34789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t curPosition;
34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    getPosition(&curPosition);
34989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNewPosition = curPosition + updatePeriod;
35089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mUpdatePeriod = updatePeriod;
35189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
35289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
35389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
35489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
35589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod)
35689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
35789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (updatePeriod == 0) return BAD_VALUE;
35889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *updatePeriod = mUpdatePeriod;
36089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
36489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getPosition(uint32_t *position)
36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (position == 0) return BAD_VALUE;
36789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
36889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *position = mCblk->user;
36989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
37189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
37289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
37489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
37689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
37889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int active;
37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int timeout = 0;
38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t result;
38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audio_track_cblk_t* cblk = mCblk;
38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t framesReq = audioBuffer->frameCount;
3831dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent    uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;
38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->frameCount  = 0;
38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->size        = 0;
38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t framesReady = cblk->framesReady();
38989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
39089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (framesReady == 0) {
39189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Mutex::Autolock _l(cblk->lock);
39289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        goto start_loop_here;
39389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        while (framesReady == 0) {
39489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            active = mActive;
39589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (UNLIKELY(!active))
39689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return NO_MORE_BUFFERS;
39789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (UNLIKELY(!waitCount))
39889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return WOULD_BLOCK;
39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            timeout = 0;
4001dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent            result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
40189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (__builtin_expect(result!=NO_ERROR, false)) {
4021dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent                cblk->waitTimeMs += waitTimeMs;
40389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
40489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    LOGW(   "obtainBuffer timed out (is the CPU pegged?) "
40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                            "user=%08x, server=%08x", cblk->user, cblk->server);
40689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    timeout = 1;
40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    cblk->waitTimeMs = 0;
40889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                }
40989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                if (--waitCount == 0) {
41089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    return TIMED_OUT;
41189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                }
41289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
41389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            // read the server count again
41489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        start_loop_here:
41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            framesReady = cblk->framesReady();
41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
41789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
41989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGW_IF(timeout,
42089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        "*** SERIOUS WARNING *** obtainBuffer() timed out "
42189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        "but didn't need to be locked. We recovered, but "
42289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        "this shouldn't happen (user=%08x, server=%08x)", cblk->user, cblk->server);
42389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
42489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    cblk->waitTimeMs = 0;
42589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
42689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (framesReq > framesReady) {
42789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        framesReq = framesReady;
42889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
42989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
43089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t u = cblk->user;
43189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
43289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
43389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (u + framesReq > bufferEnd) {
43489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        framesReq = bufferEnd - u;
43589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
43689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
43789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->flags       = 0;
43889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->channelCount= mChannelCount;
43989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->format      = mFormat;
44089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->frameCount  = framesReq;
44189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->size        = framesReq*mChannelCount*sizeof(int16_t);
44289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->raw         = (int8_t*)cblk->buffer(u);
44389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    active = mActive;
44489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return active ? status_t(NO_ERROR) : status_t(STOPPED);
44589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
44689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
44789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioRecord::releaseBuffer(Buffer* audioBuffer)
44889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
44989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audio_track_cblk_t* cblk = mCblk;
45089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    cblk->stepUser(audioBuffer->frameCount);
45189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
45289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
45389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
45489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
45589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t AudioRecord::read(void* buffer, size_t userSize)
45689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
45789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ssize_t read = 0;
45889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Buffer audioBuffer;
45989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int8_t *dst = static_cast<int8_t*>(buffer);
46089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
46189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (ssize_t(userSize) < 0) {
46289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // sanity-check. user is most-likely passing an error code.
46389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        LOGE("AudioRecord::read(buffer=%p, size=%u (%d)",
46489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                buffer, userSize, userSize);
46589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
46689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
46789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
46889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGV("read size: %d", userSize);
46989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
47089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    do {
47189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
47289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        audioBuffer.frameCount = userSize/mChannelCount/sizeof(int16_t);
47389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
47489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Calling obtainBuffer() with a negative wait count causes
47589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // an (almost) infinite wait time.
47689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        status_t err = obtainBuffer(&audioBuffer, -1);
47789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (err < 0) {
47889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            // out of buffers, return #bytes written
47989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (err == status_t(NO_MORE_BUFFERS))
48089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                break;
48189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return ssize_t(err);
48289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
48389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
48489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        size_t bytesRead = audioBuffer.size;
48589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        memcpy(dst, audioBuffer.i8, bytesRead);
48689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
48789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        dst += bytesRead;
48889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        userSize -= bytesRead;
48989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        read += bytesRead;
49089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
49189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        releaseBuffer(&audioBuffer);
49289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } while (userSize);
49389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
49489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return read;
49589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
49689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
49789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
49889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
49989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread)
50089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
50189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Buffer audioBuffer;
50289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t frames = mRemainingFrames;
50389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    size_t readSize;
50489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
50589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Manage marker callback
5067d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi    if (!mMarkerReached && (mMarkerPosition > 0)) {
50789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mCblk->user >= mMarkerPosition) {
50889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
5097d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi            mMarkerReached = true;
51089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
51189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
51289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
51389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Manage new position callback
51489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mUpdatePeriod > 0) {
51589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        while (mCblk->user >= mNewPosition) {
51689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition);
51789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mNewPosition += mUpdatePeriod;
51889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
51989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
52089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
52189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    do {
52289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        audioBuffer.frameCount = frames;
52389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Calling obtainBuffer() with a wait count of 1
52489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // limits wait time to WAIT_PERIOD_MS. This prevents from being
52589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // stuck here not being able to handle timed events (position, markers).
52689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        status_t err = obtainBuffer(&audioBuffer, 1);
52789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (err < NO_ERROR) {
52889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (err != TIMED_OUT) {
5291dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent                LOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up.");
53089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return false;
53189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
53289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            break;
53389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
53489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (err == status_t(STOPPED)) return false;
53589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
53689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        size_t reqSize = audioBuffer.size;
53789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
53889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        readSize = audioBuffer.size;
53989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
54089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Sanity check on returned size
541cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent        if (ssize_t(readSize) <= 0) {
542cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            // The callback is done filling buffers
543cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            // Keep this thread going to handle timed events and
544cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            // still try to get more data in intervals of WAIT_PERIOD_MS
545cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            // but don't just loop and block the CPU, so wait
546cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            usleep(WAIT_PERIOD_MS*1000);
547cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            break;
548cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent        }
54989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (readSize > reqSize) readSize = reqSize;
55089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
55189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        audioBuffer.size = readSize;
55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        audioBuffer.frameCount = readSize/mChannelCount/sizeof(int16_t);
55389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        frames -= audioBuffer.frameCount;
55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
55589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        releaseBuffer(&audioBuffer);
55689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
55789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } while (frames);
55889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
55989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Manage overrun callback
56189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mActive && (mCblk->framesAvailable_l() == 0)) {
56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        LOGV("Overrun user: %x, server: %x, flowControlFlag %d", mCblk->user, mCblk->server, mCblk->flowControlFlag);
56389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mCblk->flowControlFlag == 0) {
56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCbf(EVENT_OVERRUN, mUserData, 0);
56589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCblk->flowControlFlag = 1;
56689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
56789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
56889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
56989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (frames == 0) {
57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mRemainingFrames = mNotificationFrames;
57189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
57289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mRemainingFrames = frames;
57389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
57489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return true;
57589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
57689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
57789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// =========================================================================
57889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
57989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava)
58089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    : Thread(bCanCallJava), mReceiver(receiver)
58189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
58289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
58389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
58489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::ClientRecordThread::threadLoop()
58589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
58689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mReceiver.processAudioBuffer(this);
58789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
58889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
58989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
59089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
59189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android
59289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
593