AudioRecord.cpp revision e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39
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( 39e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten size_t* 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) { 573b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten ALOGE("Unsupported configuration: sampleRate %u, 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)) { 66a42ff007a17d63df22c60dd5e5fd811ee45ca1b3Glenn Kasten uint32_t 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), 78e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), 79e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten mProxy(NULL) 8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord( 84eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten audio_source_t inputSource, 8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t sampleRate, 8658f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten audio_format_t format, 87624a7fcb377f2a40109c16de5109ae8ea1f67a69Glenn Kasten audio_channel_mask_t channelMask, 8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int frameCount, 8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project callback_t cbf, 9089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project void* user, 91be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent int notificationFrames, 92be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent int sessionId) 93879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten : mStatus(NO_INIT), mSessionId(0), 94e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten mPreviousPriority(ANDROID_PRIORITY_NORMAL), 95e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten mPreviousSchedulingGroup(SP_DEFAULT), 96e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten mProxy(NULL) 9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 980d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi mStatus = set(inputSource, sampleRate, format, channelMask, 99f92eec53f886f43e4374a36195be55f2a7bbcf36Glenn Kasten frameCount, cbf, user, notificationFrames, sessionId); 10089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 10189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::~AudioRecord() 10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mStatus == NO_ERROR) { 10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Make sure that callback function exits in the case where 10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // it is looping on buffer empty condition in obtainBuffer(). 10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Otherwise the callback thread will never exit. 10889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project stop(); 10968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (mAudioRecordThread != 0) { 11068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mAudioRecordThread->requestExit(); // see comment in AudioRecord.h 11168337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mAudioRecordThread->requestExitAndWait(); 11268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mAudioRecordThread.clear(); 11389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioRecord.clear(); 11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project IPCThreadState::self()->flushCommands(); 1163a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen AudioSystem::releaseAudioSessionId(mSessionId); 11789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 118e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten delete mProxy; 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, 125624a7fcb377f2a40109c16de5109ae8ea1f67a69Glenn Kasten audio_channel_mask_t channelMask, 126e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten int frameCountInt, 12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project callback_t cbf, 12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project void* user, 12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int notificationFrames, 130be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent bool threadCanCallJava, 131be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent int sessionId) 13289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 133e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten // FIXME "int" here is legacy and will be replaced by size_t later 134e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten if (frameCountInt < 0) { 135e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten ALOGE("Invalid frame count %d", frameCountInt); 136e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten return BAD_VALUE; 137e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten } 138e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten size_t frameCount = frameCountInt; 13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 140e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten ALOGV("set(): sampleRate %u, channelMask %#x, frameCount %u", sampleRate, channelMask, 14185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten frameCount); 1421703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 1431703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 1441703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 1451dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent if (mAudioRecord != 0) { 14689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return INVALID_OPERATION; 14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 149c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (inputSource == AUDIO_SOURCE_DEFAULT) { 150c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent inputSource = AUDIO_SOURCE_MIC; 15189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 15289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (sampleRate == 0) { 15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sampleRate = DEFAULT_SAMPLE_RATE; 15589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 156e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten mSampleRate = sampleRate; 157e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten 15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // these below should probably come from the audioFlinger too... 15958f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten if (format == AUDIO_FORMAT_DEFAULT) { 160fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin format = AUDIO_FORMAT_PCM_16_BIT; 16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 162c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // validate parameters 163fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (!audio_is_valid_format(format)) { 16429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid format"); 165c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent return BAD_VALUE; 16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1680d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi if (!audio_is_input_channel(channelMask)) { 16989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 17089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 171a42ff007a17d63df22c60dd5e5fd811ee45ca1b3Glenn Kasten mChannelMask = channelMask; 172a42ff007a17d63df22c60dd5e5fd811ee45ca1b3Glenn Kasten uint32_t channelCount = popcount(channelMask); 173a42ff007a17d63df22c60dd5e5fd811ee45ca1b3Glenn Kasten mChannelCount = channelCount; 174c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 175e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten if (audio_is_linear_pcm(mFormat)) { 176e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten mFrameSize = channelCount * audio_bytes_per_sample(format); 177e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten } else { 178e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten mFrameSize = sizeof(uint8_t); 179e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten } 180e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten 1817c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent if (sessionId == 0 ) { 1827c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mSessionId = AudioSystem::newAudioSessionId(); 1837c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent } else { 1847c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mSessionId = sessionId; 1857c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent } 1863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("set(): mSessionId %d", mSessionId); 1877c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent 1886100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent audio_io_handle_t input = AudioSystem::getInput(inputSource, 1897c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent sampleRate, 1907c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent format, 1917c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent channelMask, 1927c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mSessionId); 1936100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (input == 0) { 19429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Could not get audio input for record source %d", inputSource); 19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 19689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 19889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // validate framecount 199e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten size_t minFrameCount = 0; 2006f744d75d3439f7984245e3c489cc7cf91cea41cEric Laurent status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelMask); 20115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh if (status != NO_ERROR) { 20215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh return status; 203c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 2043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 20589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (frameCount == 0) { 20789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frameCount = minFrameCount; 20889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (frameCount < minFrameCount) { 20989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (notificationFrames == 0) { 21389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project notificationFrames = frameCount/2; 21489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 21589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 21634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent // create the IAudioRecord 217a42ff007a17d63df22c60dd5e5fd811ee45ca1b3Glenn Kasten status = openRecord_l(sampleRate, format, frameCount, input); 21834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (status != NO_ERROR) { 21989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return status; 22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 22134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 222a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (cbf != NULL) { 22368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava); 22468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO); 22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 22689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 22789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mStatus = NO_ERROR; 22889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 22989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mFormat = format; 23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Update buffer size in case it has been limited by AudioFlinger during track creation 231b603744e96b07b1d5bf745bde593fb2c025cefcfGlenn Kasten mFrameCount = mCblk->frameCount_; 23283a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten 23368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mActive = false; 23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf = cbf; 23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNotificationFrames = notificationFrames; 23689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = notificationFrames; 23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUserData = user; 23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // TODO: add audio hardware input latency here 239573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent mLatency = (1000*mFrameCount) / sampleRate; 24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMarkerPosition = 0; 2417d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition = 0; 24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUpdatePeriod = 0; 244eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten mInputSource = inputSource; 24505bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent mInput = input; 2463a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen AudioSystem::acquireAudioSessionId(mSessionId); 24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::initCheck() const 25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mStatus; 25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::latency() const 25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 26089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mLatency; 26189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 26289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 26358f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kastenaudio_format_t AudioRecord::format() const 26489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 26589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mFormat; 26689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 268a42ff007a17d63df22c60dd5e5fd811ee45ca1b3Glenn Kastenuint32_t AudioRecord::channelCount() const 26989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 27089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mChannelCount; 27189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 27289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 273e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kastensize_t AudioRecord::frameCount() const 27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mFrameCount; 27689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 27789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 278eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kastenaudio_source_t AudioRecord::inputSource() const 279f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent{ 280eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten return mInputSource; 281f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent} 282f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent 28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 285a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentstatus_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession) 28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 28789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t ret = NO_ERROR; 28868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten sp<AudioRecordThread> t = mAudioRecordThread; 28989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 290a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent ALOGV("start, sync event %d trigger session %d", event, triggerSession); 29189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 292f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent AutoMutex lock(mLock); 2931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 2941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // while we are accessing the cblk 295e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IAudioRecord> audioRecord = mAudioRecord; 296e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IMemory> iMem = mCblkMemory; 2971703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent audio_track_cblk_t* cblk = mCblk; 2981703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 29968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (!mActive) { 30068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mActive = true; 3016dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten 3021703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 3039c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten if (!(cblk->flags & CBLK_INVALID)) { 3041703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 3053acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten ALOGV("mAudioRecord->start()"); 3063acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten ret = mAudioRecord->start(event, triggerSession); 3071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 3081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (ret == DEAD_OBJECT) { 3099c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten android_atomic_or(CBLK_INVALID, &cblk->flags); 3106100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } 3116100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } 3129c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten if (cblk->flags & CBLK_INVALID) { 313b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten audio_track_cblk_t* temp = cblk; 314b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten ret = restoreRecord_l(temp); 315b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten cblk = temp; 3161703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 3171703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 3186100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (ret == NO_ERROR) { 3191703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mNewPosition = cblk->user + mUpdatePeriod; 3202986460984580833161bdaabc7f17da1005a8961Eric Laurent cblk->bufferTimeoutMs = (event == AudioSystem::SYNC_EVENT_NONE) ? MAX_RUN_TIMEOUT_MS : 3212986460984580833161bdaabc7f17da1005a8961Eric Laurent AudioSystem::kSyncRecordStartTimeOutMs; 3221703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->waitTimeMs = 0; 3236100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent if (t != 0) { 32468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten t->resume(); 325c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 326879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten mPreviousPriority = getpriority(PRIO_PROCESS, 0); 327a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten get_sched_policy(0, &mPreviousSchedulingGroup); 328879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); 329c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 3306100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } else { 33168337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mActive = false; 33289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 33389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 33489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 33589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ret; 33689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 33789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 338d64cd233eef39430561c1e1df423336a199cc5d7Glenn Kastenvoid AudioRecord::stop() 33989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 34068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten sp<AudioRecordThread> t = mAudioRecordThread; 34189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("stop"); 34389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 344f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent AutoMutex lock(mLock); 34568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (mActive) { 34668337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mActive = false; 3471dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent mCblk->cv.signal(); 34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAudioRecord->stop(); 3497d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi // the record head position will reset to 0, so if a marker is set, we need 3507d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi // to activate it again 3517d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 35289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (t != 0) { 35368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten t->pause(); 35489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 355879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten setpriority(PRIO_PROCESS, 0, mPreviousPriority); 356a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten set_sched_policy(0, mPreviousSchedulingGroup); 35789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 35889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 36089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::stopped() const 36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 36368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten AutoMutex lock(mLock); 36489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return !mActive; 36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 367606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenuint32_t AudioRecord::getSampleRate() const 368573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent{ 369e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten return mSampleRate; 370573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent} 371573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent 37289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setMarkerPosition(uint32_t marker) 37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 374a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (mCbf == NULL) return INVALID_OPERATION; 37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 376955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten AutoMutex lock(mLock); 37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mMarkerPosition = marker; 3787d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi mMarkerReached = false; 37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 383606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getMarkerPosition(uint32_t *marker) const 38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 385a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (marker == NULL) return BAD_VALUE; 38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 387955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten AutoMutex lock(mLock); 38889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *marker = mMarkerPosition; 38989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 39189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 39289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 39489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 395a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (mCbf == NULL) return INVALID_OPERATION; 39689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 39789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t curPosition; 39889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project getPosition(&curPosition); 399955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten 400955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten AutoMutex lock(mLock); 40189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mNewPosition = curPosition + updatePeriod; 40289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mUpdatePeriod = updatePeriod; 40389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 40689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 407606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const 40889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 409a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (updatePeriod == NULL) return BAD_VALUE; 41089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 411955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten AutoMutex lock(mLock); 41289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *updatePeriod = mUpdatePeriod; 41389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 417606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getPosition(uint32_t *position) const 41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 419a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten if (position == NULL) return BAD_VALUE; 42089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4211703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 42289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *position = mCblk->user; 42389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 42489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_ERROR; 42589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 42689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 427606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenunsigned int AudioRecord::getInputFramesLost() const 42805bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent{ 429bf04a5d7f287fc712e0ed91849dc85c90c1e182dGlenn Kasten // no need to check mActive, because if inactive this will return 0, which is what we want 430bf04a5d7f287fc712e0ed91849dc85c90c1e182dGlenn Kasten return AudioSystem::getInputFramesLost(mInput); 43105bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent} 43289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 43389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 43489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4351703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held 4361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t AudioRecord::openRecord_l( 43734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent uint32_t sampleRate, 43858f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten audio_format_t format, 439e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten size_t frameCount, 4406100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent audio_io_handle_t input) 44134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent{ 44234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent status_t status; 44334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 44434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (audioFlinger == 0) { 445b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten ALOGE("Could not get audioflinger"); 44634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_INIT; 44734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 44834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 4491879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten pid_t tid = -1; 4501879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten // FIXME see similar logic at AudioTrack 4511879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten 452955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten int originalSessionId = mSessionId; 4536100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input, 45434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent sampleRate, format, 455a42ff007a17d63df22c60dd5e5fd811ee45ca1b3Glenn Kasten mChannelMask, 45634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent frameCount, 457a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten IAudioFlinger::TRACK_DEFAULT, 4581879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten tid, 459be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent &mSessionId, 46034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent &status); 461955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten ALOGE_IF(originalSessionId != 0 && mSessionId != originalSessionId, 462955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten "session ID changed from %d to %d", originalSessionId, mSessionId); 4633a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen 46434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (record == 0) { 46529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("AudioFlinger could not create record track, status: %d", status); 46634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return status; 46734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 468b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten sp<IMemory> iMem = record->getCblk(); 469b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten if (iMem == 0) { 47029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Could not get control block"); 47134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_INIT; 47234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 47334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mAudioRecord.clear(); 47434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mAudioRecord = record; 47534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent mCblkMemory.clear(); 476b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten mCblkMemory = iMem; 477b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer()); 478b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten mCblk = cblk; 479b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten mBuffers = (char*)cblk + sizeof(audio_track_cblk_t); 480b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 481b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten cblk->waitTimeMs = 0; 482e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten 483e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten // update proxy 484e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten delete mProxy; 485e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten mProxy = new AudioRecordClientProxy(cblk, mBuffers, frameCount, mFrameSize); 486e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten 48734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return NO_ERROR; 48834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent} 48934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent 49089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 49189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 492e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten ALOG_ASSERT(mStatus == NO_ERROR && mProxy != NULL); 493e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten 4941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 49568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten bool active; 496d0965dde97f2815ae0a15fe6b40946f8a741a81eGlenn Kasten status_t result = NO_ERROR; 49789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audio_track_cblk_t* cblk = mCblk; 49889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t framesReq = audioBuffer->frameCount; 4991dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; 50089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 50189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->frameCount = 0; 50289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer->size = 0; 50389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 504e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten size_t framesReady = mProxy->framesReady(); 50589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 50689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (framesReady == 0) { 50734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.lock(); 50889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto start_loop_here; 50989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (framesReady == 0) { 51089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project active = mActive; 511f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten if (CC_UNLIKELY(!active)) { 51234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 51389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NO_MORE_BUFFERS; 51434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 515f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten if (CC_UNLIKELY(!waitCount)) { 51634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 51789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return WOULD_BLOCK; 51834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 5199c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten if (!(cblk->flags & CBLK_INVALID)) { 5201703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 521b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten // this condition is in shared memory, so if IAudioRecord and control block 522b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten // are replaced due to mediaserver death or IAudioRecord invalidation then 523b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten // cv won't be signalled, but fortunately the timeout will limit the wait 5241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); 5251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.unlock(); 5261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 52768337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (!mActive) { 5281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent return status_t(STOPPED); 5291703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 530b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten // IAudioRecord may have been re-created while mLock was unlocked 531b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten cblk = mCblk; 5321703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 5331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 5349c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten if (cblk->flags & CBLK_INVALID) { 5351703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent goto create_new_record; 5361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 537f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten if (CC_UNLIKELY(result != NO_ERROR)) { 5381dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent cblk->waitTimeMs += waitTimeMs; 53989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 5405ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW( "obtainBuffer timed out (is the CPU pegged?) " 54189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project "user=%08x, server=%08x", cblk->user, cblk->server); 54234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent cblk->lock.unlock(); 543a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent // callback thread or sync event hasn't changed 5443acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 5451703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent cblk->lock.lock(); 54634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (result == DEAD_OBJECT) { 5479c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten android_atomic_or(CBLK_INVALID, &cblk->flags); 5481703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentcreate_new_record: 549b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten audio_track_cblk_t* temp = cblk; 550b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten result = AudioRecord::restoreRecord_l(temp); 551b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten cblk = temp; 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: 567e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten framesReady = mProxy->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; 581b603744e96b07b1d5bf745bde593fb2c025cefcfGlenn Kasten uint32_t bufferEnd = cblk->userBase + mFrameCount; 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->frameCount = framesReq; 58883a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten audioBuffer->size = framesReq * mFrameSize; 589e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten audioBuffer->raw = mProxy->buffer(u); 59089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project active = mActive; 59189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return active ? status_t(NO_ERROR) : status_t(STOPPED); 59289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 59389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 59489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioRecord::releaseBuffer(Buffer* audioBuffer) 59589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 596e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten ALOG_ASSERT(mStatus == NO_ERROR && mProxy != NULL); 597e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten 5981703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 599e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten (void) mProxy->stepUser(audioBuffer->frameCount); 60089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 60189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 602606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenaudio_io_handle_t AudioRecord::getInput() const 6036100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent{ 6041703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent AutoMutex lock(mLock); 605d1a243e41caffa8fd346907eed4625c9c47c1a86Eric Laurent return mInput; 6061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent} 6071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 6081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held 6091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentaudio_io_handle_t AudioRecord::getInput_l() 6101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{ 61105bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent mInput = AudioSystem::getInput(mInputSource, 612e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten mSampleRate, 6137c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mFormat, 6147c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mChannelMask, 6157c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent mSessionId); 61605bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent return mInput; 6176100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent} 6186100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent 619606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenint AudioRecord::getSessionId() const 620be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent{ 621955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten // no lock needed because session ID doesn't change after first set() 622be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent return mSessionId; 623be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent} 624be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent 62589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 62689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 62789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t AudioRecord::read(void* buffer, size_t userSize) 62889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 62989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ssize_t read = 0; 63089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Buffer audioBuffer; 63189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int8_t *dst = static_cast<int8_t*>(buffer); 63289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 63389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (ssize_t(userSize) < 0) { 63489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // sanity-check. user is most-likely passing an error code. 63529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)", 63689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project buffer, userSize, userSize); 63789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return BAD_VALUE; 63889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 63989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6401703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 6411703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 6421703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // while we are accessing the cblk 643e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IAudioRecord> audioRecord = mAudioRecord; 644e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IMemory> iMem = mCblkMemory; 6451703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 64689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 64889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 649c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer.frameCount = userSize/frameSize(); 65089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 65188335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // By using a wait count corresponding to twice the timeout period in 65288335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // obtainBuffer() we give a chance to recover once for a read timeout 65388335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // (if media_server crashed for instance) before returning a length of 65488335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent // 0 bytes read to the client 65588335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS)); 65689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err < 0) { 65789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // out of buffers, return #bytes written 658d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten if (err == status_t(NO_MORE_BUFFERS)) { 65989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 660d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten } 661d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten if (err == status_t(TIMED_OUT)) { 66288335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent err = 0; 663d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten } 66489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return ssize_t(err); 66589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 66689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 66789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t bytesRead = audioBuffer.size; 66889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project memcpy(dst, audioBuffer.i8, bytesRead); 66989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 67089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project dst += bytesRead; 67189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project userSize -= bytesRead; 67289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project read += bytesRead; 67389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 67489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project releaseBuffer(&audioBuffer); 67589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } while (userSize); 67689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 67789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return read; 67889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 67989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 68089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 68189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 68268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kastenbool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread) 68389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 68489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Buffer audioBuffer; 68589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t frames = mRemainingFrames; 68689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t readSize; 68789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.lock(); 6891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 6901703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // while we are accessing the cblk 691e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IAudioRecord> audioRecord = mAudioRecord; 692e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten sp<IMemory> iMem = mCblkMemory; 6931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent audio_track_cblk_t* cblk = mCblk; 69468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten bool active = mActive; 695955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten uint32_t markerPosition = mMarkerPosition; 696955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten uint32_t newPosition = mNewPosition; 697955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten uint32_t user = cblk->user; 698955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten // determine whether a marker callback will be needed, while locked 699955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten bool needMarker = !mMarkerReached && (mMarkerPosition > 0) && (user >= mMarkerPosition); 700955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten if (needMarker) { 701955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten mMarkerReached = true; 702955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten } 703955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten // determine the number of new position callback(s) that will be needed, while locked 704955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten uint32_t updatePeriod = mUpdatePeriod; 705955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten uint32_t needNewPos = updatePeriod > 0 && user >= newPosition ? 706955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten ((user - newPosition) / updatePeriod) + 1 : 0; 707955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten mNewPosition = newPosition + updatePeriod * needNewPos; 7081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent mLock.unlock(); 7091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 710955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten // perform marker callback, while unlocked 711955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten if (needMarker) { 712955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten mCbf(EVENT_MARKER, mUserData, &markerPosition); 71389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 71489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 715955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten // perform new position callback(s), while unlocked 716955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten for (; needNewPos > 0; --needNewPos) { 717955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten uint32_t temp = newPosition; 718955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten mCbf(EVENT_NEW_POS, mUserData, &temp); 719955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten newPosition += updatePeriod; 72089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 72189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 72289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 72389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer.frameCount = frames; 724c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // Calling obtainBuffer() with a wait count of 1 725c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent // limits wait time to WAIT_PERIOD_MS. This prevents from being 72689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // stuck here not being able to handle timed events (position, markers). 72789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t err = obtainBuffer(&audioBuffer, 1); 72889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err < NO_ERROR) { 72989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err != TIMED_OUT) { 73085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten ALOGE_IF(err != status_t(NO_MORE_BUFFERS), 73185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten "Error obtaining an audio buffer, giving up."); 73289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return false; 73389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 73489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 73589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 73689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (err == status_t(STOPPED)) return false; 73789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 73889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t reqSize = audioBuffer.size; 73989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 74089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project readSize = audioBuffer.size; 74189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 74289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Sanity check on returned size 743cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent if (ssize_t(readSize) <= 0) { 744cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // The callback is done filling buffers 745cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // Keep this thread going to handle timed events and 746cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // still try to get more data in intervals of WAIT_PERIOD_MS 747cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent // but don't just loop and block the CPU, so wait 748cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent usleep(WAIT_PERIOD_MS*1000); 749cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent break; 750cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent } 75189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (readSize > reqSize) readSize = reqSize; 75289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 75389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project audioBuffer.size = readSize; 754c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent audioBuffer.frameCount = readSize/frameSize(); 75589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project frames -= audioBuffer.frameCount; 75689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 75789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project releaseBuffer(&audioBuffer); 75889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 75989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } while (frames); 76089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 761c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 76289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Manage overrun callback 763e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten if (active && (mProxy->framesAvailable() == 0)) { 76468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten // The value of active is stale, but we are almost sure to be active here because 76568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten // otherwise we would have exited when obtainBuffer returned STOPPED earlier. 7663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); 7679c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) { 768955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten mCbf(EVENT_OVERRUN, mUserData, NULL); 76989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 77089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 77189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 77289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (frames == 0) { 77389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = mNotificationFrames; 77489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 77589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRemainingFrames = frames; 77689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 77789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return true; 77889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 77989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7801703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock and cblk.lock held. Callers must also hold strong references on 7811703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// the IAudioRecord and IMemory in case they are recreated here. 7821703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// If the IAudioRecord is successfully restored, the cblk pointer is updated 783b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kastenstatus_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& refCblk) 7841703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{ 7851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent status_t result; 7861703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 787b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten audio_track_cblk_t* cblk = refCblk; 788b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten audio_track_cblk_t* newCblk = cblk; 789b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten ALOGW("dead IAudioRecord, creating a new one"); 7901703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 791b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten // signal old cblk condition so that other threads waiting for available buffers stop 792b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten // waiting now 793b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten cblk->cv.broadcast(); 794b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten cblk->lock.unlock(); 7951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 796b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten // if the new IAudioRecord is created, openRecord_l() will modify the 797b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten // following member variables: mAudioRecord, mCblkMemory and mCblk. 798b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten // It will also delete the strong references on previous IAudioRecord and IMemory 799e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten result = openRecord_l(mSampleRate, mFormat, mFrameCount, getInput_l()); 800b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten if (result == NO_ERROR) { 801b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten newCblk = mCblk; 802b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten // callback thread or sync event hasn't changed 803b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 804b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten } 805b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten if (result != NO_ERROR) { 806b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten mActive = false; 8071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 808b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten 8093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x", 810b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten result, mActive, newCblk, cblk, newCblk->flags, cblk->flags); 8111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 8121703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (result == NO_ERROR) { 8131703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent // from now on we switch to the newly created cblk 814b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten refCblk = newCblk; 8151703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 816b36a7a68af073b1e7fd5cad6aa2c52223fd30efdGlenn Kasten newCblk->lock.lock(); 8171703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 8185ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result); 8191703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 8201703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent return result; 8211703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent} 8221703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 82389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ========================================================================= 82489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 82568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn KastenAudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava) 82668337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten : Thread(bCanCallJava), mReceiver(receiver), mPaused(true) 82768337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten{ 82868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten} 82968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten 83068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn KastenAudioRecord::AudioRecordThread::~AudioRecordThread() 83168337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten{ 83268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten} 83368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten 83468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kastenbool AudioRecord::AudioRecordThread::threadLoop() 83568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten{ 83668337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten { 83768337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten AutoMutex _l(mMyLock); 83868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (mPaused) { 83968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mMyCond.wait(mMyLock); 84068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten // caller will check for exitPending() 84168337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten return true; 84268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten } 84368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten } 84468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (!mReceiver.processAudioBuffer(this)) { 84568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten pause(); 84668337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten } 84768337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten return true; 84868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten} 84968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten 85068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kastenvoid AudioRecord::AudioRecordThread::requestExit() 85189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 85268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten // must be in this order to avoid a race condition 85368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten Thread::requestExit(); 85468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten resume(); 85589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 85689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 85768337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kastenvoid AudioRecord::AudioRecordThread::pause() 85889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 85968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten AutoMutex _l(mMyLock); 86068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mPaused = true; 86189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 86289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 86368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kastenvoid AudioRecord::AudioRecordThread::resume() 8646dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten{ 86568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten AutoMutex _l(mMyLock); 86668337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten if (mPaused) { 86768337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mPaused = false; 86868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten mMyCond.signal(); 8696dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten } 8706dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten} 8716dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten 87289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ------------------------------------------------------------------------- 87389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 87489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android 875