AudioRecord.cpp revision d457c970c8d08519cd77280a90b61ae1e342cfe3
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** Copyright 2008, The Android Open Source Project 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** Licensed under the Apache License, Version 2.0 (the "License"); 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** you may not use this file except in compliance with the License. 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** You may obtain a copy of the License at 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** http://www.apache.org/licenses/LICENSE-2.0 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** Unless required by applicable law or agreed to in writing, software 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** distributed under the License is distributed on an "AS IS" BASIS, 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** See the License for the specific language governing permissions and 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang** limitations under the License. 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang*/ 17e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 18e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines//#define LOG_NDEBUG 0 19462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#define LOG_TAG "AudioRecord" 20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include <sys/resource.h> 22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <binder/IPCThreadState.h> 23462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include <media/AudioRecord.h> 24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <utils/Log.h> 25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <private/media/AudioTrackShared.h> 26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include <media/IAudioFlinger.h> 279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#define WAIT_PERIOD_MS 10 29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 303fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hinesnamespace android { 313fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines// --------------------------------------------------------------------------- 32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr// static 346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrstatus_t AudioRecord::getMinFrameCount( 359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao size_t* frameCount, 36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao uint32_t sampleRate, 37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao audio_format_t format, 386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr audio_channel_mask_t channelMask) 396315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr{ 406315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr if (frameCount == NULL) { 416315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr return BAD_VALUE; 426315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr } 439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao // default to 0 in case of error 45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao *frameCount = 0; 46a41ce1d98094da84643995d40d71c529905123fcZonr Chang 47a41ce1d98094da84643995d40d71c529905123fcZonr Chang size_t size = 0; 48a41ce1d98094da84643995d40d71c529905123fcZonr Chang status_t status = AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size); 49a41ce1d98094da84643995d40d71c529905123fcZonr Chang if (status != NO_ERROR) { 50462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao ALOGE("AudioSystem could not query the input buffer size; status %d", status); 51462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return NO_INIT; 529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (size == 0) { 559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ALOGE("Unsupported configuration: sampleRate %u, format %#x, channelMask %#x", 569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao sampleRate, format, channelMask); 57a41ce1d98094da84643995d40d71c529905123fcZonr Chang return BAD_VALUE; 589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // We double the size of input buffer for ping pong use of record buffer. 619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao size <<= 1; 629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 639e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines // Assumes audio_is_linear_pcm(format) 649e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines uint32_t channelCount = popcount(channelMask); 659e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines size /= channelCount * audio_bytes_per_sample(format); 663fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines 679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao *frameCount = size; 689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NO_ERROR; 699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 71a41ce1d98094da84643995d40d71c529905123fcZonr Chang// --------------------------------------------------------------------------- 72a41ce1d98094da84643995d40d71c529905123fcZonr Chang 739ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoAudioRecord::AudioRecord() 749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE), 759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) 769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao{ 779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen HinesAudioRecord::AudioRecord( 8096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines audio_source_t inputSource, 819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao uint32_t sampleRate, 829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao audio_format_t format, 839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao audio_channel_mask_t channelMask, 849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao int frameCount, 859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao callback_t cbf, 869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao void* user, 879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao int notificationFrames, 889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao int sessionId, 899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao transfer_type transferType, 909e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines audio_input_flags_t flags __unused) 919e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE), 923fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines mPreviousPriority(ANDROID_PRIORITY_NORMAL), 933fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines mPreviousSchedulingGroup(SP_DEFAULT), 949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mProxy(NULL) 959e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines{ 969e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user, 979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao notificationFrames, false /*threadCanCallJava*/, sessionId, transferType); 989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1009e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen HinesAudioRecord::~AudioRecord() 1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao{ 1022ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (mStatus == NO_ERROR) { 1032ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // Make sure that callback function exits in the case where 1042ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // it is looping on buffer empty condition in obtainBuffer(). 1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Otherwise the callback thread will never exit. 1069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao stop(); 1079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mAudioRecordThread != 0) { 1089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mProxy->interrupt(); 1099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mAudioRecordThread->requestExit(); // see comment in AudioRecord.h 1109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mAudioRecordThread->requestExitAndWait(); 1119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mAudioRecordThread.clear(); 1129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mAudioRecord != 0) { 1149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); 1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mAudioRecord.clear(); 1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao IPCThreadState::self()->flushCommands(); 1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao AudioSystem::releaseAudioSessionId(mSessionId, -1); 1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 121c808a99831115928b4648f4c8b86dc682594217aStephen Hines 122a41ce1d98094da84643995d40d71c529905123fcZonr Changstatus_t AudioRecord::set( 123a41ce1d98094da84643995d40d71c529905123fcZonr Chang audio_source_t inputSource, 124a41ce1d98094da84643995d40d71c529905123fcZonr Chang uint32_t sampleRate, 125a41ce1d98094da84643995d40d71c529905123fcZonr Chang audio_format_t format, 126641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang audio_channel_mask_t channelMask, 127641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang int frameCountInt, 128641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang callback_t cbf, 129641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang void* user, 130641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang int notificationFrames, 131641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang bool threadCanCallJava, 132641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang int sessionId, 1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao transfer_type transferType, 1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao audio_input_flags_t flags) 1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao{ 1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (transferType) { 1379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case TRANSFER_DEFAULT: 1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (cbf == NULL || threadCanCallJava) { 1399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao transferType = TRANSFER_SYNC; 1409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao transferType = TRANSFER_CALLBACK; 1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case TRANSFER_CALLBACK: 1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (cbf == NULL) { 1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL"); 1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return BAD_VALUE; 1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case TRANSFER_OBTAIN: 1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case TRANSFER_SYNC: 1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: 1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ALOGE("Invalid transfer type %d", transferType); 1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return BAD_VALUE; 1569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTransfer = transferType; 1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // FIXME "int" here is legacy and will be replaced by size_t later 1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (frameCountInt < 0) { 1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ALOGE("Invalid frame count %d", frameCountInt); 1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return BAD_VALUE; 1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao size_t frameCount = frameCountInt; 1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ALOGV("set(): sampleRate %u, channelMask %#x, frameCount %u", sampleRate, channelMask, 1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao frameCount); 1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao AutoMutex lock(mLock); 1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mAudioRecord != 0) { 1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ALOGE("Track already in use"); 1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return INVALID_OPERATION; 1749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (inputSource == AUDIO_SOURCE_DEFAULT) { 1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao inputSource = AUDIO_SOURCE_MIC; 178b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 179b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao mInputSource = inputSource; 1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (sampleRate == 0) { 182b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ALOGE("Invalid sample rate %u", sampleRate); 1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return BAD_VALUE; 18496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 18596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines mSampleRate = sampleRate; 18696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 18796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines // these below should probably come from the audioFlinger too... 18896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines if (format == AUDIO_FORMAT_DEFAULT) { 18996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines format = AUDIO_FORMAT_PCM_16_BIT; 1903fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines } 1913fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines 1923fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines // validate parameters 1933fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines if (!audio_is_valid_format(format)) { 1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ALOGE("Invalid format %#x", format); 195462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return BAD_VALUE; 196462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Temporary restriction: AudioFlinger currently supports 16-bit PCM only 198462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if (format != AUDIO_FORMAT_PCM_16_BIT) { 199e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines ALOGE("Format %#x is not supported", format); 200 return BAD_VALUE; 201 } 202 mFormat = format; 203 204 if (!audio_is_input_channel(channelMask)) { 205 ALOGE("Invalid channel mask %#x", channelMask); 206 return BAD_VALUE; 207 } 208 mChannelMask = channelMask; 209 uint32_t channelCount = popcount(channelMask); 210 mChannelCount = channelCount; 211 212 // Assumes audio_is_linear_pcm(format), else sizeof(uint8_t) 213 mFrameSize = channelCount * audio_bytes_per_sample(format); 214 215 // validate framecount 216 size_t minFrameCount = 0; 217 status_t status = AudioRecord::getMinFrameCount(&minFrameCount, 218 sampleRate, format, channelMask); 219 if (status != NO_ERROR) { 220 ALOGE("getMinFrameCount() failed; status %d", status); 221 return status; 222 } 223 ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 224 225 if (frameCount == 0) { 226 frameCount = minFrameCount; 227 } else if (frameCount < minFrameCount) { 228 ALOGE("frameCount %u < minFrameCount %u", frameCount, minFrameCount); 229 return BAD_VALUE; 230 } 231 // mFrameCount is initialized in openRecord_l 232 mReqFrameCount = frameCount; 233 234 mNotificationFramesReq = notificationFrames; 235 mNotificationFramesAct = 0; 236 237 if (sessionId == AUDIO_SESSION_ALLOCATE) { 238 mSessionId = AudioSystem::newAudioSessionId(); 239 } else { 240 mSessionId = sessionId; 241 } 242 ALOGV("set(): mSessionId %d", mSessionId); 243 244 mFlags = flags; 245 246 // create the IAudioRecord 247 status = openRecord_l(0 /*epoch*/); 248 if (status != NO_ERROR) { 249 return status; 250 } 251 252 if (cbf != NULL) { 253 mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava); 254 mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO); 255 } 256 257 mStatus = NO_ERROR; 258 259 mActive = false; 260 mCbf = cbf; 261 mRefreshRemaining = true; 262 mUserData = user; 263 // TODO: add audio hardware input latency here 264 mLatency = (1000*mFrameCount) / sampleRate; 265 mMarkerPosition = 0; 266 mMarkerReached = false; 267 mNewPosition = 0; 268 mUpdatePeriod = 0; 269 AudioSystem::acquireAudioSessionId(mSessionId, -1); 270 mSequence = 1; 271 mObservedSequence = mSequence; 272 mInOverrun = false; 273 274 return NO_ERROR; 275} 276 277// ------------------------------------------------------------------------- 278 279status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession) 280{ 281 ALOGV("start, sync event %d trigger session %d", event, triggerSession); 282 283 AutoMutex lock(mLock); 284 if (mActive) { 285 return NO_ERROR; 286 } 287 288 // reset current position as seen by client to 0 289 mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition()); 290 // force refresh of remaining frames by processAudioBuffer() as last 291 // read before stop could be partial. 292 mRefreshRemaining = true; 293 294 mNewPosition = mProxy->getPosition() + mUpdatePeriod; 295 int32_t flags = android_atomic_acquire_load(&mCblk->mFlags); 296 297 status_t status = NO_ERROR; 298 if (!(flags & CBLK_INVALID)) { 299 ALOGV("mAudioRecord->start()"); 300 status = mAudioRecord->start(event, triggerSession); 301 if (status == DEAD_OBJECT) { 302 flags |= CBLK_INVALID; 303 } 304 } 305 if (flags & CBLK_INVALID) { 306 status = restoreRecord_l("start"); 307 } 308 309 if (status != NO_ERROR) { 310 ALOGE("start() status %d", status); 311 } else { 312 mActive = true; 313 sp<AudioRecordThread> t = mAudioRecordThread; 314 if (t != 0) { 315 t->resume(); 316 } else { 317 mPreviousPriority = getpriority(PRIO_PROCESS, 0); 318 get_sched_policy(0, &mPreviousSchedulingGroup); 319 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); 320 } 321 } 322 323 return status; 324} 325 326void AudioRecord::stop() 327{ 328 AutoMutex lock(mLock); 329 if (!mActive) { 330 return; 331 } 332 333 mActive = false; 334 mProxy->interrupt(); 335 mAudioRecord->stop(); 336 // the record head position will reset to 0, so if a marker is set, we need 337 // to activate it again 338 mMarkerReached = false; 339 sp<AudioRecordThread> t = mAudioRecordThread; 340 if (t != 0) { 341 t->pause(); 342 } else { 343 setpriority(PRIO_PROCESS, 0, mPreviousPriority); 344 set_sched_policy(0, mPreviousSchedulingGroup); 345 } 346} 347 348bool AudioRecord::stopped() const 349{ 350 AutoMutex lock(mLock); 351 return !mActive; 352} 353 354status_t AudioRecord::setMarkerPosition(uint32_t marker) 355{ 356 // The only purpose of setting marker position is to get a callback 357 if (mCbf == NULL) { 358 return INVALID_OPERATION; 359 } 360 361 AutoMutex lock(mLock); 362 mMarkerPosition = marker; 363 mMarkerReached = false; 364 365 return NO_ERROR; 366} 367 368status_t AudioRecord::getMarkerPosition(uint32_t *marker) const 369{ 370 if (marker == NULL) { 371 return BAD_VALUE; 372 } 373 374 AutoMutex lock(mLock); 375 *marker = mMarkerPosition; 376 377 return NO_ERROR; 378} 379 380status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 381{ 382 // The only purpose of setting position update period is to get a callback 383 if (mCbf == NULL) { 384 return INVALID_OPERATION; 385 } 386 387 AutoMutex lock(mLock); 388 mNewPosition = mProxy->getPosition() + updatePeriod; 389 mUpdatePeriod = updatePeriod; 390 391 return NO_ERROR; 392} 393 394status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const 395{ 396 if (updatePeriod == NULL) { 397 return BAD_VALUE; 398 } 399 400 AutoMutex lock(mLock); 401 *updatePeriod = mUpdatePeriod; 402 403 return NO_ERROR; 404} 405 406status_t AudioRecord::getPosition(uint32_t *position) const 407{ 408 if (position == NULL) { 409 return BAD_VALUE; 410 } 411 412 AutoMutex lock(mLock); 413 *position = mProxy->getPosition(); 414 415 return NO_ERROR; 416} 417 418uint32_t AudioRecord::getInputFramesLost() const 419{ 420 // no need to check mActive, because if inactive this will return 0, which is what we want 421 return AudioSystem::getInputFramesLost(getInput()); 422} 423 424// ------------------------------------------------------------------------- 425 426// must be called with mLock held 427status_t AudioRecord::openRecord_l(size_t epoch) 428{ 429 status_t status; 430 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 431 if (audioFlinger == 0) { 432 ALOGE("Could not get audioflinger"); 433 return NO_INIT; 434 } 435 436 IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT; 437 pid_t tid = -1; 438 439 // Client can only express a preference for FAST. Server will perform additional tests. 440 // The only supported use case for FAST is callback transfer mode. 441 if (mFlags & AUDIO_INPUT_FLAG_FAST) { 442 if ((mTransfer != TRANSFER_CALLBACK) || (mAudioRecordThread == 0)) { 443 ALOGW("AUDIO_INPUT_FLAG_FAST denied by client"); 444 // once denied, do not request again if IAudioRecord is re-created 445 mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST); 446 } else { 447 trackFlags |= IAudioFlinger::TRACK_FAST; 448 tid = mAudioRecordThread->getTid(); 449 } 450 } 451 452 mNotificationFramesAct = mNotificationFramesReq; 453 size_t frameCount = mReqFrameCount; 454 455 if (!(mFlags & AUDIO_INPUT_FLAG_FAST)) { 456 // Make sure that application is notified with sufficient margin before overrun 457 if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/2) { 458 mNotificationFramesAct = frameCount/2; 459 } 460 } 461 462 audio_io_handle_t input = AudioSystem::getInput(mInputSource, mSampleRate, mFormat, 463 mChannelMask, mSessionId); 464 if (input == 0) { 465 ALOGE("Could not get audio input for record source %d", mInputSource); 466 return BAD_VALUE; 467 } 468 { 469 // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger, 470 // we must release it ourselves if anything goes wrong. 471 472 size_t temp = frameCount; // temp may be replaced by a revised value of frameCount, 473 // but we will still need the original value also 474 int originalSessionId = mSessionId; 475 sp<IAudioRecord> record = audioFlinger->openRecord(input, 476 mSampleRate, mFormat, 477 mChannelMask, 478 &temp, 479 &trackFlags, 480 tid, 481 &mSessionId, 482 &status); 483 ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId, 484 "session ID changed from %d to %d", originalSessionId, mSessionId); 485 486 if (record == 0 || status != NO_ERROR) { 487 ALOGE("AudioFlinger could not create record track, status: %d", status); 488 goto release; 489 } 490 // AudioFlinger now owns the reference to the I/O handle, 491 // so we are no longer responsible for releasing it. 492 493 sp<IMemory> iMem = record->getCblk(); 494 if (iMem == 0) { 495 ALOGE("Could not get control block"); 496 return NO_INIT; 497 } 498 void *iMemPointer = iMem->pointer(); 499 if (iMemPointer == NULL) { 500 ALOGE("Could not get control block pointer"); 501 return NO_INIT; 502 } 503 if (mAudioRecord != 0) { 504 mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); 505 mDeathNotifier.clear(); 506 } 507 508 // We retain a copy of the I/O handle, but don't own the reference 509 mInput = input; 510 mAudioRecord = record; 511 mCblkMemory = iMem; 512 audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer); 513 mCblk = cblk; 514 // note that temp is the (possibly revised) value of mFrameCount 515 if (temp < frameCount || (frameCount == 0 && temp == 0)) { 516 ALOGW("Requested frameCount %u but received frameCount %u", frameCount, temp); 517 } 518 frameCount = temp; 519 // If IAudioRecord is re-created, don't let the requested frameCount 520 // decrease. This can confuse clients that cache frameCount(). 521 if (frameCount > mReqFrameCount) { 522 mReqFrameCount = frameCount; 523 } 524 525 // FIXME missing fast track frameCount logic 526 mAwaitBoost = false; 527 if (mFlags & AUDIO_INPUT_FLAG_FAST) { 528 if (trackFlags & IAudioFlinger::TRACK_FAST) { 529 ALOGV("AUDIO_INPUT_FLAG_FAST successful; frameCount %u", mFrameCount); 530 mAwaitBoost = true; 531 // double-buffering is not required for fast tracks, due to tighter scheduling 532 if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount) { 533 mNotificationFramesAct = mFrameCount; 534 } 535 } else { 536 ALOGV("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %u", mFrameCount); 537 // once denied, do not request again if IAudioRecord is re-created 538 mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST); 539 if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount/2) { 540 mNotificationFramesAct = mFrameCount/2; 541 } 542 } 543 } 544 545 // starting address of buffers in shared memory 546 void *buffers = (char*)cblk + sizeof(audio_track_cblk_t); 547 548 mFrameCount = frameCount; 549 550 // update proxy 551 mProxy = new AudioRecordClientProxy(cblk, buffers, mFrameCount, mFrameSize); 552 mProxy->setEpoch(epoch); 553 mProxy->setMinimum(mNotificationFramesAct); 554 555 mDeathNotifier = new DeathNotifier(this); 556 mAudioRecord->asBinder()->linkToDeath(mDeathNotifier, this); 557 558 return NO_ERROR; 559 } 560 561release: 562 AudioSystem::releaseInput(input); 563 if (status == NO_ERROR) { 564 status = NO_INIT; 565 } 566 return status; 567} 568 569status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 570{ 571 if (audioBuffer == NULL) { 572 return BAD_VALUE; 573 } 574 if (mTransfer != TRANSFER_OBTAIN) { 575 audioBuffer->frameCount = 0; 576 audioBuffer->size = 0; 577 audioBuffer->raw = NULL; 578 return INVALID_OPERATION; 579 } 580 581 const struct timespec *requested; 582 struct timespec timeout; 583 if (waitCount == -1) { 584 requested = &ClientProxy::kForever; 585 } else if (waitCount == 0) { 586 requested = &ClientProxy::kNonBlocking; 587 } else if (waitCount > 0) { 588 long long ms = WAIT_PERIOD_MS * (long long) waitCount; 589 timeout.tv_sec = ms / 1000; 590 timeout.tv_nsec = (int) (ms % 1000) * 1000000; 591 requested = &timeout; 592 } else { 593 ALOGE("%s invalid waitCount %d", __func__, waitCount); 594 requested = NULL; 595 } 596 return obtainBuffer(audioBuffer, requested); 597} 598 599status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *requested, 600 struct timespec *elapsed, size_t *nonContig) 601{ 602 // previous and new IAudioRecord sequence numbers are used to detect track re-creation 603 uint32_t oldSequence = 0; 604 uint32_t newSequence; 605 606 Proxy::Buffer buffer; 607 status_t status = NO_ERROR; 608 609 static const int32_t kMaxTries = 5; 610 int32_t tryCounter = kMaxTries; 611 612 do { 613 // obtainBuffer() is called with mutex unlocked, so keep extra references to these fields to 614 // keep them from going away if another thread re-creates the track during obtainBuffer() 615 sp<AudioRecordClientProxy> proxy; 616 sp<IMemory> iMem; 617 { 618 // start of lock scope 619 AutoMutex lock(mLock); 620 621 newSequence = mSequence; 622 // did previous obtainBuffer() fail due to media server death or voluntary invalidation? 623 if (status == DEAD_OBJECT) { 624 // re-create track, unless someone else has already done so 625 if (newSequence == oldSequence) { 626 status = restoreRecord_l("obtainBuffer"); 627 if (status != NO_ERROR) { 628 buffer.mFrameCount = 0; 629 buffer.mRaw = NULL; 630 buffer.mNonContig = 0; 631 break; 632 } 633 } 634 } 635 oldSequence = newSequence; 636 637 // Keep the extra references 638 proxy = mProxy; 639 iMem = mCblkMemory; 640 641 // Non-blocking if track is stopped 642 if (!mActive) { 643 requested = &ClientProxy::kNonBlocking; 644 } 645 646 } // end of lock scope 647 648 buffer.mFrameCount = audioBuffer->frameCount; 649 // FIXME starts the requested timeout and elapsed over from scratch 650 status = proxy->obtainBuffer(&buffer, requested, elapsed); 651 652 } while ((status == DEAD_OBJECT) && (tryCounter-- > 0)); 653 654 audioBuffer->frameCount = buffer.mFrameCount; 655 audioBuffer->size = buffer.mFrameCount * mFrameSize; 656 audioBuffer->raw = buffer.mRaw; 657 if (nonContig != NULL) { 658 *nonContig = buffer.mNonContig; 659 } 660 return status; 661} 662 663void AudioRecord::releaseBuffer(Buffer* audioBuffer) 664{ 665 // all TRANSFER_* are valid 666 667 size_t stepCount = audioBuffer->size / mFrameSize; 668 if (stepCount == 0) { 669 return; 670 } 671 672 Proxy::Buffer buffer; 673 buffer.mFrameCount = stepCount; 674 buffer.mRaw = audioBuffer->raw; 675 676 AutoMutex lock(mLock); 677 mInOverrun = false; 678 mProxy->releaseBuffer(&buffer); 679 680 // the server does not automatically disable recorder on overrun, so no need to restart 681} 682 683audio_io_handle_t AudioRecord::getInput() const 684{ 685 AutoMutex lock(mLock); 686 return mInput; 687} 688 689// ------------------------------------------------------------------------- 690 691ssize_t AudioRecord::read(void* buffer, size_t userSize) 692{ 693 if (mTransfer != TRANSFER_SYNC) { 694 return INVALID_OPERATION; 695 } 696 697 if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) { 698 // sanity-check. user is most-likely passing an error code, and it would 699 // make the return value ambiguous (actualSize vs error). 700 ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)", buffer, userSize, userSize); 701 return BAD_VALUE; 702 } 703 704 ssize_t read = 0; 705 Buffer audioBuffer; 706 707 while (userSize >= mFrameSize) { 708 audioBuffer.frameCount = userSize / mFrameSize; 709 710 status_t err = obtainBuffer(&audioBuffer, &ClientProxy::kForever); 711 if (err < 0) { 712 if (read > 0) { 713 break; 714 } 715 return ssize_t(err); 716 } 717 718 size_t bytesRead = audioBuffer.size; 719 memcpy(buffer, audioBuffer.i8, bytesRead); 720 buffer = ((char *) buffer) + bytesRead; 721 userSize -= bytesRead; 722 read += bytesRead; 723 724 releaseBuffer(&audioBuffer); 725 } 726 727 return read; 728} 729 730// ------------------------------------------------------------------------- 731 732nsecs_t AudioRecord::processAudioBuffer() 733{ 734 mLock.lock(); 735 if (mAwaitBoost) { 736 mAwaitBoost = false; 737 mLock.unlock(); 738 static const int32_t kMaxTries = 5; 739 int32_t tryCounter = kMaxTries; 740 uint32_t pollUs = 10000; 741 do { 742 int policy = sched_getscheduler(0); 743 if (policy == SCHED_FIFO || policy == SCHED_RR) { 744 break; 745 } 746 usleep(pollUs); 747 pollUs <<= 1; 748 } while (tryCounter-- > 0); 749 if (tryCounter < 0) { 750 ALOGE("did not receive expected priority boost on time"); 751 } 752 // Run again immediately 753 return 0; 754 } 755 756 // Can only reference mCblk while locked 757 int32_t flags = android_atomic_and(~CBLK_OVERRUN, &mCblk->mFlags); 758 759 // Check for track invalidation 760 if (flags & CBLK_INVALID) { 761 (void) restoreRecord_l("processAudioBuffer"); 762 mLock.unlock(); 763 // Run again immediately, but with a new IAudioRecord 764 return 0; 765 } 766 767 bool active = mActive; 768 769 // Manage overrun callback, must be done under lock to avoid race with releaseBuffer() 770 bool newOverrun = false; 771 if (flags & CBLK_OVERRUN) { 772 if (!mInOverrun) { 773 mInOverrun = true; 774 newOverrun = true; 775 } 776 } 777 778 // Get current position of server 779 size_t position = mProxy->getPosition(); 780 781 // Manage marker callback 782 bool markerReached = false; 783 size_t markerPosition = mMarkerPosition; 784 // FIXME fails for wraparound, need 64 bits 785 if (!mMarkerReached && (markerPosition > 0) && (position >= markerPosition)) { 786 mMarkerReached = markerReached = true; 787 } 788 789 // Determine the number of new position callback(s) that will be needed, while locked 790 size_t newPosCount = 0; 791 size_t newPosition = mNewPosition; 792 uint32_t updatePeriod = mUpdatePeriod; 793 // FIXME fails for wraparound, need 64 bits 794 if (updatePeriod > 0 && position >= newPosition) { 795 newPosCount = ((position - newPosition) / updatePeriod) + 1; 796 mNewPosition += updatePeriod * newPosCount; 797 } 798 799 // Cache other fields that will be needed soon 800 size_t notificationFrames = mNotificationFramesAct; 801 if (mRefreshRemaining) { 802 mRefreshRemaining = false; 803 mRemainingFrames = notificationFrames; 804 mRetryOnPartialBuffer = false; 805 } 806 size_t misalignment = mProxy->getMisalignment(); 807 uint32_t sequence = mSequence; 808 809 // These fields don't need to be cached, because they are assigned only by set(): 810 // mTransfer, mCbf, mUserData, mSampleRate, mFrameSize 811 812 mLock.unlock(); 813 814 // perform callbacks while unlocked 815 if (newOverrun) { 816 mCbf(EVENT_OVERRUN, mUserData, NULL); 817 } 818 if (markerReached) { 819 mCbf(EVENT_MARKER, mUserData, &markerPosition); 820 } 821 while (newPosCount > 0) { 822 size_t temp = newPosition; 823 mCbf(EVENT_NEW_POS, mUserData, &temp); 824 newPosition += updatePeriod; 825 newPosCount--; 826 } 827 if (mObservedSequence != sequence) { 828 mObservedSequence = sequence; 829 mCbf(EVENT_NEW_IAUDIORECORD, mUserData, NULL); 830 } 831 832 // if inactive, then don't run me again until re-started 833 if (!active) { 834 return NS_INACTIVE; 835 } 836 837 // Compute the estimated time until the next timed event (position, markers) 838 uint32_t minFrames = ~0; 839 if (!markerReached && position < markerPosition) { 840 minFrames = markerPosition - position; 841 } 842 if (updatePeriod > 0 && updatePeriod < minFrames) { 843 minFrames = updatePeriod; 844 } 845 846 // If > 0, poll periodically to recover from a stuck server. A good value is 2. 847 static const uint32_t kPoll = 0; 848 if (kPoll > 0 && mTransfer == TRANSFER_CALLBACK && kPoll * notificationFrames < minFrames) { 849 minFrames = kPoll * notificationFrames; 850 } 851 852 // Convert frame units to time units 853 nsecs_t ns = NS_WHENEVER; 854 if (minFrames != (uint32_t) ~0) { 855 // This "fudge factor" avoids soaking CPU, and compensates for late progress by server 856 static const nsecs_t kFudgeNs = 10000000LL; // 10 ms 857 ns = ((minFrames * 1000000000LL) / mSampleRate) + kFudgeNs; 858 } 859 860 // If not supplying data by EVENT_MORE_DATA, then we're done 861 if (mTransfer != TRANSFER_CALLBACK) { 862 return ns; 863 } 864 865 struct timespec timeout; 866 const struct timespec *requested = &ClientProxy::kForever; 867 if (ns != NS_WHENEVER) { 868 timeout.tv_sec = ns / 1000000000LL; 869 timeout.tv_nsec = ns % 1000000000LL; 870 ALOGV("timeout %ld.%03d", timeout.tv_sec, (int) timeout.tv_nsec / 1000000); 871 requested = &timeout; 872 } 873 874 while (mRemainingFrames > 0) { 875 876 Buffer audioBuffer; 877 audioBuffer.frameCount = mRemainingFrames; 878 size_t nonContig; 879 status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig); 880 LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0), 881 "obtainBuffer() err=%d frameCount=%u", err, audioBuffer.frameCount); 882 requested = &ClientProxy::kNonBlocking; 883 size_t avail = audioBuffer.frameCount + nonContig; 884 ALOGV("obtainBuffer(%u) returned %u = %u + %u err %d", 885 mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err); 886 if (err != NO_ERROR) { 887 if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) { 888 break; 889 } 890 ALOGE("Error %d obtaining an audio buffer, giving up.", err); 891 return NS_NEVER; 892 } 893 894 if (mRetryOnPartialBuffer) { 895 mRetryOnPartialBuffer = false; 896 if (avail < mRemainingFrames) { 897 int64_t myns = ((mRemainingFrames - avail) * 898 1100000000LL) / mSampleRate; 899 if (ns < 0 || myns < ns) { 900 ns = myns; 901 } 902 return ns; 903 } 904 } 905 906 size_t reqSize = audioBuffer.size; 907 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 908 size_t readSize = audioBuffer.size; 909 910 // Sanity check on returned size 911 if (ssize_t(readSize) < 0 || readSize > reqSize) { 912 ALOGE("EVENT_MORE_DATA requested %u bytes but callback returned %d bytes", 913 reqSize, (int) readSize); 914 return NS_NEVER; 915 } 916 917 if (readSize == 0) { 918 // The callback is done consuming buffers 919 // Keep this thread going to handle timed events and 920 // still try to provide more data in intervals of WAIT_PERIOD_MS 921 // but don't just loop and block the CPU, so wait 922 return WAIT_PERIOD_MS * 1000000LL; 923 } 924 925 size_t releasedFrames = readSize / mFrameSize; 926 audioBuffer.frameCount = releasedFrames; 927 mRemainingFrames -= releasedFrames; 928 if (misalignment >= releasedFrames) { 929 misalignment -= releasedFrames; 930 } else { 931 misalignment = 0; 932 } 933 934 releaseBuffer(&audioBuffer); 935 936 // FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer 937 // if callback doesn't like to accept the full chunk 938 if (readSize < reqSize) { 939 continue; 940 } 941 942 // There could be enough non-contiguous frames available to satisfy the remaining request 943 if (mRemainingFrames <= nonContig) { 944 continue; 945 } 946 947#if 0 948 // This heuristic tries to collapse a series of EVENT_MORE_DATA that would total to a 949 // sum <= notificationFrames. It replaces that series by at most two EVENT_MORE_DATA 950 // that total to a sum == notificationFrames. 951 if (0 < misalignment && misalignment <= mRemainingFrames) { 952 mRemainingFrames = misalignment; 953 return (mRemainingFrames * 1100000000LL) / mSampleRate; 954 } 955#endif 956 957 } 958 mRemainingFrames = notificationFrames; 959 mRetryOnPartialBuffer = true; 960 961 // A lot has transpired since ns was calculated, so run again immediately and re-calculate 962 return 0; 963} 964 965status_t AudioRecord::restoreRecord_l(const char *from) 966{ 967 ALOGW("dead IAudioRecord, creating a new one from %s()", from); 968 ++mSequence; 969 status_t result; 970 971 // if the new IAudioRecord is created, openRecord_l() will modify the 972 // following member variables: mAudioRecord, mCblkMemory and mCblk. 973 // It will also delete the strong references on previous IAudioRecord and IMemory 974 size_t position = mProxy->getPosition(); 975 mNewPosition = position + mUpdatePeriod; 976 result = openRecord_l(position); 977 if (result == NO_ERROR) { 978 if (mActive) { 979 // callback thread or sync event hasn't changed 980 // FIXME this fails if we have a new AudioFlinger instance 981 result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 982 } 983 } 984 if (result != NO_ERROR) { 985 ALOGW("restoreRecord_l() failed status %d", result); 986 mActive = false; 987 } 988 989 return result; 990} 991 992// ========================================================================= 993 994void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused) 995{ 996 sp<AudioRecord> audioRecord = mAudioRecord.promote(); 997 if (audioRecord != 0) { 998 AutoMutex lock(audioRecord->mLock); 999 audioRecord->mProxy->binderDied(); 1000 } 1001} 1002 1003// ========================================================================= 1004 1005AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava) 1006 : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL), 1007 mIgnoreNextPausedInt(false) 1008{ 1009} 1010 1011AudioRecord::AudioRecordThread::~AudioRecordThread() 1012{ 1013} 1014 1015bool AudioRecord::AudioRecordThread::threadLoop() 1016{ 1017 { 1018 AutoMutex _l(mMyLock); 1019 if (mPaused) { 1020 mMyCond.wait(mMyLock); 1021 // caller will check for exitPending() 1022 return true; 1023 } 1024 if (mIgnoreNextPausedInt) { 1025 mIgnoreNextPausedInt = false; 1026 mPausedInt = false; 1027 } 1028 if (mPausedInt) { 1029 if (mPausedNs > 0) { 1030 (void) mMyCond.waitRelative(mMyLock, mPausedNs); 1031 } else { 1032 mMyCond.wait(mMyLock); 1033 } 1034 mPausedInt = false; 1035 return true; 1036 } 1037 } 1038 nsecs_t ns = mReceiver.processAudioBuffer(); 1039 switch (ns) { 1040 case 0: 1041 return true; 1042 case NS_INACTIVE: 1043 pauseInternal(); 1044 return true; 1045 case NS_NEVER: 1046 return false; 1047 case NS_WHENEVER: 1048 // FIXME increase poll interval, or make event-driven 1049 ns = 1000000000LL; 1050 // fall through 1051 default: 1052 LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %lld", ns); 1053 pauseInternal(ns); 1054 return true; 1055 } 1056} 1057 1058void AudioRecord::AudioRecordThread::requestExit() 1059{ 1060 // must be in this order to avoid a race condition 1061 Thread::requestExit(); 1062 resume(); 1063} 1064 1065void AudioRecord::AudioRecordThread::pause() 1066{ 1067 AutoMutex _l(mMyLock); 1068 mPaused = true; 1069} 1070 1071void AudioRecord::AudioRecordThread::resume() 1072{ 1073 AutoMutex _l(mMyLock); 1074 mIgnoreNextPausedInt = true; 1075 if (mPaused || mPausedInt) { 1076 mPaused = false; 1077 mPausedInt = false; 1078 mMyCond.signal(); 1079 } 1080} 1081 1082void AudioRecord::AudioRecordThread::pauseInternal(nsecs_t ns) 1083{ 1084 AutoMutex _l(mMyLock); 1085 mPausedInt = true; 1086 mPausedNs = ns; 1087} 1088 1089// ------------------------------------------------------------------------- 1090 1091}; // namespace android 1092