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