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 case SL_DATAFORMAT_PCM: { 249 const SLDataFormat_PCM *df_pcm = (const SLDataFormat_PCM *) pAudioSnk->pFormat; 250 // checkDataFormat already checked sample rate, channels, and mask 251 ar->mNumChannels = df_pcm->numChannels; 252 253 if (df_pcm->endianness != ar->mObject.mEngine->mEngine.mNativeEndianness) { 254 SL_LOGE("Cannot create audio recorder: unsupported byte order %u", 255 df_pcm->endianness); 256 return SL_RESULT_CONTENT_UNSUPPORTED; 257 } 258 259 ar->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES 260 SL_LOGV("AudioRecorder requested sample rate = %u mHz, %u channel(s)", 261 ar->mSampleRateMilliHz, ar->mNumChannels); 262 263 // we don't support container size != sample depth 264 if (df_pcm->containerSize != df_pcm->bitsPerSample) { 265 SL_LOGE("Cannot create audio recorder: unsupported container size %u bits for " 266 "sample depth %u bits", 267 df_pcm->containerSize, (SLuint32)df_pcm->bitsPerSample); 268 return SL_RESULT_CONTENT_UNSUPPORTED; 269 } 270 271 } break; 272 default: 273 SL_LOGE(ERROR_RECORDER_SINK_FORMAT_MUST_BE_PCM); 274 return SL_RESULT_PARAMETER_INVALID; 275 } // switch (sourceFormatType) 276 } break; // case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE 277 default: 278 SL_LOGE(ERROR_RECORDER_SINK_MUST_BE_ANDROIDSIMPLEBUFFERQUEUE); 279 return SL_RESULT_PARAMETER_INVALID; 280 } // switch (sourceLocatorType) 281 282 // Source check: 283 // only input device sources are supported 284 // check it's an IO device 285 if (SL_DATALOCATOR_IODEVICE != *(SLuint32 *)pAudioSrc->pLocator) { 286 SL_LOGE(ERROR_RECORDER_SOURCE_MUST_BE_IODEVICE); 287 return SL_RESULT_PARAMETER_INVALID; 288 } else { 289 290 // check it's an input device 291 SLDataLocator_IODevice *dl_iod = (SLDataLocator_IODevice *) pAudioSrc->pLocator; 292 if (SL_IODEVICE_AUDIOINPUT != dl_iod->deviceType) { 293 SL_LOGE(ERROR_RECORDER_IODEVICE_MUST_BE_AUDIOINPUT); 294 return SL_RESULT_PARAMETER_INVALID; 295 } 296 297 // check it's the default input device, others aren't supported here 298 if (SL_DEFAULTDEVICEID_AUDIOINPUT != dl_iod->deviceID) { 299 SL_LOGE(ERROR_RECORDER_INPUT_ID_MUST_BE_DEFAULT); 300 return SL_RESULT_PARAMETER_INVALID; 301 } 302 } 303 304 return SL_RESULT_SUCCESS; 305 } 306 //----------------------------------------------------------------------------- 307 static void audioRecorder_callback(int event, void* user, void *info) { 308 //SL_LOGV("audioRecorder_callback(%d, %p, %p) entering", event, user, info); 309 310 CAudioRecorder *ar = (CAudioRecorder *)user; 311 312 if (!android::CallbackProtector::enterCbIfOk(ar->mCallbackProtector)) { 313 // it is not safe to enter the callback (the track is about to go away) 314 return; 315 } 316 317 void * callbackPContext = NULL; 318 319 switch (event) { 320 case android::AudioRecord::EVENT_MORE_DATA: { 321 slBufferQueueCallback callback = NULL; 322 android::AudioRecord::Buffer* pBuff = (android::AudioRecord::Buffer*)info; 323 324 // push data to the buffer queue 325 interface_lock_exclusive(&ar->mBufferQueue); 326 327 if (ar->mBufferQueue.mState.count != 0) { 328 assert(ar->mBufferQueue.mFront != ar->mBufferQueue.mRear); 329 330 BufferHeader *oldFront = ar->mBufferQueue.mFront; 331 BufferHeader *newFront = &oldFront[1]; 332 333 size_t availSink = oldFront->mSize - ar->mBufferQueue.mSizeConsumed; 334 size_t availSource = pBuff->size; 335 size_t bytesToCopy = availSink < availSource ? availSink : availSource; 336 void *pDest = (char *)oldFront->mBuffer + ar->mBufferQueue.mSizeConsumed; 337 memcpy(pDest, pBuff->raw, bytesToCopy); 338 339 if (bytesToCopy < availSink) { 340 // can't consume the whole or rest of the buffer in one shot 341 ar->mBufferQueue.mSizeConsumed += availSource; 342 // pBuff->size is already equal to bytesToCopy in this case 343 } else { 344 // finish pushing the buffer or push the buffer in one shot 345 pBuff->size = bytesToCopy; 346 ar->mBufferQueue.mSizeConsumed = 0; 347 if (newFront == &ar->mBufferQueue.mArray[ar->mBufferQueue.mNumBuffers + 1]) { 348 newFront = ar->mBufferQueue.mArray; 349 } 350 ar->mBufferQueue.mFront = newFront; 351 352 ar->mBufferQueue.mState.count--; 353 ar->mBufferQueue.mState.playIndex++; 354 355 // data has been copied to the buffer, and the buffer queue state has been updated 356 // we will notify the client if applicable 357 callback = ar->mBufferQueue.mCallback; 358 // save callback data 359 callbackPContext = ar->mBufferQueue.mContext; 360 } 361 } else { // empty queue 362 // no destination to push the data 363 pBuff->size = 0; 364 } 365 366 interface_unlock_exclusive(&ar->mBufferQueue); 367 368 // notify client 369 if (NULL != callback) { 370 (*callback)(&ar->mBufferQueue.mItf, callbackPContext); 371 } 372 } 373 break; 374 375 case android::AudioRecord::EVENT_OVERRUN: 376 audioRecorder_handleOverrun_lockRecord(ar); 377 break; 378 379 case android::AudioRecord::EVENT_MARKER: 380 audioRecorder_handleMarker_lockRecord(ar); 381 break; 382 383 case android::AudioRecord::EVENT_NEW_POS: 384 audioRecorder_handleNewPos_lockRecord(ar); 385 break; 386 387 case android::AudioRecord::EVENT_NEW_IAUDIORECORD: 388 // ignore for now 389 break; 390 391 default: 392 SL_LOGE("Encountered unknown AudioRecord event %d for CAudioRecord %p", event, ar); 393 break; 394 } 395 396 ar->mCallbackProtector->exitCb(); 397 } 398 399 400 //----------------------------------------------------------------------------- 401 SLresult android_audioRecorder_create(CAudioRecorder* ar) { 402 SL_LOGV("android_audioRecorder_create(%p) entering", ar); 403 404 const SLDataSource *pAudioSrc = &ar->mDataSource.u.mSource; 405 const SLDataSink *pAudioSnk = &ar->mDataSink.u.mSink; 406 SLresult result = SL_RESULT_SUCCESS; 407 408 const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator; 409 const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator; 410 411 // the following platform-independent fields have been initialized in CreateAudioRecorder() 412 // ar->mNumChannels 413 // ar->mSampleRateMilliHz 414 415 if ((SL_DATALOCATOR_IODEVICE == sourceLocatorType) && 416 (SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE == sinkLocatorType)) { 417 // microphone to simple buffer queue 418 ar->mAndroidObjType = AUDIORECORDER_FROM_MIC_TO_PCM_BUFFERQUEUE; 419 ar->mAudioRecord.clear(); 420 ar->mCallbackProtector = new android::CallbackProtector(); 421 ar->mRecordSource = AUDIO_SOURCE_DEFAULT; 422 ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_DEFAULT; 423 } else { 424 result = SL_RESULT_CONTENT_UNSUPPORTED; 425 } 426 427 return result; 428 } 429 430 431 //----------------------------------------------------------------------------- 432 SLresult android_audioRecorder_setConfig(CAudioRecorder* ar, const SLchar *configKey, 433 const void *pConfigValue, SLuint32 valueSize) { 434 435 SLresult result; 436 437 assert(NULL != ar && NULL != configKey && NULL != pConfigValue); 438 if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_RECORDING_PRESET) == 0) { 439 440 // recording preset 441 if (KEY_RECORDING_PRESET_PARAMSIZE > valueSize) { 442 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 443 result = SL_RESULT_BUFFER_INSUFFICIENT; 444 } else { 445 result = audioRecorder_setPreset(ar, *(SLuint32*)pConfigValue); 446 } 447 448 } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) { 449 450 // performance mode 451 if (KEY_PERFORMANCE_MODE_PARAMSIZE > valueSize) { 452 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 453 result = SL_RESULT_BUFFER_INSUFFICIENT; 454 } else { 455 result = audioRecorder_setPerformanceMode(ar, *(SLuint32*)pConfigValue); 456 } 457 } else { 458 SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY); 459 result = SL_RESULT_PARAMETER_INVALID; 460 } 461 462 return result; 463 } 464 465 466 //----------------------------------------------------------------------------- 467 SLresult android_audioRecorder_getConfig(CAudioRecorder* ar, const SLchar *configKey, 468 SLuint32* pValueSize, void *pConfigValue) { 469 470 SLresult result; 471 472 assert(NULL != ar && NULL != configKey && NULL != pValueSize); 473 if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_RECORDING_PRESET) == 0) { 474 475 // recording preset 476 if (NULL == pConfigValue) { 477 result = SL_RESULT_SUCCESS; 478 } else if (KEY_RECORDING_PRESET_PARAMSIZE > *pValueSize) { 479 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 480 result = SL_RESULT_BUFFER_INSUFFICIENT; 481 } else { 482 result = audioRecorder_getPreset(ar, (SLuint32*)pConfigValue); 483 } 484 *pValueSize = KEY_RECORDING_PRESET_PARAMSIZE; 485 486 } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) { 487 488 // performance mode 489 if (NULL == pConfigValue) { 490 result = SL_RESULT_SUCCESS; 491 } else if (KEY_PERFORMANCE_MODE_PARAMSIZE > *pValueSize) { 492 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 493 result = SL_RESULT_BUFFER_INSUFFICIENT; 494 } else { 495 result = audioRecorder_getPerformanceMode(ar, (SLuint32*)pConfigValue); 496 } 497 *pValueSize = KEY_PERFORMANCE_MODE_PARAMSIZE; 498 499 } else { 500 SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY); 501 result = SL_RESULT_PARAMETER_INVALID; 502 } 503 504 return result; 505 } 506 507 // Called from android_audioRecorder_realize for a PCM buffer queue recorder before creating the 508 // AudioRecord to determine which performance modes are allowed based on effect interfaces present 509 static void checkAndSetPerformanceModePre(CAudioRecorder* ar) 510 { 511 SLuint32 allowedModes = ANDROID_PERFORMANCE_MODE_ALL; 512 assert(ar->mAndroidObjType == AUDIORECORDER_FROM_MIC_TO_PCM_BUFFERQUEUE); 513 514 // no need to check the buffer queue size, application side 515 // double-buffering (and more) is not a requirement for using fast tracks 516 517 // Check a blacklist of interfaces that are incompatible with fast tracks. 518 // The alternative, to check a whitelist of compatible interfaces, is 519 // more maintainable but is too slow. As a compromise, in a debug build 520 // we use both methods and warn if they produce different results. 521 // In release builds, we only use the blacklist method. 522 // If a blacklisted interface is added after realization using 523 // DynamicInterfaceManagement::AddInterface, 524 // then this won't be detected but the interface will be ineffective. 525 static const unsigned blacklist[] = { 526 MPH_ANDROIDACOUSTICECHOCANCELLATION, 527 MPH_ANDROIDAUTOMATICGAINCONTROL, 528 MPH_ANDROIDNOISESUPPRESSION, 529 MPH_ANDROIDEFFECT, 530 // FIXME The problem with a blacklist is remembering to add new interfaces here 531 }; 532 533 for (unsigned i = 0; i < sizeof(blacklist)/sizeof(blacklist[0]); ++i) { 534 if (IsInterfaceInitialized(&ar->mObject, blacklist[i])) { 535 uint32_t flags = 0; 536 537 allowedModes &= ~ANDROID_PERFORMANCE_MODE_LATENCY; 538 539 // if generic effect interface is used we don't know which effect will be used and 540 // disable all low latency performance modes 541 if (blacklist[i] != MPH_ANDROIDEFFECT) { 542 switch (blacklist[i]) { 543 case MPH_ANDROIDACOUSTICECHOCANCELLATION: 544 SL_LOGV("checkAndSetPerformanceModePre found AEC name %s", 545 ar->mAcousticEchoCancellation.mAECDescriptor.name); 546 flags = ar->mAcousticEchoCancellation.mAECDescriptor.flags; 547 break; 548 case MPH_ANDROIDAUTOMATICGAINCONTROL: 549 SL_LOGV("checkAndSetPerformanceModePre found AGC name %s", 550 ar->mAutomaticGainControl.mAGCDescriptor.name); 551 flags = ar->mAutomaticGainControl.mAGCDescriptor.flags; 552 break; 553 case MPH_ANDROIDNOISESUPPRESSION: 554 SL_LOGV("checkAndSetPerformanceModePre found NS name %s", 555 ar->mNoiseSuppression.mNSDescriptor.name); 556 flags = ar->mNoiseSuppression.mNSDescriptor.flags; 557 break; 558 default: 559 break; 560 } 561 } 562 if ((flags & EFFECT_FLAG_HW_ACC_TUNNEL) == 0) { 563 allowedModes &= ~ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS; 564 break; 565 } 566 } 567 } 568 #if LOG_NDEBUG == 0 569 bool blacklistResult = ( 570 (allowedModes & 571 (ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS)) != 0); 572 bool whitelistResult = true; 573 static const unsigned whitelist[] = { 574 MPH_BUFFERQUEUE, 575 MPH_DYNAMICINTERFACEMANAGEMENT, 576 MPH_OBJECT, 577 MPH_RECORD, 578 MPH_ANDROIDCONFIGURATION, 579 MPH_ANDROIDSIMPLEBUFFERQUEUE, 580 }; 581 for (unsigned mph = MPH_MIN; mph < MPH_MAX; ++mph) { 582 for (unsigned i = 0; i < sizeof(whitelist)/sizeof(whitelist[0]); ++i) { 583 if (mph == whitelist[i]) { 584 goto compatible; 585 } 586 } 587 if (IsInterfaceInitialized(&ar->mObject, mph)) { 588 whitelistResult = false; 589 break; 590 } 591 compatible: ; 592 } 593 if (whitelistResult != blacklistResult) { 594 SL_LOGW("whitelistResult != blacklistResult"); 595 } 596 #endif 597 if (ar->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY) { 598 if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY) == 0) { 599 ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS; 600 } 601 } 602 if (ar->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) { 603 if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) == 0) { 604 ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE; 605 } 606 } 607 } 608 609 // Called from android_audioRecorder_realize for a PCM buffer queue recorder after creating the 610 // AudioRecord to adjust performance mode based on actual input flags 611 static void checkAndSetPerformanceModePost(CAudioRecorder* ar) 612 { 613 audio_input_flags_t flags = ar->mAudioRecord->getFlags(); 614 switch (ar->mPerformanceMode) { 615 case ANDROID_PERFORMANCE_MODE_LATENCY: 616 if ((flags & (AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW)) == 617 (AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW)) { 618 break; 619 } 620 ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS; 621 /* FALL THROUGH */ 622 case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS: 623 if ((flags & AUDIO_INPUT_FLAG_FAST) == 0) { 624 ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE; 625 } 626 break; 627 case ANDROID_PERFORMANCE_MODE_NONE: 628 default: 629 break; 630 } 631 } 632 //----------------------------------------------------------------------------- 633 SLresult android_audioRecorder_realize(CAudioRecorder* ar, SLboolean async) { 634 SL_LOGV("android_audioRecorder_realize(%p) entering", ar); 635 636 SLresult result = SL_RESULT_SUCCESS; 637 638 // already checked in created and checkSourceSink 639 assert(ar->mDataSink.mLocator.mLocatorType == SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE); 640 641 const SLDataFormat_PCM *df_pcm = &ar->mDataSink.mFormat.mPCM; 642 643 // the following platform-independent fields have been initialized in CreateAudioRecorder() 644 // ar->mNumChannels 645 // ar->mSampleRateMilliHz 646 647 uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec); 648 649 checkAndSetPerformanceModePre(ar); 650 651 audio_input_flags_t policy; 652 switch (ar->mPerformanceMode) { 653 case ANDROID_PERFORMANCE_MODE_NONE: 654 case ANDROID_PERFORMANCE_MODE_POWER_SAVING: 655 policy = AUDIO_INPUT_FLAG_NONE; 656 break; 657 case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS: 658 policy = AUDIO_INPUT_FLAG_FAST; 659 break; 660 case ANDROID_PERFORMANCE_MODE_LATENCY: 661 default: 662 policy = (audio_input_flags_t)(AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW); 663 break; 664 } 665 666 SL_LOGV("Audio Record format: %dch(0x%x), %dbit, %dKHz", 667 df_pcm->numChannels, 668 df_pcm->channelMask, 669 df_pcm->bitsPerSample, 670 df_pcm->samplesPerSec / 1000000); 671 672 // note that df_pcm->channelMask has already been validated during object creation. 673 audio_channel_mask_t channelMask = sles_to_audio_input_channel_mask(df_pcm->channelMask); 674 675 // To maintain backward compatibility with previous releases, ignore 676 // channel masks that are not indexed. 677 if (channelMask == AUDIO_CHANNEL_INVALID 678 || audio_channel_mask_get_representation(channelMask) 679 == AUDIO_CHANNEL_REPRESENTATION_POSITION) { 680 channelMask = audio_channel_in_mask_from_count(df_pcm->numChannels); 681 SL_LOGI("Emulating old channel mask behavior " 682 "(ignoring positional mask %#x, using default mask %#x based on " 683 "channel count of %d)", df_pcm->channelMask, channelMask, 684 df_pcm->numChannels); 685 } 686 SL_LOGV("SLES channel mask %#x converted to Android mask %#x", df_pcm->channelMask, 687 channelMask); 688 689 // initialize platform-specific CAudioRecorder fields 690 ar->mAudioRecord = new android::AudioRecord( 691 ar->mRecordSource, // source 692 sampleRate, // sample rate in Hertz 693 sles_to_android_sampleFormat(df_pcm), // format 694 channelMask, // channel mask 695 android::String16(), // app ops 696 0, // frameCount 697 audioRecorder_callback,// callback_t 698 (void*)ar, // user, callback data, here the AudioRecorder 699 0, // notificationFrames 700 AUDIO_SESSION_ALLOCATE, 701 android::AudioRecord::TRANSFER_CALLBACK, 702 // transfer type 703 policy); // audio_input_flags_t 704 705 android::status_t status = ar->mAudioRecord->initCheck(); 706 if (android::NO_ERROR != status) { 707 SL_LOGE("android_audioRecorder_realize(%p) error creating AudioRecord object; status %d", 708 ar, status); 709 // FIXME should return a more specific result depending on status 710 result = SL_RESULT_CONTENT_UNSUPPORTED; 711 ar->mAudioRecord.clear(); 712 return result; 713 } 714 715 // update performance mode according to actual flags granted to AudioRecord 716 checkAndSetPerformanceModePost(ar); 717 718 // If there is a JavaAudioRoutingProxy associated with this recorder, hook it up... 719 JNIEnv* j_env = NULL; 720 jclass clsAudioRecord = NULL; 721 jmethodID midRoutingProxy_connect = NULL; 722 if (ar->mAndroidConfiguration.mRoutingProxy != NULL && 723 (j_env = android::AndroidRuntime::getJNIEnv()) != NULL && 724 (clsAudioRecord = j_env->FindClass("android/media/AudioRecord")) != NULL && 725 (midRoutingProxy_connect = 726 j_env->GetMethodID(clsAudioRecord, "deferred_connect", "(J)V")) != NULL) { 727 j_env->ExceptionClear(); 728 j_env->CallVoidMethod(ar->mAndroidConfiguration.mRoutingProxy, 729 midRoutingProxy_connect, 730 ar->mAudioRecord.get()); 731 if (j_env->ExceptionCheck()) { 732 SL_LOGE("Java exception releasing recorder routing object."); 733 result = SL_RESULT_INTERNAL_ERROR; 734 ar->mAudioRecord.clear(); 735 return result; 736 } 737 } 738 739 if (ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY) { 740 audio_session_t sessionId = ar->mAudioRecord->getSessionId(); 741 // initialize AEC 742 effect_descriptor_t *descriptor = &ar->mAcousticEchoCancellation.mAECDescriptor; 743 if (memcmp(SL_IID_ANDROIDACOUSTICECHOCANCELLATION, &descriptor->type, 744 sizeof(effect_uuid_t)) == 0) { 745 if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) || 746 (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { 747 SL_LOGV("Need to initialize AEC for AudioRecorder=%p", ar); 748 android_aec_init(sessionId, &ar->mAcousticEchoCancellation); 749 } 750 } 751 752 // initialize AGC 753 descriptor = &ar->mAutomaticGainControl.mAGCDescriptor; 754 if (memcmp(SL_IID_ANDROIDAUTOMATICGAINCONTROL, &descriptor->type, 755 sizeof(effect_uuid_t)) == 0) { 756 if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) || 757 (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { 758 SL_LOGV("Need to initialize AGC for AudioRecorder=%p", ar); 759 android_agc_init(sessionId, &ar->mAutomaticGainControl); 760 } 761 } 762 763 // initialize NS 764 descriptor = &ar->mNoiseSuppression.mNSDescriptor; 765 if (memcmp(SL_IID_ANDROIDNOISESUPPRESSION, &descriptor->type, 766 sizeof(effect_uuid_t)) == 0) { 767 if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) || 768 (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { 769 SL_LOGV("Need to initialize NS for AudioRecorder=%p", ar); 770 android_ns_init(sessionId, &ar->mNoiseSuppression); 771 } 772 } 773 } 774 775 return result; 776 } 777 778 779 //----------------------------------------------------------------------------- 780 /** 781 * Called with a lock on AudioRecorder, and blocks until safe to destroy 782 */ 783 void android_audioRecorder_preDestroy(CAudioRecorder* ar) { 784 object_unlock_exclusive(&ar->mObject); 785 if (ar->mCallbackProtector != 0) { 786 ar->mCallbackProtector->requestCbExitAndWait(); 787 } 788 object_lock_exclusive(&ar->mObject); 789 } 790 791 792 //----------------------------------------------------------------------------- 793 void android_audioRecorder_destroy(CAudioRecorder* ar) { 794 SL_LOGV("android_audioRecorder_destroy(%p) entering", ar); 795 796 if (ar->mAudioRecord != 0) { 797 ar->mAudioRecord->stop(); 798 ar->mAudioRecord.clear(); 799 } 800 // explicit destructor 801 ar->mAudioRecord.~sp(); 802 ar->mCallbackProtector.~sp(); 803 } 804 805 806 //----------------------------------------------------------------------------- 807 void android_audioRecorder_setRecordState(CAudioRecorder* ar, SLuint32 state) { 808 SL_LOGV("android_audioRecorder_setRecordState(%p, %u) entering", ar, state); 809 810 if (ar->mAudioRecord == 0) { 811 return; 812 } 813 814 switch (state) { 815 case SL_RECORDSTATE_STOPPED: 816 ar->mAudioRecord->stop(); 817 break; 818 case SL_RECORDSTATE_PAUSED: 819 // Note that pausing is treated like stop as this implementation only records to a buffer 820 // queue, so there is no notion of destination being "opened" or "closed" (See description 821 // of SL_RECORDSTATE in specification) 822 ar->mAudioRecord->stop(); 823 break; 824 case SL_RECORDSTATE_RECORDING: 825 ar->mAudioRecord->start(); 826 break; 827 default: 828 break; 829 } 830 831 } 832 833 834 //----------------------------------------------------------------------------- 835 void android_audioRecorder_useRecordEventMask(CAudioRecorder *ar) { 836 IRecord *pRecordItf = &ar->mRecord; 837 SLuint32 eventFlags = pRecordItf->mCallbackEventsMask; 838 839 if (ar->mAudioRecord == 0) { 840 return; 841 } 842 843 if ((eventFlags & SL_RECORDEVENT_HEADATMARKER) && (pRecordItf->mMarkerPosition != 0)) { 844 ar->mAudioRecord->setMarkerPosition((uint32_t)((((int64_t)pRecordItf->mMarkerPosition 845 * sles_to_android_sampleRate(ar->mSampleRateMilliHz)))/1000)); 846 } else { 847 // clear marker 848 ar->mAudioRecord->setMarkerPosition(0); 849 } 850 851 if (eventFlags & SL_RECORDEVENT_HEADATNEWPOS) { 852 SL_LOGV("pos update period %d", pRecordItf->mPositionUpdatePeriod); 853 ar->mAudioRecord->setPositionUpdatePeriod( 854 (uint32_t)((((int64_t)pRecordItf->mPositionUpdatePeriod 855 * sles_to_android_sampleRate(ar->mSampleRateMilliHz)))/1000)); 856 } else { 857 // clear periodic update 858 ar->mAudioRecord->setPositionUpdatePeriod(0); 859 } 860 861 if (eventFlags & SL_RECORDEVENT_HEADATLIMIT) { 862 // FIXME support SL_RECORDEVENT_HEADATLIMIT 863 SL_LOGD("[ FIXME: IRecord_SetCallbackEventsMask(SL_RECORDEVENT_HEADATLIMIT) on an " 864 "SL_OBJECTID_AUDIORECORDER to be implemented ]"); 865 } 866 867 if (eventFlags & SL_RECORDEVENT_HEADMOVING) { 868 // FIXME support SL_RECORDEVENT_HEADMOVING 869 SL_LOGD("[ FIXME: IRecord_SetCallbackEventsMask(SL_RECORDEVENT_HEADMOVING) on an " 870 "SL_OBJECTID_AUDIORECORDER to be implemented ]"); 871 } 872 873 if (eventFlags & SL_RECORDEVENT_BUFFER_FULL) { 874 // nothing to do for SL_RECORDEVENT_BUFFER_FULL since this will not be encountered on 875 // recording to buffer queues 876 } 877 878 if (eventFlags & SL_RECORDEVENT_HEADSTALLED) { 879 // nothing to do for SL_RECORDEVENT_HEADSTALLED, callback event will be checked against mask 880 // when AudioRecord::EVENT_OVERRUN is encountered 881 882 } 883 884 } 885 886 887 //----------------------------------------------------------------------------- 888 void android_audioRecorder_getPosition(CAudioRecorder *ar, SLmillisecond *pPosMsec) { 889 if ((NULL == ar) || (ar->mAudioRecord == 0)) { 890 *pPosMsec = 0; 891 } else { 892 uint32_t positionInFrames; 893 ar->mAudioRecord->getPosition(&positionInFrames); 894 if (ar->mSampleRateMilliHz == UNKNOWN_SAMPLERATE) { 895 *pPosMsec = 0; 896 } else { 897 *pPosMsec = ((int64_t)positionInFrames * 1000) / 898 sles_to_android_sampleRate(ar->mSampleRateMilliHz); 899 } 900 } 901 } 902