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