AudioRecord.cpp revision f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0
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); 1311dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent if (mAudioRecord != 0) { 13289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return INVALID_OPERATION; 13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 135c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (inputSource == AUDIO_SOURCE_DEFAULT) { 136c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent inputSource = AUDIO_SOURCE_MIC; 13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 13889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (sampleRate == 0) { 14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sampleRate = DEFAULT_SAMPLE_RATE; 14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // these below should probably come from the audioFlinger too... 14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (format == 0) { 14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project format = AudioSystem::PCM_16_BIT; 14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 146c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // validate parameters 147c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (!AudioSystem::isValidFormat(format)) { 148c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent LOGE("Invalid format"); 149c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return BAD_VALUE; 15089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 15189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 152c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (!AudioSystem::isInputChannel(channels)) { 15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 155be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent 156c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent int channelCount = AudioSystem::popCount(channels); 157c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 1586100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent audio_io_handle_t input = AudioSystem::getInput(inputSource, 159c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags); 1606100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (input == 0) { 161148b266afe2ac92b5616c24e8d5160e6f9242f69Eric Laurent LOGE("Could not get audio input for record source %d", inputSource); 16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 16389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 16489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // validate framecount 16615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh int minFrameCount = 0; 16715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelCount); 16815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh if (status != NO_ERROR) { 16915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return status; 170c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 17189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 17289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 17389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (frameCount == 0) { 17489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frameCount = minFrameCount; 17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (frameCount < minFrameCount) { 17689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 17889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 17989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (notificationFrames == 0) { 18089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project notificationFrames = frameCount/2; 18189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 183be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent mSessionId = sessionId; 184be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent 18534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent // create the IAudioRecord 18615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh status = openRecord(sampleRate, format, channelCount, 18715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh frameCount, flags, input); 18834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (status != NO_ERROR) { 18989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return status; 19089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 19134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 19289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (cbf != 0) { 19389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); 19489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mClientRecordThread == 0) { 19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_INIT; 19689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 19889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 19989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mStatus = NO_ERROR; 20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 20189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFormat = format; 20289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Update buffer size in case it has been limited by AudioFlinger during track creation 20389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFrameCount = mCblk->frameCount; 204c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent mChannelCount = (uint8_t)channelCount; 2056100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mChannels = channels; 20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mActive = 0; 20789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf = cbf; 20889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNotificationFrames = notificationFrames; 20989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = notificationFrames; 21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUserData = user; 21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // TODO: add audio hardware input latency here 212573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent mLatency = (1000*mFrameCount) / sampleRate; 21389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMarkerPosition = 0; 2147d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 21589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition = 0; 21689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUpdatePeriod = 0; 217f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent mInputSource = (uint8_t)inputSource; 21834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mFlags = flags; 21905bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent mInput = input; 22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 22189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 22389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 22489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::initCheck() const 22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 22689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mStatus; 22789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 22889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 22989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 23189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::latency() const 23289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 23389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mLatency; 23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 23689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::format() const 23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mFormat; 23989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::channelCount() const 24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mChannelCount; 24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 24689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::frameCount() const 24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mFrameCount; 24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::frameSize() const 25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 253c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (AudioSystem::isLinearPCM(mFormat)) { 254c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t)); 255c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 256c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return sizeof(uint8_t); 257c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 260f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurentint AudioRecord::inputSource() const 261f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent{ 262f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent return (int)mInputSource; 263f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent} 264f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent 26589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 26689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::start() 26889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 26989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t ret = NO_ERROR; 27089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<ClientRecordThread> t = mClientRecordThread; 27189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 27289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("start"); 27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t->exitPending()) { 27689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t->requestExitAndWait() == WOULD_BLOCK) { 27789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("AudioRecord::start called from thread"); 27889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return WOULD_BLOCK; 27989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->mLock.lock(); 28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 284f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent AutoMutex lock(mLock); 285f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent if (mActive == 0) { 286f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent mActive = 1; 2876100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent ret = mAudioRecord->start(); 2886100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (ret == DEAD_OBJECT) { 2896100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent LOGV("start() dead IAudioRecord: creating a new one"); 2906100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount, 2916100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mFrameCount, mFlags, getInput()); 29234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (ret == NO_ERROR) { 2936100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent ret = mAudioRecord->start(); 2946100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } 2956100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } 2966100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (ret == NO_ERROR) { 2976100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mNewPosition = mCblk->user + mUpdatePeriod; 2986100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 2996100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->waitTimeMs = 0; 3006100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (t != 0) { 3016100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT); 302c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 3036100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT); 304c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 3056100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } else { 306f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent mActive = 0; 30789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 30889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 30989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 31089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 31189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->mLock.unlock(); 31289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 31389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 31489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ret; 31589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 31689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 31789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::stop() 31889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 31989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<ClientRecordThread> t = mClientRecordThread; 32089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 32189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("stop"); 32289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->mLock.lock(); 325f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent } 32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 327f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent AutoMutex lock(mLock); 328f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent if (mActive == 1) { 329f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent mActive = 0; 3301dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent mCblk->cv.signal(); 33189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioRecord->stop(); 3327d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi // the record head position will reset to 0, so if a marker is set, we need 3337d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi // to activate it again 3347d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 33589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 33689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->requestExit(); 33789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 33889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL); 33989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 34089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 34189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 34289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 34389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->mLock.unlock(); 34489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 34589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 34689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 34789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 34989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::stopped() const 35089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 35189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return !mActive; 35289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 35389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 354573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurentuint32_t AudioRecord::getSampleRate() 355573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent{ 356573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent return mCblk->sampleRate; 357573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent} 358573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent 35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setMarkerPosition(uint32_t marker) 36089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mCbf == 0) return INVALID_OPERATION; 36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMarkerPosition = marker; 3647d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 36789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 36889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getMarkerPosition(uint32_t *marker) 37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 37189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (marker == 0) return BAD_VALUE; 37289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *marker = mMarkerPosition; 37489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 37689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mCbf == 0) return INVALID_OPERATION; 38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t curPosition; 38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project getPosition(&curPosition); 38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition = curPosition + updatePeriod; 38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUpdatePeriod = updatePeriod; 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 Projectstatus_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) 39189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 39289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (updatePeriod == 0) return BAD_VALUE; 39389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *updatePeriod = mUpdatePeriod; 39589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 39789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 39889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getPosition(uint32_t *position) 40089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 40189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (position == 0) return BAD_VALUE; 40289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *position = mCblk->user; 40489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 40689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40805bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurentunsigned int AudioRecord::getInputFramesLost() 40905bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent{ 41005bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent if (mActive) 41105bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent return AudioSystem::getInputFramesLost(mInput); 41205bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent else 41305bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent return 0; 41405bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent} 41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 41789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurentstatus_t AudioRecord::openRecord( 41934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent uint32_t sampleRate, 42034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent int format, 42134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent int channelCount, 42234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent int frameCount, 4236100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent uint32_t flags, 4246100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent audio_io_handle_t input) 42534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent{ 42634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent status_t status; 42734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 42834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (audioFlinger == 0) { 42934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_INIT; 43034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 43134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 4326100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input, 43334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent sampleRate, format, 43434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent channelCount, 43534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent frameCount, 43634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent ((uint16_t)flags) << 16, 437be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent &mSessionId, 43834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent &status); 43934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (record == 0) { 44034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent LOGE("AudioFlinger could not create record track, status: %d", status); 44134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return status; 44234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 44334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent sp<IMemory> cblk = record->getCblk(); 44434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (cblk == 0) { 44534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent LOGE("Could not get control block"); 44634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_INIT; 44734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 44834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mAudioRecord.clear(); 44934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mAudioRecord = record; 45034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblkMemory.clear(); 45134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblkMemory = cblk; 45234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 45334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 454d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent mCblk->flags &= ~CBLK_DIRECTION_MSK; 4556100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 4566100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->waitTimeMs = 0; 45734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_ERROR; 45834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent} 45934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 46089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 46189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 46289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int active; 46389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t result; 46489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audio_track_cblk_t* cblk = mCblk; 46589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t framesReq = audioBuffer->frameCount; 4661dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; 46789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 46889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->frameCount = 0; 46989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->size = 0; 47089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 47189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t framesReady = cblk->framesReady(); 47289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 47389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (framesReady == 0) { 47434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.lock(); 47589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto start_loop_here; 47689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (framesReady == 0) { 47789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project active = mActive; 47834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (UNLIKELY(!active)) { 47934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 48089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_MORE_BUFFERS; 48134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 48234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (UNLIKELY(!waitCount)) { 48334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 48489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return WOULD_BLOCK; 48534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 4861dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); 48789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (__builtin_expect(result!=NO_ERROR, false)) { 4881dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent cblk->waitTimeMs += waitTimeMs; 48989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 49089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGW( "obtainBuffer timed out (is the CPU pegged?) " 49189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project "user=%08x, server=%08x", cblk->user, cblk->server); 49234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 49334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent result = mAudioRecord->start(); 49434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (result == DEAD_OBJECT) { 49534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent LOGW("obtainBuffer() dead IAudioRecord: creating a new one"); 49634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent result = openRecord(cblk->sampleRate, mFormat, mChannelCount, 4976100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mFrameCount, mFlags, getInput()); 49834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (result == NO_ERROR) { 49934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk = mCblk; 5006100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mAudioRecord->start(); 50134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 50234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 50334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.lock(); 50489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cblk->waitTimeMs = 0; 50589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 50689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (--waitCount == 0) { 50734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 50889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return TIMED_OUT; 50989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 51089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 51189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // read the server count again 51289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project start_loop_here: 51389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReady = cblk->framesReady(); 51489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 51534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 51689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 51789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 51889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cblk->waitTimeMs = 0; 519c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 52089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (framesReq > framesReady) { 52189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReq = framesReady; 52289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 52389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 52489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t u = cblk->user; 52589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 52689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 52789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (u + framesReq > bufferEnd) { 52889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReq = bufferEnd - u; 52989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 53089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 53189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->flags = 0; 53289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->channelCount= mChannelCount; 53389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->format = mFormat; 53489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->frameCount = framesReq; 535c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer->size = framesReq*cblk->frameSize; 53689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->raw = (int8_t*)cblk->buffer(u); 53789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project active = mActive; 53889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return active ? status_t(NO_ERROR) : status_t(STOPPED); 53989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 54089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 54189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioRecord::releaseBuffer(Buffer* audioBuffer) 54289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 54389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audio_track_cblk_t* cblk = mCblk; 54489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cblk->stepUser(audioBuffer->frameCount); 54589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 54689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 5476100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurentaudio_io_handle_t AudioRecord::getInput() 5486100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent{ 54905bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent mInput = AudioSystem::getInput(mInputSource, 5506100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->sampleRate, 5516100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mFormat, mChannels, 5526100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent (AudioSystem::audio_in_acoustics)mFlags); 55305bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent return mInput; 5546100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent} 5556100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent 556be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentint AudioRecord::getSessionId() 557be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent{ 558be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent return mSessionId; 559be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent} 560be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent 56189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 56389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t AudioRecord::read(void* buffer, size_t userSize) 56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 56589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ssize_t read = 0; 56689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Buffer audioBuffer; 56789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int8_t *dst = static_cast<int8_t*>(buffer); 56889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 56989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (ssize_t(userSize) < 0) { 57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // sanity-check. user is most-likely passing an error code. 57189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("AudioRecord::read(buffer=%p, size=%u (%d)", 57289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project buffer, userSize, userSize); 57389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 57489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 57589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 57689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 57789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 57889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 579c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer.frameCount = userSize/frameSize(); 58089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 58188335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // By using a wait count corresponding to twice the timeout period in 58288335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // obtainBuffer() we give a chance to recover once for a read timeout 58388335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // (if media_server crashed for instance) before returning a length of 58488335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // 0 bytes read to the client 58588335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS)); 58689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err < 0) { 58789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // out of buffers, return #bytes written 58889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err == status_t(NO_MORE_BUFFERS)) 58989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 59088335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent if (err == status_t(TIMED_OUT)) 59188335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent err = 0; 59289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ssize_t(err); 59389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 59489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 59589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t bytesRead = audioBuffer.size; 59689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project memcpy(dst, audioBuffer.i8, bytesRead); 59789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 59889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project dst += bytesRead; 59989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project userSize -= bytesRead; 60089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project read += bytesRead; 60189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 60289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project releaseBuffer(&audioBuffer); 60389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } while (userSize); 60489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 60589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return read; 60689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 60789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 60889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 60989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 61089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) 61189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 61289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Buffer audioBuffer; 61389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t frames = mRemainingFrames; 61489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t readSize; 61589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 61689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage marker callback 6177d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi if (!mMarkerReached && (mMarkerPosition > 0)) { 61889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mCblk->user >= mMarkerPosition) { 61989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); 6207d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = true; 62189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 62289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 62389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 62489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage new position callback 62589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mUpdatePeriod > 0) { 62689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (mCblk->user >= mNewPosition) { 62789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); 62889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition += mUpdatePeriod; 62989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 63089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 63189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 63289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 63389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer.frameCount = frames; 634c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // Calling obtainBuffer() with a wait count of 1 635c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // limits wait time to WAIT_PERIOD_MS. This prevents from being 63689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // stuck here not being able to handle timed events (position, markers). 63789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t err = obtainBuffer(&audioBuffer, 1); 63889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err < NO_ERROR) { 63989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err != TIMED_OUT) { 6401dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent LOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up."); 64189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return false; 64289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 64389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 64489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 64589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err == status_t(STOPPED)) return false; 64689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t reqSize = audioBuffer.size; 64889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 64989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project readSize = audioBuffer.size; 65089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 65189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Sanity check on returned size 652cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent if (ssize_t(readSize) <= 0) { 653cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // The callback is done filling buffers 654cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // Keep this thread going to handle timed events and 655cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // still try to get more data in intervals of WAIT_PERIOD_MS 656cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // but don't just loop and block the CPU, so wait 657cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent usleep(WAIT_PERIOD_MS*1000); 658cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent break; 659cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent } 66089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (readSize > reqSize) readSize = reqSize; 66189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 66289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer.size = readSize; 663c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer.frameCount = readSize/frameSize(); 66489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frames -= audioBuffer.frameCount; 66589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 66689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project releaseBuffer(&audioBuffer); 66789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 66889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } while (frames); 66989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 670c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 67189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage overrun callback 67289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mActive && (mCblk->framesAvailable_l() == 0)) { 673d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent LOGV("Overrun user: %x, server: %x, flags %04x", mCblk->user, mCblk->server, mCblk->flags); 674d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent if ((mCblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) { 67589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_OVERRUN, mUserData, 0); 676d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent mCblk->flags |= CBLK_UNDERRUN_ON; 67789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 67889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 67989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 68089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (frames == 0) { 68189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = mNotificationFrames; 68289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 68389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = frames; 68489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 68589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return true; 68689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 68789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 68889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ========================================================================= 68989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 69089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava) 69189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project : Thread(bCanCallJava), mReceiver(receiver) 69289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 69389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 69489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 69589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::ClientRecordThread::threadLoop() 69689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 69789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mReceiver.processAudioBuffer(this); 69889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 69989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 70089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 70189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 70289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android 70389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 704