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