• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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