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