AudioRecord.cpp revision 2986460984580833161bdaabc7f17da1005a8961
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 4064760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h> 41fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <cutils/bitops.h> 42f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten#include <cutils/compiler.h> 4389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android { 4515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh// --------------------------------------------------------------------------- 4615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 4715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh// static 4815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yehstatus_t AudioRecord::getMinFrameCount( 4915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh int* frameCount, 5015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh uint32_t sampleRate, 5158f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten audio_format_t format, 5215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh int channelCount) 5315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh{ 5415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh size_t size = 0; 5515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size) 5615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh != NO_ERROR) { 5729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("AudioSystem could not query the input buffer size."); 5815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return NO_INIT; 5915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh } 6015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 6115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh if (size == 0) { 6229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d", 6315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh sampleRate, format, channelCount); 6415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return BAD_VALUE; 6515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh } 6615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 6715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh // We double the size of input buffer for ping pong use of record buffer. 6815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh size <<= 1; 6915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 70fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (audio_is_linear_pcm(format)) { 71671a636931295d9c33ffca74551a804479d01241Eric Laurent size /= channelCount * audio_bytes_per_sample(format); 7215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh } 7315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 7415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh *frameCount = size; 7515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return NO_ERROR; 7615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh} 7789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// --------------------------------------------------------------------------- 7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord() 81879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten : mStatus(NO_INIT), mSessionId(0), 82a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) 8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord( 87eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten audio_source_t inputSource, 8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t sampleRate, 8958f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten audio_format_t format, 900d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi uint32_t channelMask, 9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int frameCount, 92679ab0b0792846a89162ce41c953819d70030112Glenn Kasten record_flags flags, 9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project callback_t cbf, 9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project void* user, 95be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent int notificationFrames, 96be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent int sessionId) 97879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten : mStatus(NO_INIT), mSessionId(0), 98a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) 9989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 1000d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi mStatus = set(inputSource, sampleRate, format, channelMask, 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(); 1173a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen AudioSystem::releaseAudioSessionId(mSessionId); 11889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 12089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 12189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::set( 122eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten audio_source_t inputSource, 12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t sampleRate, 12458f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten audio_format_t format, 1250d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi uint32_t channelMask, 12689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int frameCount, 127679ab0b0792846a89162ce41c953819d70030112Glenn Kasten record_flags flags, 12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project callback_t cbf, 12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project void* user, 13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int notificationFrames, 131be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent bool threadCanCallJava, 132be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent int sessionId) 13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("set(): sampleRate %d, channelMask %d, frameCount %d",sampleRate, channelMask, frameCount); 1361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 1371703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 1381703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 1391dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent if (mAudioRecord != 0) { 14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return INVALID_OPERATION; 14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 143c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (inputSource == AUDIO_SOURCE_DEFAULT) { 144c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent inputSource = AUDIO_SOURCE_MIC; 14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (sampleRate == 0) { 14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sampleRate = DEFAULT_SAMPLE_RATE; 14989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 15089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // these below should probably come from the audioFlinger too... 15158f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten if (format == AUDIO_FORMAT_DEFAULT) { 152fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin format = AUDIO_FORMAT_PCM_16_BIT; 15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 154c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // validate parameters 155fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (!audio_is_valid_format(format)) { 15629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid format"); 157c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return BAD_VALUE; 15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1600d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi if (!audio_is_input_channel(channelMask)) { 16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 163be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent 1640d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi int channelCount = popcount(channelMask); 165c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 1667c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent if (sessionId == 0 ) { 1677c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mSessionId = AudioSystem::newAudioSessionId(); 1687c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent } else { 1697c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mSessionId = sessionId; 1707c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent } 1713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("set(): mSessionId %d", mSessionId); 1727c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent 1736100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent audio_io_handle_t input = AudioSystem::getInput(inputSource, 1747c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent sampleRate, 1757c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent format, 1767c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent channelMask, 1777c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent (audio_in_acoustics_t)flags, 1787c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mSessionId); 1796100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (input == 0) { 18029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Could not get audio input for record source %d", inputSource); 18189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 18389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 18489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // validate framecount 18515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh int minFrameCount = 0; 18615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelCount); 18715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh if (status != NO_ERROR) { 18815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return status; 189c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 1903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 19189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 19289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (frameCount == 0) { 19389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frameCount = minFrameCount; 19489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (frameCount < minFrameCount) { 19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 19689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 19889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (notificationFrames == 0) { 19989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project notificationFrames = frameCount/2; 20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 20189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 20234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent // create the IAudioRecord 2030d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi status = openRecord_l(sampleRate, format, channelMask, 204a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten frameCount, input); 20534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (status != NO_ERROR) { 20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return status; 20789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 20834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 209a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (cbf != NULL) { 21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); 21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 21389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mStatus = NO_ERROR; 21489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 21589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFormat = format; 21689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Update buffer size in case it has been limited by AudioFlinger during track creation 21789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFrameCount = mCblk->frameCount; 218c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent mChannelCount = (uint8_t)channelCount; 2190d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi mChannelMask = channelMask; 22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mActive = 0; 22189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf = cbf; 22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNotificationFrames = notificationFrames; 22389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = notificationFrames; 22489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUserData = user; 22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // TODO: add audio hardware input latency here 226573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent mLatency = (1000*mFrameCount) / sampleRate; 22789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMarkerPosition = 0; 2287d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 22989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition = 0; 23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUpdatePeriod = 0; 231eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten mInputSource = inputSource; 23234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mFlags = flags; 23305bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent mInput = input; 2343a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen AudioSystem::acquireAudioSessionId(mSessionId); 23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 23689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 23989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::initCheck() const 24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mStatus; 24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 24689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::latency() const 24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mLatency; 24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25158f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kastenaudio_format_t AudioRecord::format() const 25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mFormat; 25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::channelCount() const 25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mChannelCount; 25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 26089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 26189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::frameCount() const 26289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 26389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mFrameCount; 26489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 26589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 266b9980659501d0428d65d8292f3c32da69d37fbd2Glenn Kastensize_t AudioRecord::frameSize() const 26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 268fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (audio_is_linear_pcm(mFormat)) { 269671a636931295d9c33ffca74551a804479d01241Eric Laurent return channelCount()*audio_bytes_per_sample(mFormat); 270c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 271c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return sizeof(uint8_t); 272c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 275eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kastenaudio_source_t AudioRecord::inputSource() const 276f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent{ 277eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten return mInputSource; 278f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent} 279f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent 28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 282a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentstatus_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession) 28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t ret = NO_ERROR; 28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<ClientRecordThread> t = mClientRecordThread; 28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 287a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent ALOGV("start, sync event %d trigger session %d", event, triggerSession); 28889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 28989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 29089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t->exitPending()) { 29189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t->requestExitAndWait() == WOULD_BLOCK) { 29229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("AudioRecord::start called from thread"); 29389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return WOULD_BLOCK; 29489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 29589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 296e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } 29789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 298f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent AutoMutex lock(mLock); 2991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 3001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // while we are accessing the cblk 301e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IAudioRecord> audioRecord = mAudioRecord; 302e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IMemory> iMem = mCblkMemory; 3031703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent audio_track_cblk_t* cblk = mCblk; 304f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent if (mActive == 0) { 305f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent mActive = 1; 3061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 3076dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten pid_t tid; 3086dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten if (t != 0) { 3096dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten mReadyToRun = WOULD_BLOCK; 310480b46802bef1371d5caa16ad5454fce04769c57Glenn Kasten t->run("AudioRecord", ANDROID_PRIORITY_AUDIO); 3116dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten tid = t->getTid(); // pid_t is unknown until run() 3126dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten ALOGV("getTid=%d", tid); 3136dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten if (tid == -1) { 3146dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten tid = 0; 3156dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten } 3166dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten // thread blocks in readyToRun() 3176dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten } else { 3186dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten tid = 0; // not gettid() 3196dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten } 3206dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten 3211703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 3221703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (!(cblk->flags & CBLK_INVALID_MSK)) { 3231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 3243acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten ALOGV("mAudioRecord->start()"); 3253acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten ret = mAudioRecord->start(event, triggerSession); 3261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 3271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (ret == DEAD_OBJECT) { 32838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent android_atomic_or(CBLK_INVALID_ON, &cblk->flags); 3296100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } 3306100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } 3311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (cblk->flags & CBLK_INVALID_MSK) { 3321703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ret = restoreRecord_l(cblk); 3331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 3341703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 3356100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (ret == NO_ERROR) { 3361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mNewPosition = cblk->user + mUpdatePeriod; 3372986460984580833161bdaabc7f17da1005a8961Eric Laurent cblk->bufferTimeoutMs = (event == AudioSystem::SYNC_EVENT_NONE) ? MAX_RUN_TIMEOUT_MS : 3382986460984580833161bdaabc7f17da1005a8961Eric Laurent AudioSystem::kSyncRecordStartTimeOutMs; 3391703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->waitTimeMs = 0; 3406100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (t != 0) { 3416dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten // thread unblocks in readyToRun() and returns NO_ERROR 3426dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten mReadyToRun = NO_ERROR; 3436dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten mCondition.signal(); 344c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 345879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten mPreviousPriority = getpriority(PRIO_PROCESS, 0); 346a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten get_sched_policy(0, &mPreviousSchedulingGroup); 347879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); 348c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 3496100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } else { 350f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent mActive = 0; 3516dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten // thread unblocks in readyToRun() and returns NO_INIT 3526dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten mReadyToRun = NO_INIT; 3536dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten mCondition.signal(); 35489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 35589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 35689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 35789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ret; 35889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::stop() 36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<ClientRecordThread> t = mClientRecordThread; 36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("stop"); 36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 366f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent AutoMutex lock(mLock); 367f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent if (mActive == 1) { 368f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent mActive = 0; 3691dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent mCblk->cv.signal(); 37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioRecord->stop(); 3717d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi // the record head position will reset to 0, so if a marker is set, we need 3727d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi // to activate it again 3737d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 37489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project t->requestExit(); 37689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 377879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten setpriority(PRIO_PROCESS, 0, mPreviousPriority); 378a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten set_sched_policy(0, mPreviousSchedulingGroup); 37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::stopped() const 38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return !mActive; 38889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 38989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 390606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenuint32_t AudioRecord::getSampleRate() const 391573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent{ 3921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 393573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent return mCblk->sampleRate; 394573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent} 395573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent 39689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setMarkerPosition(uint32_t marker) 39789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 398a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (mCbf == NULL) return INVALID_OPERATION; 39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMarkerPosition = marker; 4017d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 40289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 40489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 406606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getMarkerPosition(uint32_t *marker) const 40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 408a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (marker == NULL) return BAD_VALUE; 40989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *marker = mMarkerPosition; 41189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 41389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 41489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 417a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (mCbf == NULL) return INVALID_OPERATION; 41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t curPosition; 42089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project getPosition(&curPosition); 42189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition = curPosition + updatePeriod; 42289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUpdatePeriod = updatePeriod; 42389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 42489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 42589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 42689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 427606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const 42889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 429a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (updatePeriod == NULL) return BAD_VALUE; 43089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 43189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *updatePeriod = mUpdatePeriod; 43289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 43389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 43489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 43589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 436606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getPosition(uint32_t *position) const 43789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 438a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (position == NULL) return BAD_VALUE; 43989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4401703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 44189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *position = mCblk->user; 44289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 44389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 44489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 44589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 446606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenunsigned int AudioRecord::getInputFramesLost() const 44705bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent{ 44805bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent if (mActive) 44905bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent return AudioSystem::getInputFramesLost(mInput); 45005bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent else 45105bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent return 0; 45205bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent} 45389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 45489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 45589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4561703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held 4571703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t AudioRecord::openRecord_l( 45834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent uint32_t sampleRate, 45958f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten audio_format_t format, 4600d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi uint32_t channelMask, 46134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent int frameCount, 4626100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent audio_io_handle_t input) 46334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent{ 46434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent status_t status; 46534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 46634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (audioFlinger == 0) { 46734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_INIT; 46834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 46934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 4706100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input, 47134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent sampleRate, format, 4720d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi channelMask, 47334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent frameCount, 474a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten IAudioFlinger::TRACK_DEFAULT, 475be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent &mSessionId, 47634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent &status); 4773a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen 47834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (record == 0) { 47929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("AudioFlinger could not create record track, status: %d", status); 48034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return status; 48134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 48234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent sp<IMemory> cblk = record->getCblk(); 48334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (cblk == 0) { 48429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Could not get control block"); 48534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_INIT; 48634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 48734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mAudioRecord.clear(); 48834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mAudioRecord = record; 48934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblkMemory.clear(); 49034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblkMemory = cblk; 49134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 49234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 49338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags); 4946100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 4956100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->waitTimeMs = 0; 49634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_ERROR; 49734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent} 49834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 49989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 50089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 5011703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 50289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int active; 503d0965dde97f2815ae0a15fe6b40946f8a741a81eGlenn Kasten status_t result = NO_ERROR; 50489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audio_track_cblk_t* cblk = mCblk; 50589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t framesReq = audioBuffer->frameCount; 5061dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; 50789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 50889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->frameCount = 0; 50989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->size = 0; 51089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 51189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t framesReady = cblk->framesReady(); 51289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 51389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (framesReady == 0) { 51434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.lock(); 51589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto start_loop_here; 51689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (framesReady == 0) { 51789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project active = mActive; 518f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten if (CC_UNLIKELY(!active)) { 51934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 52089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_MORE_BUFFERS; 52134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 522f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten if (CC_UNLIKELY(!waitCount)) { 52334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 52489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return WOULD_BLOCK; 52534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 5261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (!(cblk->flags & CBLK_INVALID_MSK)) { 5271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 5281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); 5291703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 5301703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 5311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (mActive == 0) { 5321703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent return status_t(STOPPED); 5331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 5341703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 5351703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 5361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (cblk->flags & CBLK_INVALID_MSK) { 5371703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent goto create_new_record; 5381703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 539f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten if (CC_UNLIKELY(result != NO_ERROR)) { 5401dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent cblk->waitTimeMs += waitTimeMs; 54189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 5425ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW( "obtainBuffer timed out (is the CPU pegged?) " 54389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project "user=%08x, server=%08x", cblk->user, cblk->server); 54434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 545a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent // callback thread or sync event hasn't changed 5463acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 5471703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 54834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (result == DEAD_OBJECT) { 54938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent android_atomic_or(CBLK_INVALID_ON, &cblk->flags); 5501703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentcreate_new_record: 5511703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = AudioRecord::restoreRecord_l(cblk); 5521703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 5531703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result != NO_ERROR) { 5545ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("obtainBuffer create Track error %d", result); 5551703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 5561703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent return result; 55734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 55889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cblk->waitTimeMs = 0; 55989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (--waitCount == 0) { 56134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return TIMED_OUT; 56389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 56589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // read the server count again 56689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project start_loop_here: 56789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReady = cblk->framesReady(); 56889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 56934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 57189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 57289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cblk->waitTimeMs = 0; 5732986460984580833161bdaabc7f17da1005a8961Eric Laurent // reset time out to running value after obtaining a buffer 5742986460984580833161bdaabc7f17da1005a8961Eric Laurent cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 575c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 57689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (framesReq > framesReady) { 57789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReq = framesReady; 57889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 57989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 58089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t u = cblk->user; 58189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 58289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 583a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen if (framesReq > bufferEnd - u) { 58489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReq = bufferEnd - u; 58589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 58689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 58789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->flags = 0; 58889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->channelCount= mChannelCount; 58989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->format = mFormat; 59089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->frameCount = framesReq; 591c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer->size = framesReq*cblk->frameSize; 59289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->raw = (int8_t*)cblk->buffer(u); 59389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project active = mActive; 59489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return active ? status_t(NO_ERROR) : status_t(STOPPED); 59589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 59689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 59789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioRecord::releaseBuffer(Buffer* audioBuffer) 59889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 5991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 6001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mCblk->stepUser(audioBuffer->frameCount); 60189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 60289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 603606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenaudio_io_handle_t AudioRecord::getInput() const 6046100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent{ 6051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 606d1a243e41caffa8fd346907eed4625c9c47c1a86Eric Laurent return mInput; 6071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent} 6081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 6091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held 6101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentaudio_io_handle_t AudioRecord::getInput_l() 6111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{ 61205bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent mInput = AudioSystem::getInput(mInputSource, 6136100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->sampleRate, 6147c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mFormat, 6157c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mChannelMask, 6167c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent (audio_in_acoustics_t)mFlags, 6177c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mSessionId); 61805bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent return mInput; 6196100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent} 6206100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent 621606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenint AudioRecord::getSessionId() const 622be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent{ 623be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent return mSessionId; 624be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent} 625be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent 62689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 62789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 62889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t AudioRecord::read(void* buffer, size_t userSize) 62989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 63089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ssize_t read = 0; 63189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Buffer audioBuffer; 63289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int8_t *dst = static_cast<int8_t*>(buffer); 63389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 63489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (ssize_t(userSize) < 0) { 63589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // sanity-check. user is most-likely passing an error code. 63629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)", 63789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project buffer, userSize, userSize); 63889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 63989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 64089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6411703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 6421703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 6431703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // while we are accessing the cblk 644e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IAudioRecord> audioRecord = mAudioRecord; 645e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IMemory> iMem = mCblkMemory; 6461703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 64789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 64989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 650c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer.frameCount = userSize/frameSize(); 65189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 65288335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // By using a wait count corresponding to twice the timeout period in 65388335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // obtainBuffer() we give a chance to recover once for a read timeout 65488335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // (if media_server crashed for instance) before returning a length of 65588335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // 0 bytes read to the client 65688335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS)); 65789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err < 0) { 65889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // out of buffers, return #bytes written 65989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err == status_t(NO_MORE_BUFFERS)) 66089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 66188335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent if (err == status_t(TIMED_OUT)) 66288335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent err = 0; 66389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ssize_t(err); 66489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 66589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 66689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t bytesRead = audioBuffer.size; 66789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project memcpy(dst, audioBuffer.i8, bytesRead); 66889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 66989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project dst += bytesRead; 67089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project userSize -= bytesRead; 67189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project read += bytesRead; 67289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 67389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project releaseBuffer(&audioBuffer); 67489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } while (userSize); 67589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 67689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return read; 67789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 67889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 67989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 68089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 68189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) 68289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 68389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Buffer audioBuffer; 68489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t frames = mRemainingFrames; 68589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t readSize; 68689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6871703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 6881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 6891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // while we are accessing the cblk 690e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IAudioRecord> audioRecord = mAudioRecord; 691e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IMemory> iMem = mCblkMemory; 6921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent audio_track_cblk_t* cblk = mCblk; 6931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 6941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 69589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage marker callback 6967d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi if (!mMarkerReached && (mMarkerPosition > 0)) { 6971703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (cblk->user >= mMarkerPosition) { 69889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); 6997d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = true; 70089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 70189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 70289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 70389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage new position callback 70489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mUpdatePeriod > 0) { 7051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent while (cblk->user >= mNewPosition) { 70689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); 70789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition += mUpdatePeriod; 70889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 70989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 71089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 71189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 71289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer.frameCount = frames; 713c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // Calling obtainBuffer() with a wait count of 1 714c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // limits wait time to WAIT_PERIOD_MS. This prevents from being 71589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // stuck here not being able to handle timed events (position, markers). 71689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t err = obtainBuffer(&audioBuffer, 1); 71789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err < NO_ERROR) { 71889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err != TIMED_OUT) { 71929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up."); 72089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return false; 72189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 72289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 72389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 72489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err == status_t(STOPPED)) return false; 72589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 72689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t reqSize = audioBuffer.size; 72789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 72889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project readSize = audioBuffer.size; 72989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 73089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Sanity check on returned size 731cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent if (ssize_t(readSize) <= 0) { 732cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // The callback is done filling buffers 733cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // Keep this thread going to handle timed events and 734cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // still try to get more data in intervals of WAIT_PERIOD_MS 735cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // but don't just loop and block the CPU, so wait 736cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent usleep(WAIT_PERIOD_MS*1000); 737cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent break; 738cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent } 73989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (readSize > reqSize) readSize = reqSize; 74089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 74189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer.size = readSize; 742c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer.frameCount = readSize/frameSize(); 74389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frames -= audioBuffer.frameCount; 74489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 74589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project releaseBuffer(&audioBuffer); 74689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 74789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } while (frames); 74889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 749c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 75089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage overrun callback 7511703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (mActive && (cblk->framesAvailable() == 0)) { 7523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); 75338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) { 75433797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent mCbf(EVENT_OVERRUN, mUserData, 0); 75589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 75689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 75789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 75889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (frames == 0) { 75989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = mNotificationFrames; 76089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 76189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = frames; 76289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 76389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return true; 76489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 76589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7661703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock and cblk.lock held. Callers must also hold strong references on 7671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// the IAudioRecord and IMemory in case they are recreated here. 7681703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// If the IAudioRecord is successfully restored, the cblk pointer is updated 7691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) 7701703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{ 7711703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent status_t result; 7721703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 77338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { 7745ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("dead IAudioRecord, creating a new one"); 7751703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // signal old cblk condition so that other threads waiting for available buffers stop 7761703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // waiting now 7771703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->cv.broadcast(); 7781703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 7791703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 7801703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // if the new IAudioRecord is created, openRecord_l() will modify the 7811703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // following member variables: mAudioRecord, mCblkMemory and mCblk. 7821703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // It will also delete the strong references on previous IAudioRecord and IMemory 7830d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask, 784a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten mFrameCount, getInput_l()); 7851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result == NO_ERROR) { 786a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent // callback thread or sync event hasn't changed 7873acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 7881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result != NO_ERROR) { 7901703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mActive = false; 7911703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 7931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // signal old cblk condition for other threads waiting for restore completion 79438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); 7951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->cv.broadcast(); 7961703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } else { 7971703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (!(cblk->flags & CBLK_RESTORED_MSK)) { 7985ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("dead IAudioRecord, waiting for a new one to be created"); 7991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 8001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS)); 8011703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 8021703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 8031703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } else { 8045ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("dead IAudioRecord, already restored"); 8051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = NO_ERROR; 8061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 8071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 8081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result != NO_ERROR || mActive == 0) { 8091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = status_t(STOPPED); 8101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 8111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 8123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x", 813e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten result, mActive, mCblk, cblk, mCblk->flags, cblk->flags); 8141703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 8151703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result == NO_ERROR) { 8161703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // from now on we switch to the newly created cblk 8171703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk = mCblk; 8181703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 8191703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 8201703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 8215ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result); 8221703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 8231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent return result; 8241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent} 8251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 82689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ========================================================================= 82789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 82889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava) 82989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project : Thread(bCanCallJava), mReceiver(receiver) 83089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 83189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 83289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 83389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::ClientRecordThread::threadLoop() 83489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 83589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mReceiver.processAudioBuffer(this); 83689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 83789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8386dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kastenstatus_t AudioRecord::ClientRecordThread::readyToRun() 8396dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten{ 8406dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten AutoMutex(mReceiver.mLock); 8416dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten while (mReceiver.mReadyToRun == WOULD_BLOCK) { 8426dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten mReceiver.mCondition.wait(mReceiver.mLock); 8436dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten } 8446dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten return mReceiver.mReadyToRun; 8456dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten} 8466dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten 84789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 84889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 84989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android 850