AudioRecord.cpp revision fce7a473248381cc83a01855f92581077d3c9ee2
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> 3838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent#include <utils/Atomic.h> 3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <hardware/audio.h> 41fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <cutils/bitops.h> 42fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 4389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) 4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) 4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android { 4715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh// --------------------------------------------------------------------------- 4815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 4915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh// static 5015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yehstatus_t AudioRecord::getMinFrameCount( 5115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh int* frameCount, 5215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh uint32_t sampleRate, 5315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh int format, 5415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh int channelCount) 5515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh{ 5615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh size_t size = 0; 5715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size) 5815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh != NO_ERROR) { 5915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh LOGE("AudioSystem could not query the input buffer size."); 6015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return NO_INIT; 6115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh } 6215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 6315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh if (size == 0) { 6415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh LOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d", 6515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh sampleRate, format, channelCount); 6615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return BAD_VALUE; 6715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh } 6815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 6915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh // We double the size of input buffer for ping pong use of record buffer. 7015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh size <<= 1; 7115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 72fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (audio_is_linear_pcm(format)) { 73fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin size /= channelCount * (format == AUDIO_FORMAT_PCM_16_BIT ? 2 : 1); 7415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh } 7515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 7615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh *frameCount = size; 7715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return NO_ERROR; 7815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh} 7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// --------------------------------------------------------------------------- 8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord() 83be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent : mStatus(NO_INIT), mSessionId(0) 8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord( 88f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent int inputSource, 8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t sampleRate, 9089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int format, 91c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent uint32_t channels, 9289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int frameCount, 9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t flags, 9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project callback_t cbf, 9589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project void* user, 96be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent int notificationFrames, 97be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent int sessionId) 98be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent : mStatus(NO_INIT), mSessionId(0) 9989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 100c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent mStatus = set(inputSource, sampleRate, format, channels, 101be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent frameCount, flags, cbf, user, notificationFrames, sessionId); 10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::~AudioRecord() 10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mStatus == NO_ERROR) { 10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Make sure that callback function exits in the case where 10889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // it is looping on buffer empty condition in obtainBuffer(). 10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Otherwise the callback thread will never exit. 11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project stop(); 11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mClientRecordThread != 0) { 11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mClientRecordThread->requestExitAndWait(); 11389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mClientRecordThread.clear(); 11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioRecord.clear(); 11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project IPCThreadState::self()->flushCommands(); 11789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 11889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 12089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::set( 121f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent int inputSource, 12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t sampleRate, 12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int format, 124c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent uint32_t channels, 12589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int frameCount, 12689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t flags, 12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project callback_t cbf, 12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project void* user, 12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int notificationFrames, 130be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent bool threadCanCallJava, 131be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent int sessionId) 13289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 134c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent LOGV("set(): sampleRate %d, channels %d, frameCount %d",sampleRate, channels, frameCount); 1351703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 1361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 1371703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 1381dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent if (mAudioRecord != 0) { 13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return INVALID_OPERATION; 14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 142c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (inputSource == AUDIO_SOURCE_DEFAULT) { 143c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent inputSource = AUDIO_SOURCE_MIC; 14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 14689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (sampleRate == 0) { 14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sampleRate = DEFAULT_SAMPLE_RATE; 14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // these below should probably come from the audioFlinger too... 15089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (format == 0) { 151fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin format = AUDIO_FORMAT_PCM_16_BIT; 15289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 153c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // validate parameters 154fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (!audio_is_valid_format(format)) { 155c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent LOGE("Invalid format"); 156c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return BAD_VALUE; 15789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 159fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (!audio_is_input_channel(channels)) { 16089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 162be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent 163fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int channelCount = popcount(channels); 164c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 1656100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent audio_io_handle_t input = AudioSystem::getInput(inputSource, 166fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin sampleRate, format, channels, (audio_in_acoustics_t)flags); 1676100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (input == 0) { 168148b266afe2ac92b5616c24e8d5160e6f9242f69Eric Laurent LOGE("Could not get audio input for record source %d", inputSource); 16989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 17089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 17189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 17289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // validate framecount 17315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh int minFrameCount = 0; 17415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelCount); 17515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh if (status != NO_ERROR) { 17615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return status; 177c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 17889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 17989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 18089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (frameCount == 0) { 18189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frameCount = minFrameCount; 18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (frameCount < minFrameCount) { 18389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 18489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 18589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 18689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (notificationFrames == 0) { 18789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project notificationFrames = frameCount/2; 18889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 18989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 190be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent mSessionId = sessionId; 191be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent 19234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent // create the IAudioRecord 1931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent status = openRecord_l(sampleRate, format, channelCount, 19415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh frameCount, flags, input); 19534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (status != NO_ERROR) { 19689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return status; 19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 19834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 19989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (cbf != 0) { 20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); 20189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mClientRecordThread == 0) { 20289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_INIT; 20389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 20489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 20589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mStatus = NO_ERROR; 20789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 20889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFormat = format; 20989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Update buffer size in case it has been limited by AudioFlinger during track creation 21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFrameCount = mCblk->frameCount; 211c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent mChannelCount = (uint8_t)channelCount; 2126100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mChannels = channels; 21389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mActive = 0; 21489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf = cbf; 21589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNotificationFrames = notificationFrames; 21689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = notificationFrames; 21789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUserData = user; 21889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // TODO: add audio hardware input latency here 219573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent mLatency = (1000*mFrameCount) / sampleRate; 22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMarkerPosition = 0; 2217d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition = 0; 22389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUpdatePeriod = 0; 224f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent mInputSource = (uint8_t)inputSource; 22534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mFlags = flags; 22605bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent mInput = input; 22789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 22889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 22989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 23189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::initCheck() const 23289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 23389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mStatus; 23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 23689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::latency() const 23989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mLatency; 24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::format() const 24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mFormat; 24689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::channelCount() const 24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mChannelCount; 25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::frameCount() const 25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mFrameCount; 25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::frameSize() const 25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 260fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (audio_is_linear_pcm(mFormat)) { 261fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin return channelCount()*((format() == AUDIO_FORMAT_PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t)); 262c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 263c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return sizeof(uint8_t); 264c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 26589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 26689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 267f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurentint AudioRecord::inputSource() const 268f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent{ 269f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent return (int)mInputSource; 270f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent} 271f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent 27289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::start() 27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 27689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t ret = NO_ERROR; 27789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<ClientRecordThread> t = mClientRecordThread; 27889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 27989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("start"); 28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t->exitPending()) { 28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t->requestExitAndWait() == WOULD_BLOCK) { 28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("AudioRecord::start called from thread"); 28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return WOULD_BLOCK; 28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 28789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 28889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->mLock.lock(); 28989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 29089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 291f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent AutoMutex lock(mLock); 2921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 2931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // while we are accessing the cblk 2941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent sp <IAudioRecord> audioRecord = mAudioRecord; 2951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent sp <IMemory> iMem = mCblkMemory; 2961703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent audio_track_cblk_t* cblk = mCblk; 297f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent if (mActive == 0) { 298f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent mActive = 1; 2991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 3001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 3011703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (!(cblk->flags & CBLK_INVALID_MSK)) { 3021703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 3031703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ret = mAudioRecord->start(); 3041703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 3051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (ret == DEAD_OBJECT) { 30638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent android_atomic_or(CBLK_INVALID_ON, &cblk->flags); 3076100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } 3086100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } 3091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (cblk->flags & CBLK_INVALID_MSK) { 3101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ret = restoreRecord_l(cblk); 3111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 3121703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 3136100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (ret == NO_ERROR) { 3141703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mNewPosition = cblk->user + mUpdatePeriod; 3151703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 3161703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->waitTimeMs = 0; 3176100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (t != 0) { 3186100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT); 319c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 3206100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT); 321c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 3226100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } else { 323f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent mActive = 0; 32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 32589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 32789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->mLock.unlock(); 32989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 33089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 33189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ret; 33289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 33389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 33489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::stop() 33589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 33689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<ClientRecordThread> t = mClientRecordThread; 33789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 33889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("stop"); 33989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 34089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 34189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->mLock.lock(); 342f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent } 34389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 344f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent AutoMutex lock(mLock); 345f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent if (mActive == 1) { 346f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent mActive = 0; 3471dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent mCblk->cv.signal(); 34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioRecord->stop(); 3497d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi // the record head position will reset to 0, so if a marker is set, we need 3507d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi // to activate it again 3517d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 35289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 35389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->requestExit(); 35489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 35589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL); 35689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 35789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 35889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 36089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->mLock.unlock(); 36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 36489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::stopped() const 36789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 36889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return !mActive; 36989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 371573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurentuint32_t AudioRecord::getSampleRate() 372573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent{ 3731703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 374573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent return mCblk->sampleRate; 375573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent} 376573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent 37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setMarkerPosition(uint32_t marker) 37889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mCbf == 0) return INVALID_OPERATION; 38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMarkerPosition = marker; 3827d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getMarkerPosition(uint32_t *marker) 38889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 38989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (marker == 0) return BAD_VALUE; 39089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *marker = mMarkerPosition; 39289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 39489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 39589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 39789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 39889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mCbf == 0) return INVALID_OPERATION; 39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t curPosition; 40189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project getPosition(&curPosition); 40289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition = curPosition + updatePeriod; 40389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUpdatePeriod = updatePeriod; 40489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 40689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) 40989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 41089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (updatePeriod == 0) return BAD_VALUE; 41189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *updatePeriod = mUpdatePeriod; 41389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::getPosition(uint32_t *position) 41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 41989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (position == 0) return BAD_VALUE; 42089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4211703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 42289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *position = mCblk->user; 42389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 42489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 42589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 42689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 42705bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurentunsigned int AudioRecord::getInputFramesLost() 42805bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent{ 42905bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent if (mActive) 43005bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent return AudioSystem::getInputFramesLost(mInput); 43105bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent else 43205bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent return 0; 43305bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent} 43489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 43589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 43689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4371703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held 4381703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t AudioRecord::openRecord_l( 43934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent uint32_t sampleRate, 44034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent int format, 44134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent int channelCount, 44234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent int frameCount, 4436100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent uint32_t flags, 4446100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent audio_io_handle_t input) 44534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent{ 44634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent status_t status; 44734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 44834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (audioFlinger == 0) { 44934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_INIT; 45034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 45134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 4526100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input, 45334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent sampleRate, format, 45434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent channelCount, 45534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent frameCount, 45634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent ((uint16_t)flags) << 16, 457be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent &mSessionId, 45834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent &status); 45934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (record == 0) { 46034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent LOGE("AudioFlinger could not create record track, status: %d", status); 46134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return status; 46234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 46334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent sp<IMemory> cblk = record->getCblk(); 46434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (cblk == 0) { 46534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent LOGE("Could not get control block"); 46634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_INIT; 46734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 46834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mAudioRecord.clear(); 46934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mAudioRecord = record; 47034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblkMemory.clear(); 47134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblkMemory = cblk; 47234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 47334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 47438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags); 4756100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 4766100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->waitTimeMs = 0; 47734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_ERROR; 47834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent} 47934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 48089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 48189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 4821703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 48389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int active; 48489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t result; 48589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audio_track_cblk_t* cblk = mCblk; 48689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t framesReq = audioBuffer->frameCount; 4871dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; 48889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 48989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->frameCount = 0; 49089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->size = 0; 49189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 49289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t framesReady = cblk->framesReady(); 49389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 49489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (framesReady == 0) { 49534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.lock(); 49689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto start_loop_here; 49789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (framesReady == 0) { 49889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project active = mActive; 49934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (UNLIKELY(!active)) { 50034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 50189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_MORE_BUFFERS; 50234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 50334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (UNLIKELY(!waitCount)) { 50434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 50589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return WOULD_BLOCK; 50634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 5071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (!(cblk->flags & CBLK_INVALID_MSK)) { 5081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 5091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); 5101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 5111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 5121703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (mActive == 0) { 5131703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent return status_t(STOPPED); 5141703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 5151703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 5161703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 5171703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (cblk->flags & CBLK_INVALID_MSK) { 5181703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent goto create_new_record; 5191703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 52089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (__builtin_expect(result!=NO_ERROR, false)) { 5211dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent cblk->waitTimeMs += waitTimeMs; 52289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 52389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGW( "obtainBuffer timed out (is the CPU pegged?) " 52489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project "user=%08x, server=%08x", cblk->user, cblk->server); 52534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 52634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent result = mAudioRecord->start(); 5271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 52834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (result == DEAD_OBJECT) { 52938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent android_atomic_or(CBLK_INVALID_ON, &cblk->flags); 5301703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentcreate_new_record: 5311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = AudioRecord::restoreRecord_l(cblk); 5321703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 5331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result != NO_ERROR) { 5341703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent LOGW("obtainBuffer create Track error %d", result); 5351703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 5361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent return result; 53734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 53889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cblk->waitTimeMs = 0; 53989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 54089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (--waitCount == 0) { 54134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 54289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return TIMED_OUT; 54389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 54489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 54589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // read the server count again 54689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project start_loop_here: 54789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReady = cblk->framesReady(); 54889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 54934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 55089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 55189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cblk->waitTimeMs = 0; 553c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (framesReq > framesReady) { 55589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReq = framesReady; 55689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 55789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 55889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t u = cblk->user; 55989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 56189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (u + framesReq > bufferEnd) { 56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReq = bufferEnd - u; 56389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 56589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->flags = 0; 56689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->channelCount= mChannelCount; 56789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->format = mFormat; 56889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->frameCount = framesReq; 569c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer->size = framesReq*cblk->frameSize; 57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->raw = (int8_t*)cblk->buffer(u); 57189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project active = mActive; 57289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return active ? status_t(NO_ERROR) : status_t(STOPPED); 57389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 57489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 57589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioRecord::releaseBuffer(Buffer* audioBuffer) 57689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 5771703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 5781703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mCblk->stepUser(audioBuffer->frameCount); 57989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 58089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 5816100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurentaudio_io_handle_t AudioRecord::getInput() 5826100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent{ 5831703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 5841703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent return getInput_l(); 5851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent} 5861703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 5871703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held 5881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentaudio_io_handle_t AudioRecord::getInput_l() 5891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{ 59005bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent mInput = AudioSystem::getInput(mInputSource, 5916100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->sampleRate, 5926100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mFormat, mChannels, 593fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin (audio_in_acoustics_t)mFlags); 59405bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent return mInput; 5956100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent} 5966100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent 597be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentint AudioRecord::getSessionId() 598be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent{ 599be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent return mSessionId; 600be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent} 601be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent 60289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 60389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 60489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t AudioRecord::read(void* buffer, size_t userSize) 60589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 60689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ssize_t read = 0; 60789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Buffer audioBuffer; 60889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int8_t *dst = static_cast<int8_t*>(buffer); 60989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 61089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (ssize_t(userSize) < 0) { 61189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // sanity-check. user is most-likely passing an error code. 61289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("AudioRecord::read(buffer=%p, size=%u (%d)", 61389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project buffer, userSize, userSize); 61489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 61589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 61689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6171703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 6181703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 6191703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // while we are accessing the cblk 6201703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent sp <IAudioRecord> audioRecord = mAudioRecord; 6211703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent sp <IMemory> iMem = mCblkMemory; 6221703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 62389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 62489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 62589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 626c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer.frameCount = userSize/frameSize(); 62789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 62888335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // By using a wait count corresponding to twice the timeout period in 62988335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // obtainBuffer() we give a chance to recover once for a read timeout 63088335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // (if media_server crashed for instance) before returning a length of 63188335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // 0 bytes read to the client 63288335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS)); 63389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err < 0) { 63489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // out of buffers, return #bytes written 63589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err == status_t(NO_MORE_BUFFERS)) 63689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 63788335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent if (err == status_t(TIMED_OUT)) 63888335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent err = 0; 63989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ssize_t(err); 64089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 64189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t bytesRead = audioBuffer.size; 64389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project memcpy(dst, audioBuffer.i8, bytesRead); 64489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project dst += bytesRead; 64689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project userSize -= bytesRead; 64789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project read += bytesRead; 64889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project releaseBuffer(&audioBuffer); 65089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } while (userSize); 65189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 65289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return read; 65389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 65489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 65589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 65689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 65789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) 65889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 65989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Buffer audioBuffer; 66089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t frames = mRemainingFrames; 66189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t readSize; 66289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6631703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 6641703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 6651703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // while we are accessing the cblk 6661703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent sp <IAudioRecord> audioRecord = mAudioRecord; 6671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent sp <IMemory> iMem = mCblkMemory; 6681703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent audio_track_cblk_t* cblk = mCblk; 6691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 6701703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 67189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage marker callback 6727d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi if (!mMarkerReached && (mMarkerPosition > 0)) { 6731703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (cblk->user >= mMarkerPosition) { 67489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); 6757d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = true; 67689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 67789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 67889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 67989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage new position callback 68089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mUpdatePeriod > 0) { 6811703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent while (cblk->user >= mNewPosition) { 68289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); 68389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition += mUpdatePeriod; 68489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 68589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 68689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 68789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 68889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer.frameCount = frames; 689c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // Calling obtainBuffer() with a wait count of 1 690c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // limits wait time to WAIT_PERIOD_MS. This prevents from being 69189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // stuck here not being able to handle timed events (position, markers). 69289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t err = obtainBuffer(&audioBuffer, 1); 69389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err < NO_ERROR) { 69489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err != TIMED_OUT) { 6951dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent LOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up."); 69689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return false; 69789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 69889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 69989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 70089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err == status_t(STOPPED)) return false; 70189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 70289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t reqSize = audioBuffer.size; 70389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 70489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project readSize = audioBuffer.size; 70589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 70689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Sanity check on returned size 707cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent if (ssize_t(readSize) <= 0) { 708cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // The callback is done filling buffers 709cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // Keep this thread going to handle timed events and 710cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // still try to get more data in intervals of WAIT_PERIOD_MS 711cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // but don't just loop and block the CPU, so wait 712cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent usleep(WAIT_PERIOD_MS*1000); 713cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent break; 714cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent } 71589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (readSize > reqSize) readSize = reqSize; 71689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 71789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer.size = readSize; 718c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer.frameCount = readSize/frameSize(); 71989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frames -= audioBuffer.frameCount; 72089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 72189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project releaseBuffer(&audioBuffer); 72289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 72389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } while (frames); 72489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 725c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 72689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage overrun callback 7271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (mActive && (cblk->framesAvailable() == 0)) { 7281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent LOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); 72938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) { 73033797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent mCbf(EVENT_OVERRUN, mUserData, 0); 73189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 73289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 73389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 73489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (frames == 0) { 73589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = mNotificationFrames; 73689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 73789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = frames; 73889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 73989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return true; 74089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 74189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7421703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock and cblk.lock held. Callers must also hold strong references on 7431703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// the IAudioRecord and IMemory in case they are recreated here. 7441703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// If the IAudioRecord is successfully restored, the cblk pointer is updated 7451703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) 7461703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{ 7471703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent status_t result; 7481703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 74938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { 7501703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent LOGW("dead IAudioRecord, creating a new one"); 7511703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // signal old cblk condition so that other threads waiting for available buffers stop 7521703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // waiting now 7531703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->cv.broadcast(); 7541703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 7551703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 7561703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // if the new IAudioRecord is created, openRecord_l() will modify the 7571703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // following member variables: mAudioRecord, mCblkMemory and mCblk. 7581703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // It will also delete the strong references on previous IAudioRecord and IMemory 7591703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = openRecord_l(cblk->sampleRate, mFormat, mChannelCount, 7601703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mFrameCount, mFlags, getInput_l()); 7611703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result == NO_ERROR) { 7621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = mAudioRecord->start(); 7631703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7641703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result != NO_ERROR) { 7651703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mActive = false; 7661703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 7681703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // signal old cblk condition for other threads waiting for restore completion 76938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); 7701703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->cv.broadcast(); 7711703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } else { 7721703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (!(cblk->flags & CBLK_RESTORED_MSK)) { 7731703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent LOGW("dead IAudioRecord, waiting for a new one to be created"); 7741703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 7751703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS)); 7761703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 7771703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 7781703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } else { 7791703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent LOGW("dead IAudioRecord, already restored"); 7801703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = NO_ERROR; 7811703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 7821703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7831703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result != NO_ERROR || mActive == 0) { 7841703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = status_t(STOPPED); 7851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7861703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7871703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent LOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x", 7881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result, mActive, mCblk, cblk, mCblk->flags, cblk->flags); 7891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 7901703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result == NO_ERROR) { 7911703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // from now on we switch to the newly created cblk 7921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk = mCblk; 7931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 7951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 7961703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent LOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result); 7971703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 7981703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent return result; 7991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent} 8001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 80189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ========================================================================= 80289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 80389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava) 80489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project : Thread(bCanCallJava), mReceiver(receiver) 80589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 80689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 80789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 80889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::ClientRecordThread::threadLoop() 80989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 81089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mReceiver.processAudioBuffer(this); 81189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 81289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 81389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 81489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 81589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android 81689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 817