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