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