AudioRecord.cpp revision d64cd233eef39430561c1e1df423336a199cc5d7
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 <sys/resource.h> 22868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <sys/types.h> 2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 24868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <binder/IPCThreadState.h> 25868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <cutils/atomic.h> 26868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <cutils/compiler.h> 2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/AudioRecord.h> 28868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <media/AudioSystem.h> 29868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <system/audio.h> 3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Log.h> 3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 32868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <private/media/AudioTrackShared.h> 3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android { 3515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh// --------------------------------------------------------------------------- 3615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 3715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh// static 3815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yehstatus_t AudioRecord::getMinFrameCount( 3915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh int* frameCount, 4015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh uint32_t sampleRate, 4158f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten audio_format_t format, 42dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten audio_channel_mask_t channelMask) 4315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh{ 4404cd0186305e2b59d23c9147787046c6662029ccGlenn Kasten if (frameCount == NULL) return BAD_VALUE; 4504cd0186305e2b59d23c9147787046c6662029ccGlenn Kasten 4604cd0186305e2b59d23c9147787046c6662029ccGlenn Kasten // default to 0 in case of error 4704cd0186305e2b59d23c9147787046c6662029ccGlenn Kasten *frameCount = 0; 4804cd0186305e2b59d23c9147787046c6662029ccGlenn Kasten 4915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh size_t size = 0; 50dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten if (AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size) 5115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh != NO_ERROR) { 5229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("AudioSystem could not query the input buffer size."); 5315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return NO_INIT; 5415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh } 5515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 5615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh if (size == 0) { 57dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten ALOGE("Unsupported configuration: sampleRate %d, format %d, channelMask %#x", 58dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten sampleRate, format, channelMask); 5915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return BAD_VALUE; 6015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh } 6115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 6215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh // We double the size of input buffer for ping pong use of record buffer. 6315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh size <<= 1; 6415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 65fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (audio_is_linear_pcm(format)) { 66dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten int channelCount = popcount(channelMask); 67671a636931295d9c33ffca74551a804479d01241Eric Laurent size /= channelCount * audio_bytes_per_sample(format); 6815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh } 6915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh 7015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh *frameCount = size; 7115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return NO_ERROR; 7215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh} 7389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// --------------------------------------------------------------------------- 7589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord() 77879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten : mStatus(NO_INIT), mSessionId(0), 78a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) 7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord( 83eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten audio_source_t inputSource, 8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t sampleRate, 8558f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten audio_format_t format, 86624a7fcb377f2a40109c16de5109ae8ea1f67a69Glenn Kasten audio_channel_mask_t channelMask, 8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int frameCount, 8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project callback_t cbf, 8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project void* user, 90be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent int notificationFrames, 91be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent int sessionId) 92879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten : mStatus(NO_INIT), mSessionId(0), 93a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) 9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 950d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi mStatus = set(inputSource, sampleRate, format, channelMask, 96f92eec53f886f43e4374a36195be55f2a7bbcf36Glenn Kasten frameCount, cbf, user, notificationFrames, sessionId); 9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 9889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 9989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::~AudioRecord() 10089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 10189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mStatus == NO_ERROR) { 10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Make sure that callback function exits in the case where 10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // it is looping on buffer empty condition in obtainBuffer(). 10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Otherwise the callback thread will never exit. 10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project stop(); 10668337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (mAudioRecordThread != 0) { 10768337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mAudioRecordThread->requestExit(); // see comment in AudioRecord.h 10868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mAudioRecordThread->requestExitAndWait(); 10968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mAudioRecordThread.clear(); 11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioRecord.clear(); 11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project IPCThreadState::self()->flushCommands(); 1133a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen AudioSystem::releaseAudioSessionId(mSessionId); 11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 11789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::set( 118eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten audio_source_t inputSource, 11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t sampleRate, 12058f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten audio_format_t format, 121624a7fcb377f2a40109c16de5109ae8ea1f67a69Glenn Kasten audio_channel_mask_t channelMask, 12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int frameCount, 12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project callback_t cbf, 12489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project void* user, 12589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int notificationFrames, 126be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent bool threadCanCallJava, 127be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent int sessionId) 12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 130624a7fcb377f2a40109c16de5109ae8ea1f67a69Glenn Kasten ALOGV("set(): sampleRate %d, channelMask %#x, frameCount %d",sampleRate, channelMask, frameCount); 1311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 1321703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 1331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 1341dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent if (mAudioRecord != 0) { 13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return INVALID_OPERATION; 13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 138c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (inputSource == AUDIO_SOURCE_DEFAULT) { 139c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent inputSource = AUDIO_SOURCE_MIC; 14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (sampleRate == 0) { 14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sampleRate = DEFAULT_SAMPLE_RATE; 14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // these below should probably come from the audioFlinger too... 14658f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten if (format == AUDIO_FORMAT_DEFAULT) { 147fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin format = AUDIO_FORMAT_PCM_16_BIT; 14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 149c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // validate parameters 150fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (!audio_is_valid_format(format)) { 15129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid format"); 152c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return BAD_VALUE; 15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1550d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi if (!audio_is_input_channel(channelMask)) { 15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 15789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 158be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent 1590d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi int channelCount = popcount(channelMask); 160c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 1617c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent if (sessionId == 0 ) { 1627c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mSessionId = AudioSystem::newAudioSessionId(); 1637c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent } else { 1647c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mSessionId = sessionId; 1657c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent } 1663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("set(): mSessionId %d", mSessionId); 1677c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent 1686100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent audio_io_handle_t input = AudioSystem::getInput(inputSource, 1697c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent sampleRate, 1707c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent format, 1717c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent channelMask, 1727c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mSessionId); 1736100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (input == 0) { 17429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Could not get audio input for record source %d", inputSource); 17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 17689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 17889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // validate framecount 17915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh int minFrameCount = 0; 18015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelCount); 18115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh if (status != NO_ERROR) { 18215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return status; 183c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 1843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 18589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 18689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (frameCount == 0) { 18789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frameCount = minFrameCount; 18889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (frameCount < minFrameCount) { 18989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 19089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 19189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 19289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (notificationFrames == 0) { 19389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project notificationFrames = frameCount/2; 19489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 19634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent // create the IAudioRecord 1970d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi status = openRecord_l(sampleRate, format, channelMask, 198a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten frameCount, input); 19934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (status != NO_ERROR) { 20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return status; 20189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 20234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 203a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (cbf != NULL) { 20468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava); 20568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO); 20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 20789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 20889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mStatus = NO_ERROR; 20989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFormat = format; 21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Update buffer size in case it has been limited by AudioFlinger during track creation 21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFrameCount = mCblk->frameCount; 213c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent mChannelCount = (uint8_t)channelCount; 2140d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi mChannelMask = channelMask; 21568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mActive = false; 21689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf = cbf; 21789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNotificationFrames = notificationFrames; 21889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = notificationFrames; 21989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUserData = user; 22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // TODO: add audio hardware input latency here 221573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent mLatency = (1000*mFrameCount) / sampleRate; 22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMarkerPosition = 0; 2237d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 22489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition = 0; 22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUpdatePeriod = 0; 226eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten mInputSource = inputSource; 22705bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent mInput = input; 2283a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen AudioSystem::acquireAudioSessionId(mSessionId); 22989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 23189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 23289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 23389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::initCheck() const 23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mStatus; 23689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 23989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::latency() const 24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mLatency; 24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 24558f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kastenaudio_format_t AudioRecord::format() const 24689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mFormat; 24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::channelCount() const 25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mChannelCount; 25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::frameCount() const 25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mFrameCount; 25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 260b9980659501d0428d65d8292f3c32da69d37fbd2Glenn Kastensize_t AudioRecord::frameSize() const 26189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 262fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (audio_is_linear_pcm(mFormat)) { 263671a636931295d9c33ffca74551a804479d01241Eric Laurent return channelCount()*audio_bytes_per_sample(mFormat); 264c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 265c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return sizeof(uint8_t); 266c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 26889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 269eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kastenaudio_source_t AudioRecord::inputSource() const 270f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent{ 271eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten return mInputSource; 272f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent} 273f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent 27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 276a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentstatus_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession) 27789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 27889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t ret = NO_ERROR; 27968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten sp<AudioRecordThread> t = mAudioRecordThread; 28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 281a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent ALOGV("start, sync event %d trigger session %d", event, triggerSession); 28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 283f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent AutoMutex lock(mLock); 2841703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 2851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // while we are accessing the cblk 286e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IAudioRecord> audioRecord = mAudioRecord; 287e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IMemory> iMem = mCblkMemory; 2881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent audio_track_cblk_t* cblk = mCblk; 2891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 29068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (!mActive) { 29168337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mActive = true; 2926dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten 2931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 2941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (!(cblk->flags & CBLK_INVALID_MSK)) { 2951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 2963acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten ALOGV("mAudioRecord->start()"); 2973acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten ret = mAudioRecord->start(event, triggerSession); 2981703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 2991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (ret == DEAD_OBJECT) { 30038ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent android_atomic_or(CBLK_INVALID_ON, &cblk->flags); 3016100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } 3026100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } 3031703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (cblk->flags & CBLK_INVALID_MSK) { 3041703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ret = restoreRecord_l(cblk); 3051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 3061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 3076100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (ret == NO_ERROR) { 3081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mNewPosition = cblk->user + mUpdatePeriod; 3092986460984580833161bdaabc7f17da1005a8961Eric Laurent cblk->bufferTimeoutMs = (event == AudioSystem::SYNC_EVENT_NONE) ? MAX_RUN_TIMEOUT_MS : 3102986460984580833161bdaabc7f17da1005a8961Eric Laurent AudioSystem::kSyncRecordStartTimeOutMs; 3111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->waitTimeMs = 0; 3126100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (t != 0) { 31368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten t->resume(); 314c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 315879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten mPreviousPriority = getpriority(PRIO_PROCESS, 0); 316a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten get_sched_policy(0, &mPreviousSchedulingGroup); 317879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); 318c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 3196100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } else { 32068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mActive = false; 32189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 32289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ret; 32589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 327d64cd233eef39430561c1e1df423336a199cc5d7Glenn Kastenvoid AudioRecord::stop() 32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 32968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten sp<AudioRecordThread> t = mAudioRecordThread; 33089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("stop"); 33289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 333f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent AutoMutex lock(mLock); 33468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (mActive) { 33568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mActive = false; 3361dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent mCblk->cv.signal(); 33789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioRecord->stop(); 3387d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi // the record head position will reset to 0, so if a marker is set, we need 3397d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi // to activate it again 3407d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 34189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 34268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten t->pause(); 34389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 344879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten setpriority(PRIO_PROCESS, 0, mPreviousPriority); 345a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten set_sched_policy(0, mPreviousSchedulingGroup); 34689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 34789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 34989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 35089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::stopped() const 35189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 35268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten AutoMutex lock(mLock); 35389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return !mActive; 35489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 35589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 356606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenuint32_t AudioRecord::getSampleRate() const 357573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent{ 3581703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 359573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent return mCblk->sampleRate; 360573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent} 361573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent 36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setMarkerPosition(uint32_t marker) 36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 364a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (mCbf == NULL) return INVALID_OPERATION; 36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMarkerPosition = marker; 3677d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 36889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 37189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 372606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getMarkerPosition(uint32_t *marker) const 37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 374a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (marker == NULL) return BAD_VALUE; 37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *marker = mMarkerPosition; 37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 383a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (mCbf == NULL) return INVALID_OPERATION; 38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t curPosition; 38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project getPosition(&curPosition); 38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition = curPosition + updatePeriod; 38889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUpdatePeriod = updatePeriod; 38989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 39189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 39289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 393606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const 39489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 395a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (updatePeriod == NULL) return BAD_VALUE; 39689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *updatePeriod = mUpdatePeriod; 39889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 40089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 40189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 402606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getPosition(uint32_t *position) const 40389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 404a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (position == NULL) return BAD_VALUE; 40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *position = mCblk->user; 40889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 41089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 41189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 412606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenunsigned int AudioRecord::getInputFramesLost() const 41305bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent{ 414bf04a5d7f287fc712e0ed91849dc85c90c1e182dGlenn Kasten // no need to check mActive, because if inactive this will return 0, which is what we want 415bf04a5d7f287fc712e0ed91849dc85c90c1e182dGlenn Kasten return AudioSystem::getInputFramesLost(mInput); 41605bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent} 41789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 41989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4201703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held 4211703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t AudioRecord::openRecord_l( 42234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent uint32_t sampleRate, 42358f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten audio_format_t format, 424624a7fcb377f2a40109c16de5109ae8ea1f67a69Glenn Kasten audio_channel_mask_t channelMask, 42534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent int frameCount, 4266100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent audio_io_handle_t input) 42734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent{ 42834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent status_t status; 42934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 43034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (audioFlinger == 0) { 43134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_INIT; 43234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 43334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 4341879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten pid_t tid = -1; 4351879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten // FIXME see similar logic at AudioTrack 4361879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten 4376100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input, 43834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent sampleRate, format, 4390d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi channelMask, 44034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent frameCount, 441a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten IAudioFlinger::TRACK_DEFAULT, 4421879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten tid, 443be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent &mSessionId, 44434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent &status); 4453a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen 44634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (record == 0) { 44729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("AudioFlinger could not create record track, status: %d", status); 44834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return status; 44934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 45034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent sp<IMemory> cblk = record->getCblk(); 45134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (cblk == 0) { 45229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Could not get control block"); 45334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_INIT; 45434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 45534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mAudioRecord.clear(); 45634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mAudioRecord = record; 45734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblkMemory.clear(); 45834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblkMemory = cblk; 45934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 46034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 46138ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags); 4626100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 4636100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->waitTimeMs = 0; 46434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_ERROR; 46534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent} 46634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 46789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 46889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 4691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 47068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten bool active; 471d0965dde97f2815ae0a15fe6b40946f8a741a81eGlenn Kasten status_t result = NO_ERROR; 47289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audio_track_cblk_t* cblk = mCblk; 47389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t framesReq = audioBuffer->frameCount; 4741dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; 47589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 47689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->frameCount = 0; 47789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->size = 0; 47889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 47989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t framesReady = cblk->framesReady(); 48089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 48189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (framesReady == 0) { 48234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.lock(); 48389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto start_loop_here; 48489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (framesReady == 0) { 48589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project active = mActive; 486f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten if (CC_UNLIKELY(!active)) { 48734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 48889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_MORE_BUFFERS; 48934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 490f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten if (CC_UNLIKELY(!waitCount)) { 49134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 49289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return WOULD_BLOCK; 49334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 4941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (!(cblk->flags & CBLK_INVALID_MSK)) { 4951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 4961703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); 4971703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 4981703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 49968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (!mActive) { 5001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent return status_t(STOPPED); 5011703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 5021703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 5031703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 5041703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (cblk->flags & CBLK_INVALID_MSK) { 5051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent goto create_new_record; 5061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 507f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten if (CC_UNLIKELY(result != NO_ERROR)) { 5081dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent cblk->waitTimeMs += waitTimeMs; 50989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 5105ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW( "obtainBuffer timed out (is the CPU pegged?) " 51189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project "user=%08x, server=%08x", cblk->user, cblk->server); 51234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 513a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent // callback thread or sync event hasn't changed 5143acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 5151703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 51634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (result == DEAD_OBJECT) { 51738ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent android_atomic_or(CBLK_INVALID_ON, &cblk->flags); 5181703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentcreate_new_record: 5191703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = AudioRecord::restoreRecord_l(cblk); 5201703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 5211703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result != NO_ERROR) { 5225ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("obtainBuffer create Track error %d", result); 5231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 5241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent return result; 52534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 52689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cblk->waitTimeMs = 0; 52789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 52889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (--waitCount == 0) { 52934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 53089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return TIMED_OUT; 53189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 53289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 53389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // read the server count again 53489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project start_loop_here: 53589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReady = cblk->framesReady(); 53689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 53734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 53889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 53989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 54089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cblk->waitTimeMs = 0; 5412986460984580833161bdaabc7f17da1005a8961Eric Laurent // reset time out to running value after obtaining a buffer 5422986460984580833161bdaabc7f17da1005a8961Eric Laurent cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 543c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 54489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (framesReq > framesReady) { 54589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReq = framesReady; 54689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 54789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 54889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t u = cblk->user; 54989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 55089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 551a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen if (framesReq > bufferEnd - u) { 55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project framesReq = bufferEnd - u; 55389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 55589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->flags = 0; 55689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->channelCount= mChannelCount; 55789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->format = mFormat; 55889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->frameCount = framesReq; 559c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer->size = framesReq*cblk->frameSize; 56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->raw = (int8_t*)cblk->buffer(u); 56189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project active = mActive; 56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return active ? status_t(NO_ERROR) : status_t(STOPPED); 56389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 56589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioRecord::releaseBuffer(Buffer* audioBuffer) 56689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 5671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 5681703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mCblk->stepUser(audioBuffer->frameCount); 56989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 571606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenaudio_io_handle_t AudioRecord::getInput() const 5726100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent{ 5731703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 574d1a243e41caffa8fd346907eed4625c9c47c1a86Eric Laurent return mInput; 5751703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent} 5761703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 5771703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held 5781703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentaudio_io_handle_t AudioRecord::getInput_l() 5791703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{ 58005bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent mInput = AudioSystem::getInput(mInputSource, 5816100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent mCblk->sampleRate, 5827c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mFormat, 5837c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mChannelMask, 5847c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mSessionId); 58505bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent return mInput; 5866100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent} 5876100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent 588606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenint AudioRecord::getSessionId() const 589be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent{ 590be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent return mSessionId; 591be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent} 592be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent 59389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 59489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 59589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t AudioRecord::read(void* buffer, size_t userSize) 59689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 59789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ssize_t read = 0; 59889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Buffer audioBuffer; 59989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int8_t *dst = static_cast<int8_t*>(buffer); 60089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 60189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (ssize_t(userSize) < 0) { 60289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // sanity-check. user is most-likely passing an error code. 60329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)", 60489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project buffer, userSize, userSize); 60589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 60689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 60789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 6091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 6101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // while we are accessing the cblk 611e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IAudioRecord> audioRecord = mAudioRecord; 612e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IMemory> iMem = mCblkMemory; 6131703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 61489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 61589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 61689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 617c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer.frameCount = userSize/frameSize(); 61889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 61988335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // By using a wait count corresponding to twice the timeout period in 62088335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // obtainBuffer() we give a chance to recover once for a read timeout 62188335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // (if media_server crashed for instance) before returning a length of 62288335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // 0 bytes read to the client 62388335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS)); 62489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err < 0) { 62589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // out of buffers, return #bytes written 62689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err == status_t(NO_MORE_BUFFERS)) 62789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 62888335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent if (err == status_t(TIMED_OUT)) 62988335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent err = 0; 63089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ssize_t(err); 63189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 63289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 63389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t bytesRead = audioBuffer.size; 63489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project memcpy(dst, audioBuffer.i8, bytesRead); 63589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 63689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project dst += bytesRead; 63789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project userSize -= bytesRead; 63889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project read += bytesRead; 63989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project releaseBuffer(&audioBuffer); 64189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } while (userSize); 64289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return read; 64489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 64589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 64789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kastenbool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread) 64989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 65089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Buffer audioBuffer; 65189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t frames = mRemainingFrames; 65289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t readSize; 65389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6541703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 6551703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 6561703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // while we are accessing the cblk 657e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IAudioRecord> audioRecord = mAudioRecord; 658e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IMemory> iMem = mCblkMemory; 6591703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent audio_track_cblk_t* cblk = mCblk; 66068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten bool active = mActive; 6611703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 6621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 66389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage marker callback 6647d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi if (!mMarkerReached && (mMarkerPosition > 0)) { 6651703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (cblk->user >= mMarkerPosition) { 66689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); 6677d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = true; 66889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 66989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 67089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 67189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage new position callback 67289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mUpdatePeriod > 0) { 6731703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent while (cblk->user >= mNewPosition) { 67489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); 67589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition += mUpdatePeriod; 67689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 67789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 67889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 67989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 68089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer.frameCount = frames; 681c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // Calling obtainBuffer() with a wait count of 1 682c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // limits wait time to WAIT_PERIOD_MS. This prevents from being 68389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // stuck here not being able to handle timed events (position, markers). 68489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t err = obtainBuffer(&audioBuffer, 1); 68589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err < NO_ERROR) { 68689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err != TIMED_OUT) { 68729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up."); 68889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return false; 68989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 69089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 69189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 69289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err == status_t(STOPPED)) return false; 69389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 69489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t reqSize = audioBuffer.size; 69589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 69689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project readSize = audioBuffer.size; 69789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 69889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Sanity check on returned size 699cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent if (ssize_t(readSize) <= 0) { 700cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // The callback is done filling buffers 701cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // Keep this thread going to handle timed events and 702cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // still try to get more data in intervals of WAIT_PERIOD_MS 703cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // but don't just loop and block the CPU, so wait 704cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent usleep(WAIT_PERIOD_MS*1000); 705cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent break; 706cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent } 70789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (readSize > reqSize) readSize = reqSize; 70889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 70989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer.size = readSize; 710c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer.frameCount = readSize/frameSize(); 71189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frames -= audioBuffer.frameCount; 71289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 71389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project releaseBuffer(&audioBuffer); 71489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 71589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } while (frames); 71689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 717c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 71889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage overrun callback 71968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (active && (cblk->framesAvailable() == 0)) { 72068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten // The value of active is stale, but we are almost sure to be active here because 72168337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten // otherwise we would have exited when obtainBuffer returned STOPPED earlier. 7223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); 72338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) { 72433797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent mCbf(EVENT_OVERRUN, mUserData, 0); 72589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 72689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 72789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 72889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (frames == 0) { 72989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = mNotificationFrames; 73089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 73189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = frames; 73289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 73389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return true; 73489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 73589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock and cblk.lock held. Callers must also hold strong references on 7371703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// the IAudioRecord and IMemory in case they are recreated here. 7381703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// If the IAudioRecord is successfully restored, the cblk pointer is updated 7391703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) 7401703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{ 7411703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent status_t result; 7421703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 74338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { 7445ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("dead IAudioRecord, creating a new one"); 7451703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // signal old cblk condition so that other threads waiting for available buffers stop 7461703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // waiting now 7471703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->cv.broadcast(); 7481703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 7491703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 7501703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // if the new IAudioRecord is created, openRecord_l() will modify the 7511703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // following member variables: mAudioRecord, mCblkMemory and mCblk. 7521703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // It will also delete the strong references on previous IAudioRecord and IMemory 7530d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask, 754a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten mFrameCount, getInput_l()); 7551703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result == NO_ERROR) { 756a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent // callback thread or sync event hasn't changed 7573acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 7581703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7591703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result != NO_ERROR) { 7601703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mActive = false; 7611703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 7631703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // signal old cblk condition for other threads waiting for restore completion 76438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); 7651703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->cv.broadcast(); 7661703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } else { 7671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (!(cblk->flags & CBLK_RESTORED_MSK)) { 7685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("dead IAudioRecord, waiting for a new one to be created"); 7691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 7701703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS)); 7711703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 7721703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 7731703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } else { 7745ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("dead IAudioRecord, already restored"); 7751703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = NO_ERROR; 7761703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 7771703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 77868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (result != NO_ERROR || !mActive) { 7791703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = status_t(STOPPED); 7801703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7811703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x", 783e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten result, mActive, mCblk, cblk, mCblk->flags, cblk->flags); 7841703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 7851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result == NO_ERROR) { 7861703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // from now on we switch to the newly created cblk 7871703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk = mCblk; 7881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 7891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 7901703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 7915ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result); 7921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 7931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent return result; 7941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent} 7951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 79689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ========================================================================= 79789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 79868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn KastenAudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava) 79968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten : Thread(bCanCallJava), mReceiver(receiver), mPaused(true) 80068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten{ 80168337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten} 80268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten 80368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn KastenAudioRecord::AudioRecordThread::~AudioRecordThread() 80468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten{ 80568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten} 80668337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten 80768337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kastenbool AudioRecord::AudioRecordThread::threadLoop() 80868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten{ 80968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten { 81068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten AutoMutex _l(mMyLock); 81168337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (mPaused) { 81268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mMyCond.wait(mMyLock); 81368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten // caller will check for exitPending() 81468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten return true; 81568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten } 81668337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten } 81768337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (!mReceiver.processAudioBuffer(this)) { 81868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten pause(); 81968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten } 82068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten return true; 82168337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten} 82268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten 82368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kastenvoid AudioRecord::AudioRecordThread::requestExit() 82489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 82568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten // must be in this order to avoid a race condition 82668337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten Thread::requestExit(); 82768337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten resume(); 82889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 82989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 83068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kastenvoid AudioRecord::AudioRecordThread::pause() 83189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 83268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten AutoMutex _l(mMyLock); 83368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mPaused = true; 83489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 83589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 83668337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kastenvoid AudioRecord::AudioRecordThread::resume() 8376dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten{ 83868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten AutoMutex _l(mMyLock); 83968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (mPaused) { 84068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mPaused = false; 84168337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mMyCond.signal(); 8426dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten } 8436dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten} 8446dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten 84589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 84689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 84789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android 848