AudioRecord.cpp revision 1703cdfee717b1b312bf8979816a9e2f16a82e5d
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>
31c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent#include <media/mediarecorder.h>
3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
337562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IServiceManager.h>
3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Log.h>
357562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/Parcel.h>
367562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IPCThreadState.h>
3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Timers.h>
3889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
4089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
4189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android {
4315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh// ---------------------------------------------------------------------------
4415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
4515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh// static
4615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yehstatus_t AudioRecord::getMinFrameCount(
4715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        int* frameCount,
4815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        uint32_t sampleRate,
4915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        int format,
5015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        int channelCount)
5115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh{
5215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    size_t size = 0;
5315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size)
5415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh            != NO_ERROR) {
5515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        LOGE("AudioSystem could not query the input buffer size.");
5615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        return NO_INIT;
5715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    }
5815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
5915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    if (size == 0) {
6015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        LOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d",
6115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh            sampleRate, format, channelCount);
6215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        return BAD_VALUE;
6315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    }
6415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
6515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    // We double the size of input buffer for ping pong use of record buffer.
6615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    size <<= 1;
6715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
6815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    if (AudioSystem::isLinearPCM(format)) {
6915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        size /= channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1);
7015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    }
7115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
7215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    *frameCount = size;
7315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    return NO_ERROR;
7415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh}
7589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ---------------------------------------------------------------------------
7789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord()
79be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    : mStatus(NO_INIT), mSessionId(0)
8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord(
84f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent        int inputSource,
8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t sampleRate,
8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int format,
87c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        uint32_t channels,
8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int frameCount,
8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t flags,
9089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        callback_t cbf,
9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        void* user,
92be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        int notificationFrames,
93be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        int sessionId)
94be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    : mStatus(NO_INIT), mSessionId(0)
9589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
96c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    mStatus = set(inputSource, sampleRate, format, channels,
97be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent            frameCount, flags, cbf, user, notificationFrames, sessionId);
9889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
9989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
10089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::~AudioRecord()
10189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mStatus == NO_ERROR) {
10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Make sure that callback function exits in the case where
10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // it is looping on buffer empty condition in obtainBuffer().
10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Otherwise the callback thread will never exit.
10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        stop();
10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mClientRecordThread != 0) {
10889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mClientRecordThread->requestExitAndWait();
10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mClientRecordThread.clear();
11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mAudioRecord.clear();
11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        IPCThreadState::self()->flushCommands();
11389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::set(
117f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent        int inputSource,
11889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t sampleRate,
11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int format,
120c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        uint32_t channels,
12189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int frameCount,
12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t flags,
12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        callback_t cbf,
12489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        void* user,
12589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int notificationFrames,
126be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        bool threadCanCallJava,
127be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        int sessionId)
12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
130c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    LOGV("set(): sampleRate %d, channels %d, frameCount %d",sampleRate, channels, frameCount);
1311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
1321703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
1331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
1341dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent    if (mAudioRecord != 0) {
13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return INVALID_OPERATION;
13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
138c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    if (inputSource == AUDIO_SOURCE_DEFAULT) {
139c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        inputSource = AUDIO_SOURCE_MIC;
14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (sampleRate == 0) {
14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        sampleRate = DEFAULT_SAMPLE_RATE;
14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // these below should probably come from the audioFlinger too...
14689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (format == 0) {
14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        format = AudioSystem::PCM_16_BIT;
14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
149c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    // validate parameters
150c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    if (!AudioSystem::isValidFormat(format)) {
151c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        LOGE("Invalid format");
152c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        return BAD_VALUE;
15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
155c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    if (!AudioSystem::isInputChannel(channels)) {
15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
15789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
158be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent
159c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    int channelCount = AudioSystem::popCount(channels);
160c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
1616100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    audio_io_handle_t input = AudioSystem::getInput(inputSource,
162c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent                                    sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags);
1636100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    if (input == 0) {
164148b266afe2ac92b5616c24e8d5160e6f9242f69Eric Laurent        LOGE("Could not get audio input for record source %d", inputSource);
16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
16889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // validate framecount
16915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    int minFrameCount = 0;
17015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelCount);
17115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    if (status != NO_ERROR) {
17215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        return status;
173c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    }
17489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
17689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (frameCount == 0) {
17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        frameCount = minFrameCount;
17889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (frameCount < minFrameCount) {
17989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
18089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
18189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (notificationFrames == 0) {
18389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        notificationFrames = frameCount/2;
18489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
18589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
186be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    mSessionId = sessionId;
187be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent
18834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    // create the IAudioRecord
1891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    status = openRecord_l(sampleRate, format, channelCount,
19015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh                        frameCount, flags, input);
19134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (status != NO_ERROR) {
19289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return status;
19389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
19434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (cbf != 0) {
19689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava);
19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mClientRecordThread == 0) {
19889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return NO_INIT;
19989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
20189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
20289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mStatus = NO_ERROR;
20389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
20489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mFormat = format;
20589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Update buffer size in case it has been limited by AudioFlinger during track creation
20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mFrameCount = mCblk->frameCount;
207c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    mChannelCount = (uint8_t)channelCount;
2086100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    mChannels = channels;
20989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mActive = 0;
21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCbf = cbf;
21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNotificationFrames = notificationFrames;
21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mRemainingFrames = notificationFrames;
21389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mUserData = user;
21489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // TODO: add audio hardware input latency here
215573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent    mLatency = (1000*mFrameCount) / sampleRate;
21689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mMarkerPosition = 0;
2177d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi    mMarkerReached = false;
21889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNewPosition = 0;
21989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mUpdatePeriod = 0;
220f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent    mInputSource = (uint8_t)inputSource;
22134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mFlags = flags;
22205bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    mInput = input;
22389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
22489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
22689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
22789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::initCheck() const
22889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
22989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mStatus;
23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
23189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
23389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::latency() const
23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
23689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mLatency;
23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::format() const
24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mFormat;
24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::channelCount() const
24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
24689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mChannelCount;
24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::frameCount() const
25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mFrameCount;
25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::frameSize() const
25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
256c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    if (AudioSystem::isLinearPCM(mFormat)) {
257c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t));
258c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    } else {
259c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        return sizeof(uint8_t);
260c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    }
26189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
26289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
263f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurentint AudioRecord::inputSource() const
264f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent{
265f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent    return (int)mInputSource;
266f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent}
267f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent
26889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
26989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
27089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::start()
27189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
27289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t ret = NO_ERROR;
27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<ClientRecordThread> t = mClientRecordThread;
27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGV("start");
27689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
27789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (t != 0) {
27889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (t->exitPending()) {
27989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (t->requestExitAndWait() == WOULD_BLOCK) {
28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                LOGE("AudioRecord::start called from thread");
28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return WOULD_BLOCK;
28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        t->mLock.lock();
28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     }
28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
287f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    AutoMutex lock(mLock);
2881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
2891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // while we are accessing the cblk
2901703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    sp <IAudioRecord> audioRecord = mAudioRecord;
2911703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    sp <IMemory> iMem = mCblkMemory;
2921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    audio_track_cblk_t* cblk = mCblk;
293f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    if (mActive == 0) {
294f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent        mActive = 1;
2951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
2961703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->lock.lock();
2971703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (!(cblk->flags & CBLK_INVALID_MSK)) {
2981703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->lock.unlock();
2991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            ret = mAudioRecord->start();
3001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->lock.lock();
3011703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            if (ret == DEAD_OBJECT) {
3021703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                cblk->flags |= CBLK_INVALID_MSK;
3036100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent            }
3046100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        }
3051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (cblk->flags & CBLK_INVALID_MSK) {
3061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            ret = restoreRecord_l(cblk);
3071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
3081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->lock.unlock();
3096100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        if (ret == NO_ERROR) {
3101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            mNewPosition = cblk->user + mUpdatePeriod;
3111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
3121703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->waitTimeMs = 0;
3136100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent            if (t != 0) {
3146100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent               t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
315c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent            } else {
3166100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent                setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
317c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent            }
3186100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        } else {
319f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent            mActive = 0;
32089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
32189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
32289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (t != 0) {
32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        t->mLock.unlock();
32589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return ret;
32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
32989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
33089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::stop()
33189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
33289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<ClientRecordThread> t = mClientRecordThread;
33389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
33489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOGV("stop");
33589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
33689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (t != 0) {
33789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        t->mLock.lock();
338f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    }
33989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
340f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    AutoMutex lock(mLock);
341f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    if (mActive == 1) {
342f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent        mActive = 0;
3431dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent        mCblk->cv.signal();
34489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mAudioRecord->stop();
3457d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi        // the record head position will reset to 0, so if a marker is set, we need
3467d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi        // to activate it again
3477d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi        mMarkerReached = false;
34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (t != 0) {
34989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            t->requestExit();
35089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
35189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
35289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
35389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
35489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
35589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (t != 0) {
35689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        t->mLock.unlock();
35789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
35889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
36089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::stopped() const
36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
36489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return !mActive;
36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
367573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurentuint32_t AudioRecord::getSampleRate()
368573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent{
3691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
370573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent    return mCblk->sampleRate;
371573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent}
372573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent
37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setMarkerPosition(uint32_t marker)
37489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mCbf == 0) return INVALID_OPERATION;
37689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mMarkerPosition = marker;
3787d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi    mMarkerReached = false;
37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getMarkerPosition(uint32_t *marker)
38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (marker == 0) return BAD_VALUE;
38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *marker = mMarkerPosition;
38889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
39089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
39189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
39289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
39389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
39489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mCbf == 0) return INVALID_OPERATION;
39589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
39689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t curPosition;
39789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    getPosition(&curPosition);
39889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNewPosition = curPosition + updatePeriod;
39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mUpdatePeriod = updatePeriod;
40089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
40189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
40289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
40389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
40489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod)
40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
40689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (updatePeriod == 0) return BAD_VALUE;
40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
40889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *updatePeriod = mUpdatePeriod;
40989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
41089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
41189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
41289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
41389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getPosition(uint32_t *position)
41489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (position == 0) return BAD_VALUE;
41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4171703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *position = mCblk->user;
41989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
42089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
42189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
42289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
42305bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurentunsigned int AudioRecord::getInputFramesLost()
42405bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent{
42505bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    if (mActive)
42605bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent        return AudioSystem::getInputFramesLost(mInput);
42705bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    else
42805bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent        return 0;
42905bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent}
43089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
43189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
43289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held
4341703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t AudioRecord::openRecord_l(
43534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        uint32_t sampleRate,
43634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        int format,
43734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        int channelCount,
43834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        int frameCount,
4396100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        uint32_t flags,
4406100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        audio_io_handle_t input)
44134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent{
44234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    status_t status;
44334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
44434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (audioFlinger == 0) {
44534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        return NO_INIT;
44634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    }
44734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
4486100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input,
44934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                                       sampleRate, format,
45034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                                       channelCount,
45134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                                       frameCount,
45234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                                       ((uint16_t)flags) << 16,
453be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent                                                       &mSessionId,
45434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                                       &status);
45534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (record == 0) {
45634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        LOGE("AudioFlinger could not create record track, status: %d", status);
45734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        return status;
45834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    }
45934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    sp<IMemory> cblk = record->getCblk();
46034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (cblk == 0) {
46134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        LOGE("Could not get control block");
46234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        return NO_INIT;
46334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    }
46434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mAudioRecord.clear();
46534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mAudioRecord = record;
46634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mCblkMemory.clear();
46734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mCblkMemory = cblk;
46834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
46934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
470d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent    mCblk->flags &= ~CBLK_DIRECTION_MSK;
4716100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
4726100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    mCblk->waitTimeMs = 0;
47334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    return NO_ERROR;
47434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent}
47534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
47689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
47789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
4781703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
47989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int active;
48089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t result;
48189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audio_track_cblk_t* cblk = mCblk;
48289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t framesReq = audioBuffer->frameCount;
4831dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent    uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;
48489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
48589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->frameCount  = 0;
48689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->size        = 0;
48789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
48889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t framesReady = cblk->framesReady();
48989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
49089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (framesReady == 0) {
49134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        cblk->lock.lock();
49289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        goto start_loop_here;
49389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        while (framesReady == 0) {
49489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            active = mActive;
49534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            if (UNLIKELY(!active)) {
49634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                cblk->lock.unlock();
49789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return NO_MORE_BUFFERS;
49834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            }
49934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            if (UNLIKELY(!waitCount)) {
50034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                cblk->lock.unlock();
50189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return WOULD_BLOCK;
50234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            }
5031703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            if (!(cblk->flags & CBLK_INVALID_MSK)) {
5041703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                mLock.unlock();
5051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
5061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                cblk->lock.unlock();
5071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                mLock.lock();
5081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                if (mActive == 0) {
5091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    return status_t(STOPPED);
5101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                }
5111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                cblk->lock.lock();
5121703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            }
5131703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            if (cblk->flags & CBLK_INVALID_MSK) {
5141703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                goto create_new_record;
5151703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            }
51689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (__builtin_expect(result!=NO_ERROR, false)) {
5171dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent                cblk->waitTimeMs += waitTimeMs;
51889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
51989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    LOGW(   "obtainBuffer timed out (is the CPU pegged?) "
52089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                            "user=%08x, server=%08x", cblk->user, cblk->server);
52134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    cblk->lock.unlock();
52234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    result = mAudioRecord->start();
5231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    cblk->lock.lock();
52434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    if (result == DEAD_OBJECT) {
5251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                        cblk->flags |= CBLK_INVALID_MSK;
5261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentcreate_new_record:
5271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                        result = AudioRecord::restoreRecord_l(cblk);
5281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    }
5291703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    if (result != NO_ERROR) {
5301703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                        LOGW("obtainBuffer create Track error %d", result);
5311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                        cblk->lock.unlock();
5321703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                        return result;
53334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    }
53489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    cblk->waitTimeMs = 0;
53589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                }
53689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                if (--waitCount == 0) {
53734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    cblk->lock.unlock();
53889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    return TIMED_OUT;
53989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                }
54089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
54189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            // read the server count again
54289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        start_loop_here:
54389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            framesReady = cblk->framesReady();
54489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
54534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        cblk->lock.unlock();
54689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
54789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
54889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    cblk->waitTimeMs = 0;
549c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
55089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (framesReq > framesReady) {
55189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        framesReq = framesReady;
55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
55389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t u = cblk->user;
55589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
55689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
55789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (u + framesReq > bufferEnd) {
55889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        framesReq = bufferEnd - u;
55989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
56189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->flags       = 0;
56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->channelCount= mChannelCount;
56389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->format      = mFormat;
56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->frameCount  = framesReq;
565c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    audioBuffer->size        = framesReq*cblk->frameSize;
56689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->raw         = (int8_t*)cblk->buffer(u);
56789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    active = mActive;
56889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return active ? status_t(NO_ERROR) : status_t(STOPPED);
56989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
57189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioRecord::releaseBuffer(Buffer* audioBuffer)
57289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
5731703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
5741703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    mCblk->stepUser(audioBuffer->frameCount);
57589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
57689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
5776100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurentaudio_io_handle_t AudioRecord::getInput()
5786100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent{
5791703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
5801703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    return getInput_l();
5811703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent}
5821703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
5831703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held
5841703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentaudio_io_handle_t AudioRecord::getInput_l()
5851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{
58605bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    mInput = AudioSystem::getInput(mInputSource,
5876100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent                                mCblk->sampleRate,
5886100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent                                mFormat, mChannels,
5896100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent                                (AudioSystem::audio_in_acoustics)mFlags);
59005bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    return mInput;
5916100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent}
5926100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent
593be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentint AudioRecord::getSessionId()
594be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent{
595be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    return mSessionId;
596be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent}
597be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent
59889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
59989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
60089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t AudioRecord::read(void* buffer, size_t userSize)
60189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
60289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ssize_t read = 0;
60389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Buffer audioBuffer;
60489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int8_t *dst = static_cast<int8_t*>(buffer);
60589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
60689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (ssize_t(userSize) < 0) {
60789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // sanity-check. user is most-likely passing an error code.
60889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        LOGE("AudioRecord::read(buffer=%p, size=%u (%d)",
60989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                buffer, userSize, userSize);
61089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
61189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
61289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
6131703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    mLock.lock();
6141703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
6151703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // while we are accessing the cblk
6161703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    sp <IAudioRecord> audioRecord = mAudioRecord;
6171703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    sp <IMemory> iMem = mCblkMemory;
6181703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    mLock.unlock();
61989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
62089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    do {
62189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
622c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        audioBuffer.frameCount = userSize/frameSize();
62389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
62488335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent        // By using a wait count corresponding to twice the timeout period in
62588335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent        // obtainBuffer() we give a chance to recover once for a read timeout
62688335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent        // (if media_server crashed for instance) before returning a length of
62788335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent        // 0 bytes read to the client
62888335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent        status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS));
62989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (err < 0) {
63089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            // out of buffers, return #bytes written
63189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (err == status_t(NO_MORE_BUFFERS))
63289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                break;
63388335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent            if (err == status_t(TIMED_OUT))
63488335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent                err = 0;
63589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return ssize_t(err);
63689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
63789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
63889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        size_t bytesRead = audioBuffer.size;
63989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        memcpy(dst, audioBuffer.i8, bytesRead);
64089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
64189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        dst += bytesRead;
64289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        userSize -= bytesRead;
64389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        read += bytesRead;
64489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
64589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        releaseBuffer(&audioBuffer);
64689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } while (userSize);
64789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
64889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return read;
64989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
65089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
65189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
65289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
65389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread)
65489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
65589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Buffer audioBuffer;
65689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t frames = mRemainingFrames;
65789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    size_t readSize;
65889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
6591703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    mLock.lock();
6601703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
6611703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // while we are accessing the cblk
6621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    sp <IAudioRecord> audioRecord = mAudioRecord;
6631703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    sp <IMemory> iMem = mCblkMemory;
6641703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    audio_track_cblk_t* cblk = mCblk;
6651703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    mLock.unlock();
6661703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
66789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Manage marker callback
6687d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi    if (!mMarkerReached && (mMarkerPosition > 0)) {
6691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (cblk->user >= mMarkerPosition) {
67089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
6717d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi            mMarkerReached = true;
67289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
67389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
67489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
67589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Manage new position callback
67689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mUpdatePeriod > 0) {
6771703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        while (cblk->user >= mNewPosition) {
67889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition);
67989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mNewPosition += mUpdatePeriod;
68089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
68189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
68289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
68389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    do {
68489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        audioBuffer.frameCount = frames;
685c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        // Calling obtainBuffer() with a wait count of 1
686c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        // limits wait time to WAIT_PERIOD_MS. This prevents from being
68789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // stuck here not being able to handle timed events (position, markers).
68889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        status_t err = obtainBuffer(&audioBuffer, 1);
68989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (err < NO_ERROR) {
69089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (err != TIMED_OUT) {
6911dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent                LOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up.");
69289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return false;
69389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
69489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            break;
69589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
69689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (err == status_t(STOPPED)) return false;
69789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
69889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        size_t reqSize = audioBuffer.size;
69989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
70089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        readSize = audioBuffer.size;
70189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
70289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Sanity check on returned size
703cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent        if (ssize_t(readSize) <= 0) {
704cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            // The callback is done filling buffers
705cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            // Keep this thread going to handle timed events and
706cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            // still try to get more data in intervals of WAIT_PERIOD_MS
707cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            // but don't just loop and block the CPU, so wait
708cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            usleep(WAIT_PERIOD_MS*1000);
709cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            break;
710cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent        }
71189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (readSize > reqSize) readSize = reqSize;
71289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
71389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        audioBuffer.size = readSize;
714c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        audioBuffer.frameCount = readSize/frameSize();
71589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        frames -= audioBuffer.frameCount;
71689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
71789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        releaseBuffer(&audioBuffer);
71889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
71989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } while (frames);
72089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
721c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
72289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Manage overrun callback
7231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    if (mActive && (cblk->framesAvailable() == 0)) {
7241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        LOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
7251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if ((cblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) {
72689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCbf(EVENT_OVERRUN, mUserData, 0);
7271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->flags |= CBLK_UNDERRUN_ON;
72889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
72989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
73089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
73189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (frames == 0) {
73289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mRemainingFrames = mNotificationFrames;
73389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
73489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mRemainingFrames = frames;
73589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
73689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return true;
73789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
73889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
7391703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock and cblk.lock held. Callers must also hold strong references on
7401703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// the IAudioRecord and IMemory in case they are recreated here.
7411703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// If the IAudioRecord is successfully restored, the cblk pointer is updated
7421703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk)
7431703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{
7441703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    status_t result;
7451703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
7461703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    if (!(cblk->flags & CBLK_RESTORING_MSK)) {
7471703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        LOGW("dead IAudioRecord, creating a new one");
7481703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
7491703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->flags |= CBLK_RESTORING_ON;
7501703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // signal old cblk condition so that other threads waiting for available buffers stop
7511703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // waiting now
7521703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->cv.broadcast();
7531703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->lock.unlock();
7541703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
7551703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // if the new IAudioRecord is created, openRecord_l() will modify the
7561703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // following member variables: mAudioRecord, mCblkMemory and mCblk.
7571703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // It will also delete the strong references on previous IAudioRecord and IMemory
7581703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        result = openRecord_l(cblk->sampleRate, mFormat, mChannelCount,
7591703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                mFrameCount, mFlags, getInput_l());
7601703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (result == NO_ERROR) {
7611703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            result = mAudioRecord->start();
7621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
7631703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (result != NO_ERROR) {
7641703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            mActive = false;
7651703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
7661703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
7671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // signal old cblk condition for other threads waiting for restore completion
7681703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->lock.lock();
7691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->flags |= CBLK_RESTORED_MSK;
7701703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->cv.broadcast();
7711703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->lock.unlock();
7721703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    } else {
7731703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (!(cblk->flags & CBLK_RESTORED_MSK)) {
7741703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            LOGW("dead IAudioRecord, waiting for a new one to be created");
7751703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            mLock.unlock();
7761703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
7771703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->lock.unlock();
7781703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            mLock.lock();
7791703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        } else {
7801703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            LOGW("dead IAudioRecord, already restored");
7811703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            result = NO_ERROR;
7821703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->lock.unlock();
7831703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
7841703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (result != NO_ERROR || mActive == 0) {
7851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            result = status_t(STOPPED);
7861703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
7871703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    }
7881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    LOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
7891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent         result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);
7901703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
7911703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    if (result == NO_ERROR) {
7921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // from now on we switch to the newly created cblk
7931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk = mCblk;
7941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    }
7951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    cblk->lock.lock();
7961703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
7971703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    LOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result);
7981703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
7991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    return result;
8001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent}
8011703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
80289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// =========================================================================
80389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
80489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava)
80589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    : Thread(bCanCallJava), mReceiver(receiver)
80689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
80789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
80889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
80989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::ClientRecordThread::threadLoop()
81089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
81189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mReceiver.processAudioBuffer(this);
81289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
81389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
81489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
81589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
81689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android
81789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
818