AudioRecord.cpp revision 34f1d8ecd23169a5f299937e3aaf1bd7937578a0
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/MemoryDealer.h> 367562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/Parcel.h> 377562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IPCThreadState.h> 3889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Timers.h> 3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <cutils/atomic.h> 4089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) 4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) 4389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android { 4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// --------------------------------------------------------------------------- 4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord() 49c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent : mStatus(NO_INIT), mInput(0) 5089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 5189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 5289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 5389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord( 54f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent int inputSource, 5589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t sampleRate, 5689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int format, 57c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent uint32_t channels, 5889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int frameCount, 5989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t flags, 6089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project callback_t cbf, 6189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project void* user, 6289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int notificationFrames) 63c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent : mStatus(NO_INIT), mInput(0) 6489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 65c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent mStatus = set(inputSource, sampleRate, format, channels, 6689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frameCount, flags, cbf, user, notificationFrames); 6789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 6889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::~AudioRecord() 7089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 7189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mStatus == NO_ERROR) { 7289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Make sure that callback function exits in the case where 7389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // it is looping on buffer empty condition in obtainBuffer(). 7489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Otherwise the callback thread will never exit. 7589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project stop(); 7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mClientRecordThread != 0) { 7789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mClientRecordThread->requestExitAndWait(); 7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mClientRecordThread.clear(); 7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioRecord.clear(); 8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project IPCThreadState::self()->flushCommands(); 82c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent AudioSystem::releaseInput(mInput); 8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::set( 87f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent int inputSource, 8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t sampleRate, 8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int format, 90c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent uint32_t channels, 9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int frameCount, 9289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t flags, 9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project callback_t cbf, 9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project void* user, 9589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int notificationFrames, 9689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project bool threadCanCallJava) 9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 9889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 99c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent LOGV("set(): sampleRate %d, channels %d, frameCount %d",sampleRate, channels, frameCount); 1001dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent if (mAudioRecord != 0) { 10189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return INVALID_OPERATION; 10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 104c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (inputSource == AUDIO_SOURCE_DEFAULT) { 105c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent inputSource = AUDIO_SOURCE_MIC; 10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 10889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (sampleRate == 0) { 10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sampleRate = DEFAULT_SAMPLE_RATE; 11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // these below should probably come from the audioFlinger too... 11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (format == 0) { 11389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project format = AudioSystem::PCM_16_BIT; 11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 115c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // validate parameters 116c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (!AudioSystem::isValidFormat(format)) { 117c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent LOGE("Invalid format"); 118c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return BAD_VALUE; 11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 12089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 121c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (!AudioSystem::isInputChannel(channels)) { 12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 124c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent int channelCount = AudioSystem::popCount(channels); 125c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 126c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent mInput = AudioSystem::getInput(inputSource, 127c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags); 128c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (mInput == 0) { 129c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent LOGE("Could not get audio output for stream type %d", inputSource); 13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 13189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 13289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // validate framecount 13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t inputBuffSizeInBytes = -1; 13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &inputBuffSizeInBytes) 13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project != NO_ERROR) { 13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("AudioSystem could not query the input buffer size."); 138c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return NO_INIT; 13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 140c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (inputBuffSizeInBytes == 0) { 14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Recording parameters are not supported: sampleRate %d, channelCount %d, format %d", 14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sampleRate, channelCount, format); 14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 146c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int frameSizeInBytes = channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1); 148c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (AudioSystem::isLinearPCM(format)) { 149c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent frameSizeInBytes = channelCount * (format == AudioSystem::PCM_16_BIT ? sizeof(int16_t) : sizeof(int8_t)); 150c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 151c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent frameSizeInBytes = sizeof(int8_t); 152c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 153c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 15589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // We use 2* size of input buffer for ping pong use of record buffer. 15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int minFrameCount = 2 * inputBuffSizeInBytes / frameSizeInBytes; 15789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (frameCount == 0) { 16089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frameCount = minFrameCount; 16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (frameCount < minFrameCount) { 16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 16389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 16489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (notificationFrames == 0) { 16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project notificationFrames = frameCount/2; 16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 16889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 16934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent // create the IAudioRecord 17034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent status_t status = openRecord(sampleRate, format, channelCount, 17134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent frameCount, flags); 17234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 17334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (status != NO_ERROR) { 17489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return status; 17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 17634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (cbf != 0) { 17889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); 17989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mClientRecordThread == 0) { 18089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_INIT; 18189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 18389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 18489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mStatus = NO_ERROR; 18589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 18689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFormat = format; 18789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Update buffer size in case it has been limited by AudioFlinger during track creation 18889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFrameCount = mCblk->frameCount; 189c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent mChannelCount = (uint8_t)channelCount; 19089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mActive = 0; 19189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf = cbf; 19289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNotificationFrames = notificationFrames; 19389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = notificationFrames; 19489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUserData = user; 19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // TODO: add audio hardware input latency here 196573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent mLatency = (1000*mFrameCount) / sampleRate; 19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMarkerPosition = 0; 1987d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 19989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition = 0; 20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUpdatePeriod = 0; 201f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent mInputSource = (uint8_t)inputSource; 20234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mFlags = flags; 20389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 20489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 20589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 20789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::initCheck() const 20889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 20989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mStatus; 21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 21389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 21489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::latency() const 21589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 21689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mLatency; 21789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 21889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 21989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::format() const 22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 22189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mFormat; 22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 22389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 22489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::channelCount() const 22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 22689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mChannelCount; 22789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 22889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 22989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::frameCount() const 23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 23189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mFrameCount; 23289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 23389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::frameSize() const 23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 236c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (AudioSystem::isLinearPCM(mFormat)) { 237c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t)); 238c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 239c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return sizeof(uint8_t); 240c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 243f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurentint AudioRecord::inputSource() const 244f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent{ 245f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent return (int)mInputSource; 246f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent} 247f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent 24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::start() 25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t ret = NO_ERROR; 25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<ClientRecordThread> t = mClientRecordThread; 25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("start"); 25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t->exitPending()) { 25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t->requestExitAndWait() == WOULD_BLOCK) { 26089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("AudioRecord::start called from thread"); 26189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return WOULD_BLOCK; 26289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 26389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 26489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->mLock.lock(); 26589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 26689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (android_atomic_or(1, &mActive) == 0) { 268c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent ret = AudioSystem::startInput(mInput); 269c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (ret == NO_ERROR) { 27034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent ret = mAudioRecord->start(); 27134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (ret == DEAD_OBJECT) { 27234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent LOGV("start() dead IAudioRecord: creating a new one"); 27334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount, 27434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mFrameCount, mFlags); 27534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 27634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (ret == NO_ERROR) { 27734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mNewPosition = mCblk->user + mUpdatePeriod; 27834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 27934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk->waitTimeMs = 0; 28034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (t != 0) { 28134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT); 28234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } else { 28334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT); 28434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 285c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 28634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent LOGV("start() failed"); 28734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent AudioSystem::stopInput(mInput); 28834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent android_atomic_and(~1, &mActive); 289c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 29089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 29189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 29289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 29389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 29489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->mLock.unlock(); 29589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 29689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 29789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ret; 29889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 29989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 30089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::stop() 30189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 30289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<ClientRecordThread> t = mClientRecordThread; 30389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 30489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("stop"); 30589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 30689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 30789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->mLock.lock(); 30889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 30989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 31089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (android_atomic_and(~1, &mActive) == 1) { 3111dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent mCblk->cv.signal(); 31289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioRecord->stop(); 3137d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi // the record head position will reset to 0, so if a marker is set, we need 3147d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi // to activate it again 3157d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 31689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 31789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->requestExit(); 31889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 31989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL); 32089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 321c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent AudioSystem::stopInput(mInput); 32289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 32589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->mLock.unlock(); 32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 32789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 32989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 33089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 33189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::stopped() const 33289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 33389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return !mActive; 33489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 33589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 336573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurentuint32_t AudioRecord::getSampleRate() 337573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent{ 338573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent return mCblk->sampleRate; 339573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent} 340573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent 34189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setMarkerPosition(uint32_t marker) 34289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 34389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mCbf == 0) return INVALID_OPERATION; 34489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 34589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMarkerPosition = marker; 3467d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 34789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 34989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 35089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 35189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getMarkerPosition(uint32_t *marker) 35289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 35389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (marker == 0) return BAD_VALUE; 35489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 35589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *marker = mMarkerPosition; 35689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 35789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 35889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mCbf == 0) return INVALID_OPERATION; 36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t curPosition; 36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project getPosition(&curPosition); 36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition = curPosition + updatePeriod; 36789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUpdatePeriod = updatePeriod; 36889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 37189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) 37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 37489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (updatePeriod == 0) return BAD_VALUE; 37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *updatePeriod = mUpdatePeriod; 37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getPosition(uint32_t *position) 38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (position == 0) return BAD_VALUE; 38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *position = mCblk->user; 38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 38889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 38989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 39289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurentstatus_t AudioRecord::openRecord( 39434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent uint32_t sampleRate, 39534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent int format, 39634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent int channelCount, 39734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent int frameCount, 39834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent uint32_t flags) 39934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent{ 40034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent status_t status; 40134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 40234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (audioFlinger == 0) { 40334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_INIT; 40434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 40534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 40634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), mInput, 40734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent sampleRate, format, 40834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent channelCount, 40934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent frameCount, 41034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent ((uint16_t)flags) << 16, 41134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent &status); 41234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (record == 0) { 41334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent LOGE("AudioFlinger could not create record track, status: %d", status); 41434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return status; 41534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 41634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent sp<IMemory> cblk = record->getCblk(); 41734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (cblk == 0) { 41834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent LOGE("Could not get control block"); 41934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_INIT; 42034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 42134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mAudioRecord.clear(); 42234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mAudioRecord = record; 42334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblkMemory.clear(); 42434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblkMemory = cblk; 42534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 42634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 42734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk->out = 0; 42834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 42934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_ERROR; 43034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent} 43134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 43289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 43389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 43489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int active; 43589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t result; 43689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audio_track_cblk_t* cblk = mCblk; 43789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t framesReq = audioBuffer->frameCount; 4381dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; 43989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 44089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->frameCount = 0; 44189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->size = 0; 44289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 44389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t framesReady = cblk->framesReady(); 44489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 44589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (framesReady == 0) { 44634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.lock(); 44789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto start_loop_here; 44889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (framesReady == 0) { 44989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project active = mActive; 45034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (UNLIKELY(!active)) { 45134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 45289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_MORE_BUFFERS; 45334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 45434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (UNLIKELY(!waitCount)) { 45534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 45689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return WOULD_BLOCK; 45734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 4581dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); 45989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (__builtin_expect(result!=NO_ERROR, false)) { 4601dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent cblk->waitTimeMs += waitTimeMs; 46189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 46289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGW( "obtainBuffer timed out (is the CPU pegged?) " 46389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project "user=%08x, server=%08x", cblk->user, cblk->server); 46434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 46534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent result = mAudioRecord->start(); 46634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (result == DEAD_OBJECT) { 46734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent LOGW("obtainBuffer() dead IAudioRecord: creating a new one"); 46834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent result = openRecord(cblk->sampleRate, mFormat, mChannelCount, 46934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mFrameCount, mFlags); 47034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (result == NO_ERROR) { 47134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk = mCblk; 47234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 47334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 47434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 47534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.lock(); 47689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cblk->waitTimeMs = 0; 47789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 47889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (--waitCount == 0) { 47934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 48089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return TIMED_OUT; 48189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 48289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 48389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // read the server count again 48489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project start_loop_here: 48589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReady = cblk->framesReady(); 48689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 48734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 48889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 48989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 49089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cblk->waitTimeMs = 0; 491c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 49289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (framesReq > framesReady) { 49389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReq = framesReady; 49489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 49589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 49689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t u = cblk->user; 49789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 49889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 49989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (u + framesReq > bufferEnd) { 50089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReq = bufferEnd - u; 50189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 50289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 50389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->flags = 0; 50489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->channelCount= mChannelCount; 50589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->format = mFormat; 50689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->frameCount = framesReq; 507c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer->size = framesReq*cblk->frameSize; 50889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->raw = (int8_t*)cblk->buffer(u); 50989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project active = mActive; 51089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return active ? status_t(NO_ERROR) : status_t(STOPPED); 51189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 51289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 51389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioRecord::releaseBuffer(Buffer* audioBuffer) 51489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 51589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audio_track_cblk_t* cblk = mCblk; 51689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cblk->stepUser(audioBuffer->frameCount); 51789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 51889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 51989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 52089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 52189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t AudioRecord::read(void* buffer, size_t userSize) 52289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 52389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ssize_t read = 0; 52489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Buffer audioBuffer; 52589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int8_t *dst = static_cast<int8_t*>(buffer); 52689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 52789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (ssize_t(userSize) < 0) { 52889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // sanity-check. user is most-likely passing an error code. 52989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("AudioRecord::read(buffer=%p, size=%u (%d)", 53089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project buffer, userSize, userSize); 53189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 53289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 53389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 53489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("read size: %d", userSize); 53589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 53689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 53789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 538c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer.frameCount = userSize/frameSize(); 53989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 54089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Calling obtainBuffer() with a negative wait count causes 54189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // an (almost) infinite wait time. 54289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t err = obtainBuffer(&audioBuffer, -1); 54389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err < 0) { 54489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // out of buffers, return #bytes written 54589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err == status_t(NO_MORE_BUFFERS)) 54689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 54789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ssize_t(err); 54889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 54989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 55089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t bytesRead = audioBuffer.size; 55189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project memcpy(dst, audioBuffer.i8, bytesRead); 55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 55389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project dst += bytesRead; 55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project userSize -= bytesRead; 55589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project read += bytesRead; 55689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 55789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project releaseBuffer(&audioBuffer); 55889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } while (userSize); 55989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return read; 56189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 56389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 56589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) 56689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 56789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Buffer audioBuffer; 56889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t frames = mRemainingFrames; 56989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t readSize; 57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 57189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage marker callback 5727d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi if (!mMarkerReached && (mMarkerPosition > 0)) { 57389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mCblk->user >= mMarkerPosition) { 57489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); 5757d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = true; 57689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 57789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 57889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 57989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage new position callback 58089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mUpdatePeriod > 0) { 58189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (mCblk->user >= mNewPosition) { 58289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); 58389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition += mUpdatePeriod; 58489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 58589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 58689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 58789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 58889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer.frameCount = frames; 589c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // Calling obtainBuffer() with a wait count of 1 590c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // limits wait time to WAIT_PERIOD_MS. This prevents from being 59189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // stuck here not being able to handle timed events (position, markers). 59289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t err = obtainBuffer(&audioBuffer, 1); 59389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err < NO_ERROR) { 59489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err != TIMED_OUT) { 5951dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent LOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up."); 59689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return false; 59789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 59889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 59989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 60089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err == status_t(STOPPED)) return false; 60189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 60289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t reqSize = audioBuffer.size; 60389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 60489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project readSize = audioBuffer.size; 60589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 60689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Sanity check on returned size 607cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent if (ssize_t(readSize) <= 0) { 608cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // The callback is done filling buffers 609cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // Keep this thread going to handle timed events and 610cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // still try to get more data in intervals of WAIT_PERIOD_MS 611cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // but don't just loop and block the CPU, so wait 612cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent usleep(WAIT_PERIOD_MS*1000); 613cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent break; 614cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent } 61589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (readSize > reqSize) readSize = reqSize; 61689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 61789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer.size = readSize; 618c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer.frameCount = readSize/frameSize(); 61989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frames -= audioBuffer.frameCount; 62089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 62189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project releaseBuffer(&audioBuffer); 62289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 62389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } while (frames); 62489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 625c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 62689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage overrun callback 62789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mActive && (mCblk->framesAvailable_l() == 0)) { 62889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Overrun user: %x, server: %x, flowControlFlag %d", mCblk->user, mCblk->server, mCblk->flowControlFlag); 62989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mCblk->flowControlFlag == 0) { 63089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_OVERRUN, mUserData, 0); 63189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCblk->flowControlFlag = 1; 63289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 63389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 63489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 63589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (frames == 0) { 63689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = mNotificationFrames; 63789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 63889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = frames; 63989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 64089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return true; 64189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 64289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ========================================================================= 64489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava) 64689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project : Thread(bCanCallJava), mReceiver(receiver) 64789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 64889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 64989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 65089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::ClientRecordThread::threadLoop() 65189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 65289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mReceiver.processAudioBuffer(this); 65389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 65489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 65589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 65689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 65789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android 65889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 659