1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "sles_allinclusive.h" 18 #include "android_prompts.h" 19 #include "channels.h" 20 21 #include <utils/String16.h> 22 23 #include <system/audio.h> 24 #include <SLES/OpenSLES_Android.h> 25 26 #include <android_runtime/AndroidRuntime.h> 27 28 #define KEY_RECORDING_SOURCE_PARAMSIZE sizeof(SLuint32) 29 #define KEY_RECORDING_PRESET_PARAMSIZE sizeof(SLuint32) 30 #define KEY_PERFORMANCE_MODE_PARAMSIZE sizeof(SLuint32) 31 32 //----------------------------------------------------------------------------- 33 // Internal utility functions 34 //---------------------------- 35 36 SLresult audioRecorder_setPreset(CAudioRecorder* ar, SLuint32 recordPreset) { 37 SLresult result = SL_RESULT_SUCCESS; 38 39 audio_source_t newRecordSource = AUDIO_SOURCE_DEFAULT; 40 switch (recordPreset) { 41 case SL_ANDROID_RECORDING_PRESET_GENERIC: 42 newRecordSource = AUDIO_SOURCE_DEFAULT; 43 break; 44 case SL_ANDROID_RECORDING_PRESET_CAMCORDER: 45 newRecordSource = AUDIO_SOURCE_CAMCORDER; 46 break; 47 case SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION: 48 newRecordSource = AUDIO_SOURCE_VOICE_RECOGNITION; 49 break; 50 case SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION: 51 newRecordSource = AUDIO_SOURCE_VOICE_COMMUNICATION; 52 break; 53 case SL_ANDROID_RECORDING_PRESET_UNPROCESSED: 54 newRecordSource = AUDIO_SOURCE_UNPROCESSED; 55 break; 56 case SL_ANDROID_RECORDING_PRESET_NONE: 57 // it is an error to set preset "none" 58 default: 59 SL_LOGE(ERROR_RECORDERPRESET_SET_UNKNOWN_PRESET); 60 result = SL_RESULT_PARAMETER_INVALID; 61 } 62 63 // recording preset needs to be set before the object is realized 64 // (ap->mAudioRecord is supposed to be 0 until then) 65 if (SL_OBJECT_STATE_UNREALIZED != ar->mObject.mState) { 66 SL_LOGE(ERROR_RECORDERPRESET_REALIZED); 67 result = SL_RESULT_PRECONDITIONS_VIOLATED; 68 } else { 69 ar->mRecordSource = newRecordSource; 70 } 71 72 return result; 73 } 74 75 76 //----------------------------------------------------------------------------- 77 SLresult audioRecorder_setPerformanceMode(CAudioRecorder* ar, SLuint32 mode) { 78 SLresult result = SL_RESULT_SUCCESS; 79 SL_LOGV("performance mode set to %d", mode); 80 81 SLuint32 perfMode = ANDROID_PERFORMANCE_MODE_DEFAULT; 82 switch (mode) { 83 case SL_ANDROID_PERFORMANCE_LATENCY: 84 perfMode = ANDROID_PERFORMANCE_MODE_LATENCY; 85 break; 86 case SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS: 87 perfMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS; 88 break; 89 case SL_ANDROID_PERFORMANCE_NONE: 90 perfMode = ANDROID_PERFORMANCE_MODE_NONE; 91 break; 92 case SL_ANDROID_PERFORMANCE_POWER_SAVING: 93 perfMode = ANDROID_PERFORMANCE_MODE_POWER_SAVING; 94 break; 95 default: 96 SL_LOGE(ERROR_CONFIG_PERF_MODE_UNKNOWN); 97 result = SL_RESULT_PARAMETER_INVALID; 98 break; 99 } 100 101 // performance mode needs to be set before the object is realized 102 // (ar->mAudioRecord is supposed to be NULL until then) 103 if (SL_OBJECT_STATE_UNREALIZED != ar->mObject.mState) { 104 SL_LOGE(ERROR_CONFIG_PERF_MODE_REALIZED); 105 result = SL_RESULT_PRECONDITIONS_VIOLATED; 106 } else { 107 ar->mPerformanceMode = perfMode; 108 } 109 110 return result; 111 } 112 113 114 SLresult audioRecorder_getPreset(CAudioRecorder* ar, SLuint32* pPreset) { 115 SLresult result = SL_RESULT_SUCCESS; 116 117 switch (ar->mRecordSource) { 118 case AUDIO_SOURCE_DEFAULT: 119 case AUDIO_SOURCE_MIC: 120 *pPreset = SL_ANDROID_RECORDING_PRESET_GENERIC; 121 break; 122 case AUDIO_SOURCE_VOICE_UPLINK: 123 case AUDIO_SOURCE_VOICE_DOWNLINK: 124 case AUDIO_SOURCE_VOICE_CALL: 125 *pPreset = SL_ANDROID_RECORDING_PRESET_NONE; 126 break; 127 case AUDIO_SOURCE_VOICE_RECOGNITION: 128 *pPreset = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION; 129 break; 130 case AUDIO_SOURCE_CAMCORDER: 131 *pPreset = SL_ANDROID_RECORDING_PRESET_CAMCORDER; 132 break; 133 case AUDIO_SOURCE_VOICE_COMMUNICATION: 134 *pPreset = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; 135 break; 136 case AUDIO_SOURCE_UNPROCESSED: 137 *pPreset = SL_ANDROID_RECORDING_PRESET_UNPROCESSED; 138 break; 139 default: 140 *pPreset = SL_ANDROID_RECORDING_PRESET_NONE; 141 result = SL_RESULT_INTERNAL_ERROR; 142 break; 143 } 144 145 return result; 146 } 147 148 149 //----------------------------------------------------------------------------- 150 SLresult audioRecorder_getPerformanceMode(CAudioRecorder* ar, SLuint32 *pMode) { 151 SLresult result = SL_RESULT_SUCCESS; 152 153 switch (ar->mPerformanceMode) { 154 case ANDROID_PERFORMANCE_MODE_LATENCY: 155 *pMode = SL_ANDROID_PERFORMANCE_LATENCY; 156 break; 157 case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS: 158 *pMode = SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS; 159 break; 160 case ANDROID_PERFORMANCE_MODE_NONE: 161 *pMode = SL_ANDROID_PERFORMANCE_NONE; 162 break; 163 case ANDROID_PERFORMANCE_MODE_POWER_SAVING: 164 *pMode = SL_ANDROID_PERFORMANCE_POWER_SAVING; 165 break; 166 default: 167 result = SL_RESULT_INTERNAL_ERROR; 168 *pMode = SL_ANDROID_PERFORMANCE_LATENCY; 169 break; 170 } 171 172 return result; 173 } 174 175 176 void audioRecorder_handleNewPos_lockRecord(CAudioRecorder* ar) { 177 //SL_LOGV("received event EVENT_NEW_POS from AudioRecord"); 178 slRecordCallback callback = NULL; 179 void* callbackPContext = NULL; 180 181 interface_lock_shared(&ar->mRecord); 182 callback = ar->mRecord.mCallback; 183 callbackPContext = ar->mRecord.mContext; 184 interface_unlock_shared(&ar->mRecord); 185 186 if (NULL != callback) { 187 // getting this event implies SL_RECORDEVENT_HEADATNEWPOS was set in the event mask 188 (*callback)(&ar->mRecord.mItf, callbackPContext, SL_RECORDEVENT_HEADATNEWPOS); 189 } 190 } 191 192 193 void audioRecorder_handleMarker_lockRecord(CAudioRecorder* ar) { 194 //SL_LOGV("received event EVENT_MARKER from AudioRecord"); 195 slRecordCallback callback = NULL; 196 void* callbackPContext = NULL; 197 198 interface_lock_shared(&ar->mRecord); 199 callback = ar->mRecord.mCallback; 200 callbackPContext = ar->mRecord.mContext; 201 interface_unlock_shared(&ar->mRecord); 202 203 if (NULL != callback) { 204 // getting this event implies SL_RECORDEVENT_HEADATMARKER was set in the event mask 205 (*callback)(&ar->mRecord.mItf, callbackPContext, SL_RECORDEVENT_HEADATMARKER); 206 } 207 } 208 209 210 void audioRecorder_handleOverrun_lockRecord(CAudioRecorder* ar) { 211 //SL_LOGV("received event EVENT_OVERRUN from AudioRecord"); 212 slRecordCallback callback = NULL; 213 void* callbackPContext = NULL; 214 215 interface_lock_shared(&ar->mRecord); 216 if (ar->mRecord.mCallbackEventsMask & SL_RECORDEVENT_HEADSTALLED) { 217 callback = ar->mRecord.mCallback; 218 callbackPContext = ar->mRecord.mContext; 219 } 220 interface_unlock_shared(&ar->mRecord); 221 222 if (NULL != callback) { 223 (*callback)(&ar->mRecord.mItf, callbackPContext, SL_RECORDEVENT_HEADSTALLED); 224 } 225 } 226 227 //----------------------------------------------------------------------------- 228 SLresult android_audioRecorder_checkSourceSink(CAudioRecorder* ar) { 229 230 const SLDataSource *pAudioSrc = &ar->mDataSource.u.mSource; 231 const SLDataSink *pAudioSnk = &ar->mDataSink.u.mSink; 232 233 const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator; 234 const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSnk->pFormat; 235 236 const SLuint32 *df_representation = NULL; // pointer to representation field, if it exists 237 238 // sink must be an Android simple buffer queue with PCM data format 239 switch (sinkLocatorType) { 240 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: { 241 switch (sinkFormatType) { 242 case SL_ANDROID_DATAFORMAT_PCM_EX: { 243 const SLAndroidDataFormat_PCM_EX *df_pcm = 244 (SLAndroidDataFormat_PCM_EX *) pAudioSnk->pFormat; 245 // checkDataFormat() already checked representation 246 df_representation = &df_pcm->representation; 247 } // SL_ANDROID_DATAFORMAT_PCM_EX - fall through to next test. 248 FALLTHROUGH_INTENDED; 249 case SL_DATAFORMAT_PCM: { 250 const SLDataFormat_PCM *df_pcm = (const SLDataFormat_PCM *) pAudioSnk->pFormat; 251 // checkDataFormat already checked sample rate, channels, and mask 252 ar->mNumChannels = df_pcm->numChannels; 253 254 if (df_pcm->endianness != ar->mObject.mEngine->mEngine.mNativeEndianness) { 255 SL_LOGE("Cannot create audio recorder: unsupported byte order %u", 256 df_pcm->endianness); 257 return SL_RESULT_CONTENT_UNSUPPORTED; 258 } 259 260 ar->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES 261 SL_LOGV("AudioRecorder requested sample rate = %u mHz, %u channel(s)", 262 ar->mSampleRateMilliHz, ar->mNumChannels); 263 264 // we don't support container size != sample depth 265 if (df_pcm->containerSize != df_pcm->bitsPerSample) { 266 SL_LOGE("Cannot create audio recorder: unsupported container size %u bits for " 267 "sample depth %u bits", 268 df_pcm->containerSize, (SLuint32)df_pcm->bitsPerSample); 269 return SL_RESULT_CONTENT_UNSUPPORTED; 270 } 271 272 } break; 273 default: 274 SL_LOGE(ERROR_RECORDER_SINK_FORMAT_MUST_BE_PCM); 275 return SL_RESULT_PARAMETER_INVALID; 276 } // switch (sourceFormatType) 277 } break; // case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE 278 default: 279 SL_LOGE(ERROR_RECORDER_SINK_MUST_BE_ANDROIDSIMPLEBUFFERQUEUE); 280 return SL_RESULT_PARAMETER_INVALID; 281 } // switch (sourceLocatorType) 282 283 // Source check: 284 // only input device sources are supported 285 // check it's an IO device 286 if (SL_DATALOCATOR_IODEVICE != *(SLuint32 *)pAudioSrc->pLocator) { 287 SL_LOGE(ERROR_RECORDER_SOURCE_MUST_BE_IODEVICE); 288 return SL_RESULT_PARAMETER_INVALID; 289 } else { 290 291 // check it's an input device 292 SLDataLocator_IODevice *dl_iod = (SLDataLocator_IODevice *) pAudioSrc->pLocator; 293 if (SL_IODEVICE_AUDIOINPUT != dl_iod->deviceType) { 294 SL_LOGE(ERROR_RECORDER_IODEVICE_MUST_BE_AUDIOINPUT); 295 return SL_RESULT_PARAMETER_INVALID; 296 } 297 298 // check it's the default input device, others aren't supported here 299 if (SL_DEFAULTDEVICEID_AUDIOINPUT != dl_iod->deviceID) { 300 SL_LOGE(ERROR_RECORDER_INPUT_ID_MUST_BE_DEFAULT); 301 return SL_RESULT_PARAMETER_INVALID; 302 } 303 } 304 305 return SL_RESULT_SUCCESS; 306 } 307 //----------------------------------------------------------------------------- 308 static void audioRecorder_callback(int event, void* user, void *info) { 309 //SL_LOGV("audioRecorder_callback(%d, %p, %p) entering", event, user, info); 310 311 CAudioRecorder *ar = (CAudioRecorder *)user; 312 313 if (!android::CallbackProtector::enterCbIfOk(ar->mCallbackProtector)) { 314 // it is not safe to enter the callback (the track is about to go away) 315 return; 316 } 317 318 void * callbackPContext = NULL; 319 320 switch (event) { 321 case android::AudioRecord::EVENT_MORE_DATA: { 322 slBufferQueueCallback callback = NULL; 323 android::AudioRecord::Buffer* pBuff = (android::AudioRecord::Buffer*)info; 324 325 // push data to the buffer queue 326 interface_lock_exclusive(&ar->mBufferQueue); 327 328 if (ar->mBufferQueue.mState.count != 0) { 329 assert(ar->mBufferQueue.mFront != ar->mBufferQueue.mRear); 330 331 BufferHeader *oldFront = ar->mBufferQueue.mFront; 332 BufferHeader *newFront = &oldFront[1]; 333 334 size_t availSink = oldFront->mSize - ar->mBufferQueue.mSizeConsumed; 335 size_t availSource = pBuff->size; 336 size_t bytesToCopy = availSink < availSource ? availSink : availSource; 337 void *pDest = (char *)oldFront->mBuffer + ar->mBufferQueue.mSizeConsumed; 338 memcpy(pDest, pBuff->raw, bytesToCopy); 339 340 if (bytesToCopy < availSink) { 341 // can't consume the whole or rest of the buffer in one shot 342 ar->mBufferQueue.mSizeConsumed += availSource; 343 // pBuff->size is already equal to bytesToCopy in this case 344 } else { 345 // finish pushing the buffer or push the buffer in one shot 346 pBuff->size = bytesToCopy; 347 ar->mBufferQueue.mSizeConsumed = 0; 348 if (newFront == &ar->mBufferQueue.mArray[ar->mBufferQueue.mNumBuffers + 1]) { 349 newFront = ar->mBufferQueue.mArray; 350 } 351 ar->mBufferQueue.mFront = newFront; 352 353 ar->mBufferQueue.mState.count--; 354 ar->mBufferQueue.mState.playIndex++; 355 356 // data has been copied to the buffer, and the buffer queue state has been updated 357 // we will notify the client if applicable 358 callback = ar->mBufferQueue.mCallback; 359 // save callback data 360 callbackPContext = ar->mBufferQueue.mContext; 361 } 362 } else { // empty queue 363 // no destination to push the data 364 pBuff->size = 0; 365 } 366 367 interface_unlock_exclusive(&ar->mBufferQueue); 368 369 // notify client 370 if (NULL != callback) { 371 (*callback)(&ar->mBufferQueue.mItf, callbackPContext); 372 } 373 } 374 break; 375 376 case android::AudioRecord::EVENT_OVERRUN: 377 audioRecorder_handleOverrun_lockRecord(ar); 378 break; 379 380 case android::AudioRecord::EVENT_MARKER: 381 audioRecorder_handleMarker_lockRecord(ar); 382 break; 383 384 case android::AudioRecord::EVENT_NEW_POS: 385 audioRecorder_handleNewPos_lockRecord(ar); 386 break; 387 388 case android::AudioRecord::EVENT_NEW_IAUDIORECORD: 389 // ignore for now 390 break; 391 392 default: 393 SL_LOGE("Encountered unknown AudioRecord event %d for CAudioRecord %p", event, ar); 394 break; 395 } 396 397 ar->mCallbackProtector->exitCb(); 398 } 399 400 401 //----------------------------------------------------------------------------- 402 SLresult android_audioRecorder_create(CAudioRecorder* ar) { 403 SL_LOGV("android_audioRecorder_create(%p) entering", ar); 404 405 const SLDataSource *pAudioSrc = &ar->mDataSource.u.mSource; 406 const SLDataSink *pAudioSnk = &ar->mDataSink.u.mSink; 407 SLresult result = SL_RESULT_SUCCESS; 408 409 const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator; 410 const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator; 411 412 // the following platform-independent fields have been initialized in CreateAudioRecorder() 413 // ar->mNumChannels 414 // ar->mSampleRateMilliHz 415 416 if ((SL_DATALOCATOR_IODEVICE == sourceLocatorType) && 417 (SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE == sinkLocatorType)) { 418 // microphone to simple buffer queue 419 ar->mAndroidObjType = AUDIORECORDER_FROM_MIC_TO_PCM_BUFFERQUEUE; 420 ar->mAudioRecord.clear(); 421 ar->mCallbackProtector = new android::CallbackProtector(); 422 ar->mRecordSource = AUDIO_SOURCE_DEFAULT; 423 ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_DEFAULT; 424 } else { 425 result = SL_RESULT_CONTENT_UNSUPPORTED; 426 } 427 428 return result; 429 } 430 431 432 //----------------------------------------------------------------------------- 433 SLresult android_audioRecorder_setConfig(CAudioRecorder* ar, const SLchar *configKey, 434 const void *pConfigValue, SLuint32 valueSize) { 435 436 SLresult result; 437 438 assert(NULL != ar && NULL != configKey && NULL != pConfigValue); 439 if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_RECORDING_PRESET) == 0) { 440 441 // recording preset 442 if (KEY_RECORDING_PRESET_PARAMSIZE > valueSize) { 443 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 444 result = SL_RESULT_BUFFER_INSUFFICIENT; 445 } else { 446 result = audioRecorder_setPreset(ar, *(SLuint32*)pConfigValue); 447 } 448 449 } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) { 450 451 // performance mode 452 if (KEY_PERFORMANCE_MODE_PARAMSIZE > valueSize) { 453 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 454 result = SL_RESULT_BUFFER_INSUFFICIENT; 455 } else { 456 result = audioRecorder_setPerformanceMode(ar, *(SLuint32*)pConfigValue); 457 } 458 } else { 459 SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY); 460 result = SL_RESULT_PARAMETER_INVALID; 461 } 462 463 return result; 464 } 465 466 467 //----------------------------------------------------------------------------- 468 SLresult android_audioRecorder_getConfig(CAudioRecorder* ar, const SLchar *configKey, 469 SLuint32* pValueSize, void *pConfigValue) { 470 471 SLresult result; 472 473 assert(NULL != ar && NULL != configKey && NULL != pValueSize); 474 if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_RECORDING_PRESET) == 0) { 475 476 // recording preset 477 if (NULL == pConfigValue) { 478 result = SL_RESULT_SUCCESS; 479 } else if (KEY_RECORDING_PRESET_PARAMSIZE > *pValueSize) { 480 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 481 result = SL_RESULT_BUFFER_INSUFFICIENT; 482 } else { 483 result = audioRecorder_getPreset(ar, (SLuint32*)pConfigValue); 484 } 485 *pValueSize = KEY_RECORDING_PRESET_PARAMSIZE; 486 487 } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) { 488 489 // performance mode 490 if (NULL == pConfigValue) { 491 result = SL_RESULT_SUCCESS; 492 } else if (KEY_PERFORMANCE_MODE_PARAMSIZE > *pValueSize) { 493 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 494 result = SL_RESULT_BUFFER_INSUFFICIENT; 495 } else { 496 result = audioRecorder_getPerformanceMode(ar, (SLuint32*)pConfigValue); 497 } 498 *pValueSize = KEY_PERFORMANCE_MODE_PARAMSIZE; 499 500 } else { 501 SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY); 502 result = SL_RESULT_PARAMETER_INVALID; 503 } 504 505 return result; 506 } 507 508 // Called from android_audioRecorder_realize for a PCM buffer queue recorder before creating the 509 // AudioRecord to determine which performance modes are allowed based on effect interfaces present 510 static void checkAndSetPerformanceModePre(CAudioRecorder* ar) 511 { 512 SLuint32 allowedModes = ANDROID_PERFORMANCE_MODE_ALL; 513 assert(ar->mAndroidObjType == AUDIORECORDER_FROM_MIC_TO_PCM_BUFFERQUEUE); 514 515 // no need to check the buffer queue size, application side 516 // double-buffering (and more) is not a requirement for using fast tracks 517 518 // Check a blacklist of interfaces that are incompatible with fast tracks. 519 // The alternative, to check a whitelist of compatible interfaces, is 520 // more maintainable but is too slow. As a compromise, in a debug build 521 // we use both methods and warn if they produce different results. 522 // In release builds, we only use the blacklist method. 523 // If a blacklisted interface is added after realization using 524 // DynamicInterfaceManagement::AddInterface, 525 // then this won't be detected but the interface will be ineffective. 526 static const unsigned blacklist[] = { 527 MPH_ANDROIDACOUSTICECHOCANCELLATION, 528 MPH_ANDROIDAUTOMATICGAINCONTROL, 529 MPH_ANDROIDNOISESUPPRESSION, 530 MPH_ANDROIDEFFECT, 531 // FIXME The problem with a blacklist is remembering to add new interfaces here 532 }; 533 534 for (unsigned i = 0; i < sizeof(blacklist)/sizeof(blacklist[0]); ++i) { 535 if (IsInterfaceInitialized(&ar->mObject, blacklist[i])) { 536 uint32_t flags = 0; 537 538 allowedModes &= ~ANDROID_PERFORMANCE_MODE_LATENCY; 539 540 // if generic effect interface is used we don't know which effect will be used and 541 // disable all low latency performance modes 542 if (blacklist[i] != MPH_ANDROIDEFFECT) { 543 switch (blacklist[i]) { 544 case MPH_ANDROIDACOUSTICECHOCANCELLATION: 545 SL_LOGV("checkAndSetPerformanceModePre found AEC name %s", 546 ar->mAcousticEchoCancellation.mAECDescriptor.name); 547 flags = ar->mAcousticEchoCancellation.mAECDescriptor.flags; 548 break; 549 case MPH_ANDROIDAUTOMATICGAINCONTROL: 550 SL_LOGV("checkAndSetPerformanceModePre found AGC name %s", 551 ar->mAutomaticGainControl.mAGCDescriptor.name); 552 flags = ar->mAutomaticGainControl.mAGCDescriptor.flags; 553 break; 554 case MPH_ANDROIDNOISESUPPRESSION: 555 SL_LOGV("checkAndSetPerformanceModePre found NS name %s", 556 ar->mNoiseSuppression.mNSDescriptor.name); 557 flags = ar->mNoiseSuppression.mNSDescriptor.flags; 558 break; 559 default: 560 break; 561 } 562 } 563 if ((flags & EFFECT_FLAG_HW_ACC_TUNNEL) == 0) { 564 allowedModes &= ~ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS; 565 break; 566 } 567 } 568 } 569 #if LOG_NDEBUG == 0 570 bool blacklistResult = ( 571 (allowedModes & 572 (ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS)) != 0); 573 bool whitelistResult = true; 574 static const unsigned whitelist[] = { 575 MPH_BUFFERQUEUE, 576 MPH_DYNAMICINTERFACEMANAGEMENT, 577 MPH_OBJECT, 578 MPH_RECORD, 579 MPH_ANDROIDCONFIGURATION, 580 MPH_ANDROIDSIMPLEBUFFERQUEUE, 581 }; 582 for (unsigned mph = MPH_MIN; mph < MPH_MAX; ++mph) { 583 for (unsigned i = 0; i < sizeof(whitelist)/sizeof(whitelist[0]); ++i) { 584 if (mph == whitelist[i]) { 585 goto compatible; 586 } 587 } 588 if (IsInterfaceInitialized(&ar->mObject, mph)) { 589 whitelistResult = false; 590 break; 591 } 592 compatible: ; 593 } 594 if (whitelistResult != blacklistResult) { 595 SL_LOGW("whitelistResult != blacklistResult"); 596 } 597 #endif 598 if (ar->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY) { 599 if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY) == 0) { 600 ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS; 601 } 602 } 603 if (ar->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) { 604 if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) == 0) { 605 ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE; 606 } 607 } 608 } 609 610 // Called from android_audioRecorder_realize for a PCM buffer queue recorder after creating the 611 // AudioRecord to adjust performance mode based on actual input flags 612 static void checkAndSetPerformanceModePost(CAudioRecorder* ar) 613 { 614 audio_input_flags_t flags = ar->mAudioRecord->getFlags(); 615 switch (ar->mPerformanceMode) { 616 case ANDROID_PERFORMANCE_MODE_LATENCY: 617 if ((flags & (AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW)) == 618 (AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW)) { 619 break; 620 } 621 ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS; 622 FALLTHROUGH_INTENDED; 623 case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS: 624 if ((flags & AUDIO_INPUT_FLAG_FAST) == 0) { 625 ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE; 626 } 627 break; 628 case ANDROID_PERFORMANCE_MODE_NONE: 629 default: 630 break; 631 } 632 } 633 //----------------------------------------------------------------------------- 634 SLresult android_audioRecorder_realize(CAudioRecorder* ar, SLboolean async) { 635 SL_LOGV("android_audioRecorder_realize(%p) entering", ar); 636 637 SLresult result = SL_RESULT_SUCCESS; 638 639 // already checked in created and checkSourceSink 640 assert(ar->mDataSink.mLocator.mLocatorType == SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE); 641 642 const SLDataFormat_PCM *df_pcm = &ar->mDataSink.mFormat.mPCM; 643 644 // the following platform-independent fields have been initialized in CreateAudioRecorder() 645 // ar->mNumChannels 646 // ar->mSampleRateMilliHz 647 648 uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec); 649 650 checkAndSetPerformanceModePre(ar); 651 652 audio_input_flags_t policy; 653 switch (ar->mPerformanceMode) { 654 case ANDROID_PERFORMANCE_MODE_NONE: 655 case ANDROID_PERFORMANCE_MODE_POWER_SAVING: 656 policy = AUDIO_INPUT_FLAG_NONE; 657 break; 658 case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS: 659 policy = AUDIO_INPUT_FLAG_FAST; 660 break; 661 case ANDROID_PERFORMANCE_MODE_LATENCY: 662 default: 663 policy = (audio_input_flags_t)(AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW); 664 break; 665 } 666 667 SL_LOGV("Audio Record format: %dch(0x%x), %dbit, %dKHz", 668 df_pcm->numChannels, 669 df_pcm->channelMask, 670 df_pcm->bitsPerSample, 671 df_pcm->samplesPerSec / 1000000); 672 673 // note that df_pcm->channelMask has already been validated during object creation. 674 audio_channel_mask_t channelMask = sles_to_audio_input_channel_mask(df_pcm->channelMask); 675 676 // To maintain backward compatibility with previous releases, ignore 677 // channel masks that are not indexed. 678 if (channelMask == AUDIO_CHANNEL_INVALID 679 || audio_channel_mask_get_representation(channelMask) 680 == AUDIO_CHANNEL_REPRESENTATION_POSITION) { 681 channelMask = audio_channel_in_mask_from_count(df_pcm->numChannels); 682 SL_LOGI("Emulating old channel mask behavior " 683 "(ignoring positional mask %#x, using default mask %#x based on " 684 "channel count of %d)", df_pcm->channelMask, channelMask, 685 df_pcm->numChannels); 686 } 687 SL_LOGV("SLES channel mask %#x converted to Android mask %#x", df_pcm->channelMask, 688 channelMask); 689 690 // initialize platform-specific CAudioRecorder fields 691 ar->mAudioRecord = new android::AudioRecord( 692 ar->mRecordSource, // source 693 sampleRate, // sample rate in Hertz 694 sles_to_android_sampleFormat(df_pcm), // format 695 channelMask, // channel mask 696 android::String16(), // app ops 697 0, // frameCount 698 audioRecorder_callback,// callback_t 699 (void*)ar, // user, callback data, here the AudioRecorder 700 0, // notificationFrames 701 AUDIO_SESSION_ALLOCATE, 702 android::AudioRecord::TRANSFER_CALLBACK, 703 // transfer type 704 policy); // audio_input_flags_t 705 706 android::status_t status = ar->mAudioRecord->initCheck(); 707 if (android::NO_ERROR != status) { 708 SL_LOGE("android_audioRecorder_realize(%p) error creating AudioRecord object; status %d", 709 ar, status); 710 // FIXME should return a more specific result depending on status 711 result = SL_RESULT_CONTENT_UNSUPPORTED; 712 ar->mAudioRecord.clear(); 713 return result; 714 } 715 716 // update performance mode according to actual flags granted to AudioRecord 717 checkAndSetPerformanceModePost(ar); 718 719 // If there is a JavaAudioRoutingProxy associated with this recorder, hook it up... 720 JNIEnv* j_env = NULL; 721 jclass clsAudioRecord = NULL; 722 jmethodID midRoutingProxy_connect = NULL; 723 if (ar->mAndroidConfiguration.mRoutingProxy != NULL && 724 (j_env = android::AndroidRuntime::getJNIEnv()) != NULL && 725 (clsAudioRecord = j_env->FindClass("android/media/AudioRecord")) != NULL && 726 (midRoutingProxy_connect = 727 j_env->GetMethodID(clsAudioRecord, "deferred_connect", "(J)V")) != NULL) { 728 j_env->ExceptionClear(); 729 j_env->CallVoidMethod(ar->mAndroidConfiguration.mRoutingProxy, 730 midRoutingProxy_connect, 731 ar->mAudioRecord.get()); 732 if (j_env->ExceptionCheck()) { 733 SL_LOGE("Java exception releasing recorder routing object."); 734 result = SL_RESULT_INTERNAL_ERROR; 735 ar->mAudioRecord.clear(); 736 return result; 737 } 738 } 739 740 if (ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY) { 741 audio_session_t sessionId = ar->mAudioRecord->getSessionId(); 742 // initialize AEC 743 effect_descriptor_t *descriptor = &ar->mAcousticEchoCancellation.mAECDescriptor; 744 if (memcmp(SL_IID_ANDROIDACOUSTICECHOCANCELLATION, &descriptor->type, 745 sizeof(effect_uuid_t)) == 0) { 746 if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) || 747 (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { 748 SL_LOGV("Need to initialize AEC for AudioRecorder=%p", ar); 749 android_aec_init(sessionId, &ar->mAcousticEchoCancellation); 750 } 751 } 752 753 // initialize AGC 754 descriptor = &ar->mAutomaticGainControl.mAGCDescriptor; 755 if (memcmp(SL_IID_ANDROIDAUTOMATICGAINCONTROL, &descriptor->type, 756 sizeof(effect_uuid_t)) == 0) { 757 if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) || 758 (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { 759 SL_LOGV("Need to initialize AGC for AudioRecorder=%p", ar); 760 android_agc_init(sessionId, &ar->mAutomaticGainControl); 761 } 762 } 763 764 // initialize NS 765 descriptor = &ar->mNoiseSuppression.mNSDescriptor; 766 if (memcmp(SL_IID_ANDROIDNOISESUPPRESSION, &descriptor->type, 767 sizeof(effect_uuid_t)) == 0) { 768 if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) || 769 (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { 770 SL_LOGV("Need to initialize NS for AudioRecorder=%p", ar); 771 android_ns_init(sessionId, &ar->mNoiseSuppression); 772 } 773 } 774 } 775 776 return result; 777 } 778 779 780 //----------------------------------------------------------------------------- 781 /** 782 * Called with a lock on AudioRecorder, and blocks until safe to destroy 783 */ 784 void android_audioRecorder_preDestroy(CAudioRecorder* ar) { 785 object_unlock_exclusive(&ar->mObject); 786 if (ar->mCallbackProtector != 0) { 787 ar->mCallbackProtector->requestCbExitAndWait(); 788 } 789 object_lock_exclusive(&ar->mObject); 790 } 791 792 793 //----------------------------------------------------------------------------- 794 void android_audioRecorder_destroy(CAudioRecorder* ar) { 795 SL_LOGV("android_audioRecorder_destroy(%p) entering", ar); 796 797 if (ar->mAudioRecord != 0) { 798 ar->mAudioRecord->stop(); 799 ar->mAudioRecord.clear(); 800 } 801 // explicit destructor 802 ar->mAudioRecord.~sp(); 803 ar->mCallbackProtector.~sp(); 804 } 805 806 807 //----------------------------------------------------------------------------- 808 void android_audioRecorder_setRecordState(CAudioRecorder* ar, SLuint32 state) { 809 SL_LOGV("android_audioRecorder_setRecordState(%p, %u) entering", ar, state); 810 811 if (ar->mAudioRecord == 0) { 812 return; 813 } 814 815 switch (state) { 816 case SL_RECORDSTATE_STOPPED: 817 ar->mAudioRecord->stop(); 818 break; 819 case SL_RECORDSTATE_PAUSED: 820 // Note that pausing is treated like stop as this implementation only records to a buffer 821 // queue, so there is no notion of destination being "opened" or "closed" (See description 822 // of SL_RECORDSTATE in specification) 823 ar->mAudioRecord->stop(); 824 break; 825 case SL_RECORDSTATE_RECORDING: 826 ar->mAudioRecord->start(); 827 break; 828 default: 829 break; 830 } 831 832 } 833 834 835 //----------------------------------------------------------------------------- 836 void android_audioRecorder_useRecordEventMask(CAudioRecorder *ar) { 837 IRecord *pRecordItf = &ar->mRecord; 838 SLuint32 eventFlags = pRecordItf->mCallbackEventsMask; 839 840 if (ar->mAudioRecord == 0) { 841 return; 842 } 843 844 if ((eventFlags & SL_RECORDEVENT_HEADATMARKER) && (pRecordItf->mMarkerPosition != 0)) { 845 ar->mAudioRecord->setMarkerPosition((uint32_t)((((int64_t)pRecordItf->mMarkerPosition 846 * sles_to_android_sampleRate(ar->mSampleRateMilliHz)))/1000)); 847 } else { 848 // clear marker 849 ar->mAudioRecord->setMarkerPosition(0); 850 } 851 852 if (eventFlags & SL_RECORDEVENT_HEADATNEWPOS) { 853 SL_LOGV("pos update period %d", pRecordItf->mPositionUpdatePeriod); 854 ar->mAudioRecord->setPositionUpdatePeriod( 855 (uint32_t)((((int64_t)pRecordItf->mPositionUpdatePeriod 856 * sles_to_android_sampleRate(ar->mSampleRateMilliHz)))/1000)); 857 } else { 858 // clear periodic update 859 ar->mAudioRecord->setPositionUpdatePeriod(0); 860 } 861 862 if (eventFlags & SL_RECORDEVENT_HEADATLIMIT) { 863 // FIXME support SL_RECORDEVENT_HEADATLIMIT 864 SL_LOGD("[ FIXME: IRecord_SetCallbackEventsMask(SL_RECORDEVENT_HEADATLIMIT) on an " 865 "SL_OBJECTID_AUDIORECORDER to be implemented ]"); 866 } 867 868 if (eventFlags & SL_RECORDEVENT_HEADMOVING) { 869 // FIXME support SL_RECORDEVENT_HEADMOVING 870 SL_LOGD("[ FIXME: IRecord_SetCallbackEventsMask(SL_RECORDEVENT_HEADMOVING) on an " 871 "SL_OBJECTID_AUDIORECORDER to be implemented ]"); 872 } 873 874 if (eventFlags & SL_RECORDEVENT_BUFFER_FULL) { 875 // nothing to do for SL_RECORDEVENT_BUFFER_FULL since this will not be encountered on 876 // recording to buffer queues 877 } 878 879 if (eventFlags & SL_RECORDEVENT_HEADSTALLED) { 880 // nothing to do for SL_RECORDEVENT_HEADSTALLED, callback event will be checked against mask 881 // when AudioRecord::EVENT_OVERRUN is encountered 882 883 } 884 885 } 886 887 888 //----------------------------------------------------------------------------- 889 void android_audioRecorder_getPosition(CAudioRecorder *ar, SLmillisecond *pPosMsec) { 890 if ((NULL == ar) || (ar->mAudioRecord == 0)) { 891 *pPosMsec = 0; 892 } else { 893 uint32_t positionInFrames; 894 ar->mAudioRecord->getPosition(&positionInFrames); 895 if (ar->mSampleRateMilliHz == UNKNOWN_SAMPLERATE) { 896 *pPosMsec = 0; 897 } else { 898 *pPosMsec = ((int64_t)positionInFrames * 1000) / 899 sles_to_android_sampleRate(ar->mSampleRateMilliHz); 900 } 901 } 902 } 903