录音机和录像机的输入通路

来源:互联网 发布:js 排序算法 编辑:程序博客网 时间:2024/04/28 14:20
ssize_t AudioALSAStreamIn::read(void *buffer, ssize_t bytes){    ssize_t ret_size = bytes;    int tryCount = 10;    if (mSuspendCount > 0 || ((mStreamAttributeTarget.input_source == AUDIO_SOURCE_FM_TUNER)         && (mStreamManager->isEchoRefUsing() == true)))    {        // here to sleep a buffer size latency and return.        memset(buffer, 0, bytes);        size_t wordSize = 0;        switch (mStreamAttributeTarget.audio_format)        {            case AUDIO_FORMAT_PCM_8_BIT:            {                wordSize = sizeof(int8_t);                break;            }            case AUDIO_FORMAT_PCM_16_BIT:            {                wordSize = sizeof(int16_t);                break;            }            case AUDIO_FORMAT_PCM_8_24_BIT:            case AUDIO_FORMAT_PCM_32_BIT:            {                wordSize = sizeof(int32_t);                break;            }            default:            {                wordSize = sizeof(int16_t);                break;            }        }        int sleepus = ((bytes * 1000) / ((mStreamAttributeTarget.sample_rate / 1000)                       * mStreamAttributeTarget.num_channels * wordSize));        usleep(sleepus);        return bytes;    }    tryCount = 10;    while(mLockCount && tryCount--) {        usleep(300);    }    status_t status = NO_ERROR;    if ((mUpdateOutputDevice == true) || (mUpdateInputDevice == true))    {        mUpdateOutputDevice = false;        {            AudioAutoTimeoutLock standbyLock(mStandbyLock);            if (mStandby == false)            {                status = close();            }        }        if (mUpdateInputDevice == true)        {            mUpdateInputDevice = false;            mStreamAttributeTarget.input_device = mNewInputDevice;        }    }    if (mStandby == true)    {        status = open();//打开输入设备    }    if (status != NO_ERROR)    {        ret_size = 0;    } else    {        ret_size = mCaptureHandler->read(buffer, bytes);//读取数据        WritePcmDumpData(buffer, bytes);    }    return ret_size;}

读取数据之前会创建handler对象,然后打开输入设备

status_t AudioALSAStreamIn::open(){    status_t status = NO_ERROR;    if (mStandby == true)    {        mCaptureHandler = mStreamManager->createCaptureHandler(&mStreamAttributeTarget);        mStandby = false;        status = mCaptureHandler->open();        OpenPCMDump();    }    return status;}

根据不同的场景(input_source和input_device)创建不同的handler

AudioALSACaptureHandlerBase *AudioALSAStreamManager::createCaptureHandler(    stream_attribute_t *stream_attribute_target){    // use primary stream out device    const audio_devices_t current_output_devices = (mStreamOutVector.size() > 0)                                                   ? mStreamOutVector[0]->getStreamAttribute()->output_devices                                                   : AUDIO_DEVICE_NONE;    // Init input stream attribute here    stream_attribute_target->audio_mode = mAudioMode;    stream_attribute_target->output_devices = current_output_devices;    stream_attribute_target->micmute = mMicMute;    // BesRecordInfo    stream_attribute_target->BesRecord_Info.besrecord_enable = false; // default set besrecord off    stream_attribute_target->BesRecord_Info.besrecord_bypass_dualmicprocess = mBypassDualMICProcessUL;    // create    AudioALSACaptureHandlerBase *pCaptureHandler = NULL;    {        if (stream_attribute_target->input_source == AUDIO_SOURCE_FM_TUNER)//FM广播        {            if (isEchoRefUsing() == true)            {                ALOGD("%s(), not support FM record in VoIP mode, return NULL", __FUNCTION__);                mLock.unlock();                return NULL;            }            pCaptureHandler = new AudioALSACaptureHandlerFMRadio(stream_attribute_target);        } else if (stream_attribute_target->input_source == AUDIO_SOURCE_ANC)        {            pCaptureHandler = new AudioALSACaptureHandlerANC(stream_attribute_target);        } else if (isModeInPhoneCall() == true)//打电话        {            pCaptureHandler = new AudioALSACaptureHandlerVoice(stream_attribute_target);        } else if ((isModeInVoipCall() == true)                  || (stream_attribute_target->NativePreprocess_Info.PreProcessEffect_AECOn == true)                 || (stream_attribute_target->input_source == AUDIO_SOURCE_VOICE_COMMUNICATION)                 || (stream_attribute_target->input_source == AUDIO_SOURCE_CUSTOMIZATION1) //MagiASR enable AEC                 || (stream_attribute_target->input_source == AUDIO_SOURCE_CUSTOMIZATION2)) //Normal REC with AEC        {            stream_attribute_target->BesRecord_Info.besrecord_enable = EnableBesRecord();            if (mStreamInVector.size() > 1)            {                for (size_t i = 0; i < mStreamInVector.size(); i++)                {                    if (mStreamInVector[i]->getStreamAttribute()->input_source == AUDIO_SOURCE_FM_TUNER)                    {                        mStreamInVector[i]->standby();                    }                }            }            if (isModeInVoipCall() == true                 || (stream_attribute_target->input_source == AUDIO_SOURCE_VOICE_COMMUNICATION))            {                stream_attribute_target->BesRecord_Info.besrecord_voip_enable = true;            }            switch (stream_attribute_target->input_device)            {                case AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET:                {                    pCaptureHandler = new AudioALSACaptureHandlerBT(stream_attribute_target);                    break;                }                default:                {                    pCaptureHandler = new AudioALSACaptureHandlerAEC(stream_attribute_target);                    break;                }            }        } else        {            //enable BesRecord if not these input sources            if ((stream_attribute_target->input_source != AUDIO_SOURCE_VOICE_UNLOCK) &&                (stream_attribute_target->input_source != AUDIO_SOURCE_FM_TUNER) &&                 (stream_attribute_target->input_source != AUDIO_SOURCE_MATV) &&                (stream_attribute_target->input_source != AUDIO_SOURCE_ANC) &&                (stream_attribute_target->input_source != AUDIO_SOURCE_UNPROCESSED))            {                //no uplink preprocess for sample rate higher than 48k                if ((stream_attribute_target->sample_rate > 48000)                      || (stream_attribute_target->audio_format != AUDIO_FORMAT_PCM_16_BIT))                       stream_attribute_target->BesRecord_Info.besrecord_enable = false;                else                    stream_attribute_target->BesRecord_Info.besrecord_enable = EnableBesRecord();//返回true            }            switch (stream_attribute_target->input_device)            {                case AUDIO_DEVICE_IN_BUILTIN_MIC://普通录音                case AUDIO_DEVICE_IN_BACK_MIC:                case AUDIO_DEVICE_IN_WIRED_HEADSET:                {                    pCaptureHandler = new AudioALSACaptureHandlerNormal(stream_attribute_target);//普通录音                    break;                }                case AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET:                {                    pCaptureHandler = new AudioALSACaptureHandlerBT(stream_attribute_target);                    break;                }                default:                {                    pCaptureHandler = new AudioALSACaptureHandlerNormal(stream_attribute_target);                    break;                }            }        }    }    // save capture handler object in vector    pCaptureHandler->setIdentity(mCaptureHandlerIndex);    mCaptureHandlerVector.add(mCaptureHandlerIndex, pCaptureHandler);    mCaptureHandlerIndex++;    return pCaptureHandler;}AudioALSACaptureHandlerNormal::AudioALSACaptureHandlerNormal(stream_attribute_t *stream_attribute_target) :    AudioALSACaptureHandlerBase(stream_attribute_target){    init();}status_t AudioALSACaptureHandlerNormal::init(){    mCaptureHandlerType = CAPTURE_HANDLER_NORMAL;    return NO_ERROR;}status_t AudioALSACaptureHandlerNormal::open(){    mCaptureDataClient = new AudioALSACaptureDataClient(AudioALSACaptureDataProviderNormal::getInstance(),                                                         mStreamAttributeTarget);    mHardwareResourceManager->startInputDevice(mStreamAttributeTarget->input_device);    //============Voice UI&Unlock REFERECE=============    AudioVUnlockDL *VUnlockhdl = AudioVUnlockDL::getInstance();    if (VUnlockhdl != NULL)    {        struct timespec systemtime;        memset(&systemtime, 0, sizeof(timespec));        VUnlockhdl->SetUplinkStartTime(systemtime, 1);    }    //===========================================    return NO_ERROR;}
AudioALSACaptureDataClient::AudioALSACaptureDataClient(    AudioALSACaptureDataProviderBase *pCaptureDataProvider,     stream_attribute_t *stream_attribute_target) :    mCaptureDataProvider(pCaptureDataProvider),    mIdentity(0xFFFFFFFF),    mStreamAttributeSource(mCaptureDataProvider->getStreamAttributeSource()),    mStreamAttributeTarget(stream_attribute_target),    mAudioALSAVolumeController(AudioVolumeFactory::CreateAudioVolumeController()),    mAudioSpeechEnhanceInfoInstance(AudioSpeechEnhanceInfo::getInstance()),    mChannelRemixOp(CHANNEL_REMIX_NOP),{    // init member struct    memset((void *)&mEchoRefRawDataBuf, 0, sizeof(mEchoRefRawDataBuf));    memset((void *)&mEchoRefSrcDataBuf, 0, sizeof(mEchoRefSrcDataBuf));    // raw data,输入设备的数据    memset((void *)&mRawDataBuf, 0, sizeof(mRawDataBuf));    mRawDataBuf.pBufBase = new char[kClientBufferSize];    mRawDataBuf.bufLen   = kClientBufferSize;    mRawDataBuf.pRead    = mRawDataBuf.pBufBase;    mRawDataBuf.pWrite   = mRawDataBuf.pBufBase;    // src data,重采样之后的数据    memset((void *)&mSrcDataBuf, 0, sizeof(mSrcDataBuf));    mSrcDataBuf.pBufBase = new char[kClientBufferSize];    mSrcDataBuf.bufLen   = kClientBufferSize;    mSrcDataBuf.pRead    = mSrcDataBuf.pBufBase;    mSrcDataBuf.pWrite   = mSrcDataBuf.pBufBase;    // processed data,处理之后的数据    memset((void *)&mProcessedDataBuf, 0, sizeof(mProcessedDataBuf));    mProcessedDataBuf.pBufBase = new char[kClientBufferSize];    mProcessedDataBuf.bufLen   = kClientBufferSize;    mProcessedDataBuf.pRead    = mProcessedDataBuf.pBufBase;    mProcessedDataBuf.pWrite   = mProcessedDataBuf.pBufBase;    mBesRecordStereoMode = false;    mBypassBesRecord = false;    mNeedBesRecordSRC = false;    mBliSrcHandler1 = NULL;    mBliSrcHandler2 = NULL;    mBesRecSRCSizeFactor = 1;    mBesRecSRCSizeFactor2 = 1;    dropBesRecordDataSize = 0;    mFirstSRC = true;    mFirstEchoSRC = true;    mDropMs = 0;    mSpeechProcessMode = SPE_MODE_REC;    mVoIPSpeechEnhancementMask = mStreamAttributeTarget->BesRecord_Info.besrecord_dynamic_mask;    //BesRecord Config    mSPELayer = new SPELayer();    SetCaptureGain();    if (mStreamAttributeTarget->BesRecord_Info.besrecord_enable)    {        LoadBesRecordParams();        mSPELayer->SetVMDumpEnable(mStreamAttributeTarget->BesRecord_Info.besrecord_tuningEnable ||                                        mStreamAttributeTarget->BesRecord_Info.besrecord_dmnr_tuningEnable);        mSPELayer->SetVMDumpFileName(mStreamAttributeTarget->BesRecord_Info.besrecord_VMFileName);        mSPELayer->SetPlatfromTimeOffset(ECHOREF_TIME_OFFSET); //Default -4ms EchoRef data        ConfigBesRecordParams(); //配置BesRecord对象的参数        StartBesRecord();        if((stream_attribute_target->BesRecord_Info.besrecord_voip_enable == true) ||            (stream_attribute_target->BesRecord_Info.besrecord_ForceMagiASREnable == true) ||            (stream_attribute_target->BesRecord_Info.besrecord_ForceAECRecEnable == true))        {            ALOGD("sample rate = %d, drop ms = %d, channels = %d, byts per sample = %d,             dropBesRecordDataSize = %d\n",            stream_attribute_target->sample_rate,             stream_attribute_target->num_channels,             audio_bytes_per_sample(stream_attribute_target->audio_format),             dropBesRecordDataSize);    } else {        CheckBesRecordStereoModeEnable();    }    //Android Native Preprocess effect +++    mAudioPreProcessEffect = NULL;    mAudioPreProcessEffect = new AudioPreProcess(mStreamAttributeTarget);    CheckNativeEffect();    //Android Native Preprocess effect ---    // attach client to capture data provider    mCaptureDataProvider->attach(this); // 设置mStreamAttributeSource    //assume starts after PCM open    mSPELayer->SetUPLinkDropTime(CAPTURE_DROP_MS);    mSPELayer->SetUPLinkIntrStartTime(GetSystemTime(false));    //根据源数据和目标数据的采样率确定是否需要重采样    if (mStreamAttributeSource->sample_rate != mStreamAttributeTarget->sample_rate)    {        SRC_PCM_FORMAT  SrcFormat = mStreamAttributeTarget->audio_format ==                                     AUDIO_FORMAT_PCM_16_BIT ? SRC_IN_Q1P15_OUT_Q1P15 :SRC_IN_Q1P31_OUT_Q1P31;        mBliSrc = newMtkAudioSrc(                mStreamAttributeSource->sample_rate, mStreamAttributeSource->num_channels,                mStreamAttributeTarget->sample_rate, mStreamAttributeSource->num_channels,                SrcFormat);        mBliSrc->open();    }    if (mStreamAttributeTarget->BesRecord_Info.besrecord_enable)    {        //move CheckNeedBesRecordSRC to here for mStreamAttributeSource info        CheckNeedBesRecordSRC();//判断BesRecord是否需要重采样,录音机和录像机都不需要    }    CheckChannelRemixOp();//判断是否需要声道转换}

配置BesRecord对象的参数

void AudioALSACaptureDataClient::ConfigBesRecordParams(void){    AppOps* appOps = appOpsGetInstance();    AppHandle* pAppHandle = appOps->appHandleGetInstance();//初始化audio_param的XML文件解析对象,用于参数读取    AudioType* VoIPAudioType = appOps->appHandleGetAudioTypeByName(pAppHandle, VOIP_AUDIO_TYPE);    AudioType* VoIPDmnrAudioType = appOps->appHandleGetAudioTypeByName(pAppHandle, VOIPDMNR_AUDIO_TYPE);    AudioType* VoIPGeneralAudioType = appOps->appHandleGetAudioTypeByName(pAppHandle, VOIPGENERAL_AUDIO_TYPE);    AudioType* RecordAudioType = appOps->appHandleGetAudioTypeByName(pAppHandle, RECORD_AUDIO_TYPE);    AudioType* RecordFirAudioType = appOps->appHandleGetAudioTypeByName(pAppHandle, RECORDFIR_AUDIO_TYPE);    AudioType* RecordDmnrAudioType = appOps->appHandleGetAudioTypeByName(pAppHandle, RECORDDMNR_AUDIO_TYPE);    std::string categoryPath = "";    uWord32 BesRecordEnhanceParas[EnhanceParasNum] = {0};    Word16 BesRecordCompenFilter[CompenFilterNum] = {0};    Word16 BesRecordDMNRParam[DMNRCalDataNum] = {0};    bool bVoIPEnable = IsVoIPEnable();    int RoutePath = GetBesRecordRoutePath();//获得路由ROUTE_SPEAKER    SPE_MODE mode = mSpeechProcessMode;    mBesRecordStereoMode = false;    // Get mSpeechProcessMode    if (bVoIPEnable)//VOIP通话    {        mode = SPE_MODE_VOIP;        mSpeechProcessMode = mode;    } else if ((mStreamAttributeTarget->input_source == AUDIO_SOURCE_CUSTOMIZATION1)//MagiASR need AEC             || (mStreamAttributeTarget->input_source == AUDIO_SOURCE_CUSTOMIZATION2))//Normal Record+AEC    {        mode = SPE_MODE_AECREC;        mSpeechProcessMode = mode;    } else {//普通录音        mode = SPE_MODE_REC;        mSpeechProcessMode = mode;//设置mode为SPE_MODE_REC    }    if (bVoIPEnable)//VOIP通话    {        // Get VoIP category path        if (RoutePath == ROUTE_BT)        {            categoryPath = VOIP_BT_PATH;        } else if (RoutePath == ROUTE_EARPHONE)        {            categoryPath = VOIP_3POLE_HEADSET_PATH;        } else if (RoutePath == ROUTE_HEADSET)        {            switch (AudioALSAHardwareResourceManager::getInstance()->getNumOfHeadsetPole())            {            case 4:                categoryPath = VOIP_4POLE_HEADSET_PATH;                break;            case 5:                if (AudioALSAHardware::GetInstance()->getParameters(keyANC_runing) == "ANC_running=true") {                    categoryPath += "," VOIP_5POLE_HEADSET_ANC_PATH;                } else {                    categoryPath += "," VOIP_5POLE_HEADSET_PATH;                }                break;            }        } else if (RoutePath == ROUTE_SPEAKER)        {            if ( appOps->appHandleIsFeatureOptionEnabled(pAppHandle, VOIP_HANDSFREE_DMNR_SUPPORT_FO) == 1) {                categoryPath = VOIP_HANDSFREE_NR_PATH;            } else {                categoryPath = VOIP_HANDSFREE_NO_NR_PATH;            }        } else        {            if ( appOps->appHandleIsFeatureOptionEnabled(pAppHandle, VOIP_NORMAL_DMNR_SUPPORT_FO) == 1) {                categoryPath = VOIP_HANDSET_DMNR_PATH;            } else {                categoryPath = VOIP_HANDSET_NO_DMNR_PATH;            }        }    } else {//普通录音        // Get Record category path        if ((mStreamAttributeTarget->input_source == AUDIO_SOURCE_VOICE_RECOGNITION) ||                                 mStreamAttributeTarget->BesRecord_Info.besrecord_tuning16K)        {            categoryPath += RECORD_VR_PATH;        } else if (mStreamAttributeTarget->input_source == AUDIO_SOURCE_VOICE_UNLOCK)        {            categoryPath += RECORD_VOICE_UNLOCK_PATH;            CheckBesRecordStereoModeEnable();        } else if (mStreamAttributeTarget->input_source == AUDIO_SOURCE_CUSTOMIZATION1)        {            categoryPath += RECORD_ASR_PATH;        } else if (mStreamAttributeTarget->input_source == AUDIO_SOURCE_CUSTOMIZATION2)        {            categoryPath += RECORD_CUSTOMIZATION2_PATH;        } else if (mStreamAttributeTarget->input_source == AUDIO_SOURCE_UNPROCESSED)        {            categoryPath += RECORD_UNPROCESSED_PATH;        } else {            // Sound/Video recording, Get application from besrecord_scene            switch(mStreamAttributeTarget->BesRecord_Info.besrecord_scene)            {            case 1:                categoryPath += RECORD_SND_REC_NORMAL_PATH;                CheckBesRecordStereoModeEnable();                break;            case 2:                categoryPath += RECORD_SND_REC_MEETING_PATH;                CheckBesRecordStereoModeEnable();                break;            case 3:                categoryPath += RECORD_SND_REC_LECTURE_PATH;                CheckBesRecordStereoModeEnable();                break;            case 4:                categoryPath += RECORD_CAM_REC_NORMAL_PATH;                CheckBesRecordStereoModeEnable();                break;            case 5:                categoryPath += RECORD_CAM_REC_MEETING_PATH;                break;            default:                if (mStreamAttributeTarget->input_source == AUDIO_SOURCE_CAMCORDER)                {                    categoryPath += RECORD_CAM_REC_NORMAL_PATH;//录像机录音                    CheckBesRecordStereoModeEnable();                } else {                    categoryPath += RECORD_SND_REC_NORMAL_PATH;//录音机录音                    CheckBesRecordStereoModeEnable();                }                break;            }        }        if (RoutePath == ROUTE_BT)//蓝牙录音        {            categoryPath += "," RECORD_BT_PATH;        } else if (RoutePath == ROUTE_HEADSET)//耳机录音        {            switch (AudioALSAHardwareResourceManager::getInstance()->getNumOfHeadsetPole())            {            case 4:                categoryPath += "," RECORD_4POLE_HEADSET_PATH;                break;            case 5:                if (AudioALSAHardware::GetInstance()->getParameters(keyANC_runing) == "ANC_running=true") {                    categoryPath += "," RECORD_5POLE_HEADSET_ANC_PATH;                } else {                    categoryPath += "," RECORD_5POLE_HEADSET_PATH;                }                break;            }        } else if (RoutePath == ROUTE_SPEAKER)        {            categoryPath += "," RECORD_HANDSET_PATH;//主辅麦录音        } else {            categoryPath += "," RECORD_HANDSET_PATH;        }    }    // set speech parameters+++    if (mode == SPE_MODE_VOIP || mStreamAttributeTarget->BesRecord_Info.besrecord_dmnr_tuningEnable == true)    {        pParamUnit = appOps->audioTypeGetParamUnit(VoIPAudioType, categoryPath.c_str());        pSpeciParam = appOps->paramUnitGetParamByName(pParamUnit, VOIP_PARAM);    } else {//普通录音         // record case        pParamUnit = appOps->audioTypeGetParamUnit(RecordAudioType, categoryPath.c_str());        pSpeciParam = appOps->paramUnitGetParamByName(pParamUnit, RECORD_PARAM);    }    //common parameters as same as VoIP's    pParamUnit = appOps->audioTypeGetParamUnit(VoIPGeneralAudioType, VOIP_COMMON_PATH);    pCommonParam = appOps->paramUnitGetParamByName(pParamUnit, VOIPGENERAL_PARAM_NAME);    //pSpeciParam + pCommonParam    memcpy(BesRecordEnhanceParas, (uWord32*)pSpeciParam->data, pSpeciParam->arraySize * sizeof(uWord32));    memcpy(&BesRecordEnhanceParas[pSpeciParam->arraySize], (uWord32*)pCommonParam->data,            pCommonParam->arraySize * sizeof(uWord32));    mSPELayer->SetEnhPara(mode, BesRecordEnhanceParas);    //speech parameters---    //FIR parameters+++    if (mStreamAttributeTarget->BesRecord_Info.besrecord_dmnr_tuningEnable == true)    {        pParamUnit = appOps->audioTypeGetParamUnit(VoIPAudioType, categoryPath.c_str());        pInFirParam = appOps->paramUnitGetParamByName(pParamUnit, VOIP_IN_FIR_PARAM);        memcpy(BesRecordCompenFilter, (Word16*)pInFirParam->data,                pInFirParam->arraySize * sizeof(Word16));   // UL1        memcpy(&BesRecordCompenFilter[pInFirParam->arraySize], (Word16*)pInFirParam->data,                pInFirParam->arraySize * sizeof(Word16));    } else if (mode == SPE_MODE_VOIP)    {        pParamUnit = appOps->audioTypeGetParamUnit(VoIPAudioType, categoryPath.c_str());        pInFirParam = appOps->paramUnitGetParamByName(pParamUnit, VOIP_IN_FIR_PARAM);        pOutFirParam = appOps->paramUnitGetParamByName(pParamUnit, VOIP_OUT_FIR_PARAM);        // VoIP FIR parameter have 3 FIR parameter, but 1 FIR parameter work for SWIP limitation.        memcpy(BesRecordCompenFilter, (Word16*)pInFirParam->data,                pInFirParam->arraySize * sizeof(Word16));   // UL1        memcpy(&BesRecordCompenFilter[pInFirParam->arraySize], (Word16*)pInFirParam->data,                pInFirParam->arraySize * sizeof(Word16));        memcpy(&BesRecordCompenFilter[pInFirParam->arraySize*2], (Word16*)pOutFirParam->data,                 pOutFirParam->arraySize * sizeof(Word16));   // DL    } else {//普通录音的参数读取,设置FIR滤波器        // Record 2 FIR param is work        pParamUnit = appOps->audioTypeGetParamUnit(RecordFirAudioType, categoryPath.c_str());        pInFir1Param = appOps->paramUnitGetParamByName(pParamUnit, RECORD_IN_FIR1_PARAM);        pInFir2Param = appOps->paramUnitGetParamByName(pParamUnit, RECORD_IN_FIR2_PARAM);        memcpy(BesRecordCompenFilter, (Word16*)pInFir1Param->data,                pInFir1Param->arraySize * sizeof(Word16));   // UL1        memcpy(&BesRecordCompenFilter[pInFir1Param->arraySize], (Word16*)pInFir2Param->data,                pInFir2Param->arraySize * sizeof(Word16));   // UL2    }    mSPELayer->SetCompFilter(mode, BesRecordCompenFilter);    //FIR parameters---    //DMNR parameters+++    if (((QueryFeatureSupportInfo()& SUPPORT_DUAL_MIC) > 0)        && (mStreamAttributeTarget->BesRecord_Info.besrecord_bypass_dualmicprocess == false))    {        //DMNR parameters        //google default input source AUDIO_SOURCE_VOICE_RECOGNITION not using DMNR (on/off by parameters)        if (((mStreamAttributeTarget->input_source == AUDIO_SOURCE_VOICE_RECOGNITION)             || (mStreamAttributeTarget->input_source == AUDIO_SOURCE_CUSTOMIZATION1)             || mStreamAttributeTarget->BesRecord_Info.besrecord_tuning16K             || mStreamAttributeTarget->BesRecord_Info.besrecord_dmnr_tuningEnable)             && ((QueryFeatureSupportInfo()& SUPPORT_ASR) > 0))        {            pParamUnit = appOps->audioTypeGetParamUnit(RecordDmnrAudioType, categoryPath.c_str());            pDmnrParam = appOps->paramUnitGetParamByName(pParamUnit, RECORD_DMNR_PARAM);            memcpy(BesRecordDMNRParam, (Word16*)pDmnrParam->data, pDmnrParam->arraySize * sizeof(Word16));        } else if (mode == SPE_MODE_VOIP)        {            //receiver path            if ((RoutePath == ROUTE_NORMAL) && ((QueryFeatureSupportInfo()& SUPPORT_VOIP_NORMAL_DMNR) > 0)                && CheckDynamicSpeechEnhancementMaskOnOff(VOIP_SPH_ENH_DYNAMIC_MASK_DMNR))            {                pParamUnit = appOps->audioTypeGetParamUnit(VoIPDmnrAudioType, categoryPath.c_str());                pDmnrParam = appOps->paramUnitGetParamByName(pParamUnit, VOIP_DMNR_PARAM);                memcpy(BesRecordDMNRParam, (Word16*)pDmnrParam->data, pDmnrParam->arraySize * sizeof(Word16));                SetDMNREnable(DMNR_NORMAL, true);            }            //speaker path            else if ((RoutePath == ROUTE_SPEAKER) && ((QueryFeatureSupportInfo()& SUPPORT_VOIP_HANDSFREE_DMNR) > 0)                     && CheckDynamicSpeechEnhancementMaskOnOff(VOIP_SPH_ENH_DYNAMIC_MASK_LSPK_DMNR))            {                pParamUnit = appOps->audioTypeGetParamUnit(VoIPDmnrAudioType, categoryPath.c_str());                pDmnrParam = appOps->paramUnitGetParamByName(pParamUnit, VOIP_DMNR_PARAM);                memcpy(BesRecordDMNRParam, (Word16*)pDmnrParam->data, pDmnrParam->arraySize * sizeof(Word16));                SetDMNREnable(DMNR_HANDSFREE, true);            } else            {                pParamUnit = appOps->audioTypeGetParamUnit(VoIPDmnrAudioType, VOIP_NO_DMNR_PATH);                pDmnrParam = appOps->paramUnitGetParamByName(pParamUnit, VOIP_DMNR_PARAM);                memcpy(BesRecordDMNRParam, (Word16*)pDmnrParam->data, pDmnrParam->arraySize * sizeof(Word16));                SetDMNREnable(DMNR_DISABLE, false);            }        } else //普通录音的消噪        {            pParamUnit = appOps->audioTypeGetParamUnit(RecordDmnrAudioType, RECORD_NO_DMNR_PATH);            pDmnrParam = appOps->paramUnitGetParamByName(pParamUnit, RECORD_DMNR_PARAM);            memcpy(BesRecordDMNRParam, (Word16*)pDmnrParam->data, pDmnrParam->arraySize * sizeof(Word16));        }        mSPELayer->SetDMNRPara(mode, BesRecordDMNRParam);    } else    {        // no DMNR support DMNR disabled        pParamUnit = appOps->audioTypeGetParamUnit(RecordDmnrAudioType, RECORD_NO_DMNR_PATH);        pDmnrParam = appOps->paramUnitGetParamByName(pParamUnit, RECORD_DMNR_PARAM);        memcpy(BesRecordDMNRParam, (Word16*)pDmnrParam->data, pDmnrParam->arraySize * sizeof(Word16));        mSPELayer->SetDMNRPara(mode, BesRecordDMNRParam);        SetDMNREnable(DMNR_DISABLE, false);    }    //DMNR parameters---    //need to config as 16k sample rate for voice recognition    //(Google's will use 48K preprocess instead) or VoIP or REC+AEC    if ((mStreamAttributeTarget->input_source == AUDIO_SOURCE_CUSTOMIZATION1)        || (mStreamAttributeTarget->input_source == AUDIO_SOURCE_CUSTOMIZATION2)        || (mStreamAttributeTarget->BesRecord_Info.besrecord_tuning16K == true)         || (IsVoIPEnable() == true))    {        if (mode == SPE_MODE_VOIP) //VoIP case        {            mSPELayer->SetSampleRate(mode, VOICE_RECOGNITION_RECORD_SAMPLE_RATE);            mSPELayer->SetAPPTable(mode, WB_VOIP);        } else    //voice recognition case        {            mSPELayer->SetSampleRate(mode, VOICE_RECOGNITION_RECORD_SAMPLE_RATE);            if (mStreamAttributeTarget->input_source == AUDIO_SOURCE_CUSTOMIZATION2)            {                mSPELayer->SetAPPTable(mode, MONO_AEC_RECORD);   //set library do AEC Record            } else//set library do voice recognition process or MagiASR            {                mSPELayer->SetAPPTable(mode, SPEECH_RECOGNITION);               }        }    } else    //normal record  use 48k    {        mSPELayer->SetSampleRate(mode, HD_RECORD_SAMPLE_RATE);//设置48k的采样率        if (mBesRecordStereoMode)//set library do stereo process,双声道录音        {            mSPELayer->SetAPPTable(mode, STEREO_RECORD);        } else //set library do mono process,单声道录音        {            mSPELayer->SetAPPTable(mode, MONO_RECORD);        }    }    mSPELayer->SetRoute((SPE_ROUTE)RoutePath);//设置输出路由为ROUTE_SPEAKER    //设置MIC的录音音量    long gain = mAudioALSAVolumeController->GetSWMICGain();    uint8_t TotalGain = mAudioALSAVolumeController->GetULTotalGain();    if (mStreamAttributeTarget->input_device == AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)    {        gain = 0;        TotalGain = 0;        ALOGD("BT path set Digital MIC gain = 0");    }    mSPELayer->SetMICDigitalGain(mode, gain);    mSPELayer->SetUpLinkTotalGain(mode, TotalGain);    ALOGD("-%s()", __FUNCTION__);}

判断输入设备到BesRecord是否需要重采样

bool AudioALSACaptureDataClient::CheckNeedBesRecordSRC(){    uint32_t BesRecord_usingsamplerate = HD_RECORD_SAMPLE_RATE;    if (mStreamAttributeTarget->BesRecord_Info.besrecord_enable == true)    {        //BesRecord need 16K sample rate data         //(Google's voice recognition will use 48K process due to new CTS test case)        if ((mStreamAttributeTarget->input_source == AUDIO_SOURCE_CUSTOMIZATION1)            || (mStreamAttributeTarget->input_source == AUDIO_SOURCE_CUSTOMIZATION2)            || (mStreamAttributeTarget->BesRecord_Info.besrecord_tuning16K == true)             || (IsVoIPEnable() == true))        {            BesRecord_usingsamplerate = VOICE_RECOGNITION_RECORD_SAMPLE_RATE;            //need src if the stream source sample rate are not the same with BesRecord needed            if ((mStreamAttributeSource->sample_rate  != VOICE_RECOGNITION_RECORD_SAMPLE_RATE)                  || (mStreamAttributeSource->num_channels != 2))            {                mNeedBesRecordSRC = true;            } else            {                mNeedBesRecordSRC = false;            }        } else    //BesRecord need 48K sample rate data        {            //need src if the stream source sample rate are not the same with BesRecord needed            if ((mStreamAttributeSource->sample_rate  != HD_RECORD_SAMPLE_RATE)              || (mStreamAttributeSource->num_channels != 2))            {                mNeedBesRecordSRC = true;                BesRecord_usingsamplerate = HD_RECORD_SAMPLE_RATE;            } else //录像机和录音机,不需要重采样            {                mNeedBesRecordSRC = false;            }        }        //if need to do BesRecord SRC        {            // Need SRC from stream target to BesRecord needed            if ((mStreamAttributeSource->sample_rate != BesRecord_usingsamplerate)                 || (mStreamAttributeSource->num_channels != 2))            {                mBliSrcHandler1 = newMtkAudioSrc(mStreamAttributeSource->sample_rate,                                                  mStreamAttributeSource->num_channels,                                                 BesRecord_usingsamplerate, 2,                                                  SRC_IN_Q1P15_OUT_Q1P15);                mBliSrcHandler1->open();            }            mBesRecSRCSizeFactor = ((BesRecord_usingsamplerate * 2) / (mStreamAttributeSource->sample_rate *                                     mStreamAttributeSource->num_channels)) + 1;            // Need SRC from BesRecord to stream target needed            if (mStreamAttributeTarget->sample_rate != BesRecord_usingsamplerate)            {                mBliSrcHandler2 = newMtkAudioSrc(BesRecord_usingsamplerate, 2,                                  mStreamAttributeTarget->sample_rate, 2, SRC_IN_Q1P15_OUT_Q1P15);                mBliSrcHandler2->open();            }            mBesRecSRCSizeFactor2 = ((mStreamAttributeTarget->sample_rate * 2) / (BesRecord_usingsamplerate * 2)) + 1;        }    } else    {        mNeedBesRecordSRC = false;    }    return mNeedBesRecordSRC;}

关联DataProvider对象和DataClient对象,DataProvider可以为多个DataClient提供数据

void AudioALSACaptureDataProviderBase::attach(AudioALSACaptureDataClient *pCaptureDataClient){    pCaptureDataClient->setIdentity(mCaptureDataClientIndex);    mCaptureDataClientVector.add(pCaptureDataClient->getIdentity(), pCaptureDataClient);    mCaptureDataClientIndex++;    // open pcm interface when 1st attach    if (mCaptureDataClientVector.size() == 1)    {        mOpenIndex++;        open();//打开输入设备    }}

打开输入设备,创建读取线程

status_t AudioALSACaptureDataProviderNormal::open(){    ALOGD("%s()", __FUNCTION__);    int pcmindex = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmUl1Capture);    int cardindex = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmUl1Capture);    ALOGD("%s cardindex = %d  pcmindex = %d", __FUNCTION__, cardindex, pcmindex);    struct pcm_params *params;    params = pcm_params_get(cardindex, pcmindex,  PCM_IN);    unsigned int buffersizemax = pcm_params_get_max(params, PCM_PARAM_BUFFER_BYTES);    ALOGD("buffersizemax = %d", buffersizemax);    pcm_params_free(params);    bool bHifiRecord = AudioSpeechEnhanceInfo::getInstance()->GetHifiRecord();    ALOGD("bHifiRecord = %d", bHifiRecord);    //debug++    btempDebug = AudioSpeechEnhanceInfo::getInstance()->GetDebugStatus();    ALOGD("btempDebug = %d", btempDebug);    //debug--    mConfig.channels = 2;    mConfig.period_count = 4;    mConfig.rate = 48000;    uint32_t latency = getLatencyTime();    if (bHifiRecord == true)    {       mConfig.rate = 96000;    }    if (latency == UPLINK_LOW_LATENCY_MS)    {       mConfig.period_count = 8; // 2*(20ms/5ms);    }    mConfig.format = PCM_FORMAT_S16_LE;    mStreamAttributeSource.audio_format = AUDIO_FORMAT_PCM_16_BIT;    // (UL)48K\5ms data\stereo\4byte\(Align64byte)    kReadBufferSize = (((uint32_t)(mConfig.rate / 1000 * latency * mConfig.channels *                       (pcm_format_to_bits(mConfig.format) / 8))) & 0xFFFFFFC0);    mConfig.period_size = (buffersizemax / mConfig.channels /                           (pcm_format_to_bits(mConfig.format) / 8) / mConfig.period_count;    mConfig.start_threshold = 0;    mConfig.stop_threshold = 0;    mConfig.silence_threshold = 0;    mCaptureDataProviderType = CAPTURE_PROVIDER_NORMAL;    mCaptureDropSize = 0;    // config attribute (will used in client SRC/Enh/... later) // TODO(Harvey): query this    mStreamAttributeSource.audio_channel_mask = AUDIO_CHANNEL_IN_STEREO;    mStreamAttributeSource.num_channels =         android_audio_legacy::AudioSystem::popCount(mStreamAttributeSource.audio_channel_mask);    mStreamAttributeSource.sample_rate = mConfig.rate;  //48000;    // Reset frames readed counter    mStreamAttributeSource.Time_Info.total_frames_readed = 0;    ALOGD("%s(), mCaptureDropSize=%d, CAPTURE_DROP_MS=%d", __FUNCTION__, mCaptureDropSize, CAPTURE_DROP_MS);    ALOGD("%s(), period_count=%d, period_size=%d, samplerate = %d", __FUNCTION__, mConfig.period_count,                  mConfig.period_size, mConfig.rate);    OpenPCMDump(LOG_TAG);    // enable pcm    int pcmIdx = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmUl1Capture);    int cardIdx = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmUl1Capture);    mPcm = pcm_open(cardIdx, pcmIdx, PCM_IN | PCM_MONOTONIC, &mConfig);    ALOGV("%s(), mPcm = %p", __FUNCTION__, mPcm);    pcm_start(mPcm);    // create reading thread    mEnable = true;    int ret = pthread_create(&hReadThread, NULL, AudioALSACaptureDataProviderNormal::readThread, (void *)this);    return NO_ERROR;}

检查是否需要进行重新混音

void AudioALSACaptureDataClient::CheckChannelRemixOp(void){    uint32_t targetChannel = mStreamAttributeTarget->num_channels;    uint32_t sourceChannel = mStreamAttributeSource->num_channels;    //支持BesRecord功能,SUPPORT_HD_RECORD    if (mStreamAttributeTarget->BesRecord_Info.besrecord_enable) {        if (targetChannel == 1) {//录音机,双声道变成单声道            mChannelRemixOp = CHANNEL_STEREO_DOWNMIX_L_ONLY;        } else if (targetChannel == 2 && !mBesRecordStereoMode) {            // speech enhancement output data is mono, need to convert to stereo            mChannelRemixOp = CHANNEL_STEREO_CROSSMIX_L2R;        } else {//录像机,不需要混音            mChannelRemixOp = CHANNEL_REMIX_NOP;        }    } else {        if (targetChannel == 1 && sourceChannel == 2) {            /* For unprocessed audio source, the down channel should refer to L ch only, don't do the channel mix */            if (mBesRecordStereoMode && mStreamAttributeTarget->input_source != AUDIO_SOURCE_UNPROCESSED) {                mChannelRemixOp = CHANNEL_STEREO_DOWNMIX;            } else {                mChannelRemixOp = CHANNEL_STEREO_DOWNMIX_L_ONLY;            }        } else if (targetChannel == 2 && sourceChannel == 1) {            mChannelRemixOp = CHANNEL_MONO_TO_STEREO;        } else if (targetChannel == 2 && sourceChannel == 2) {            if (mBesRecordStereoMode) {                mChannelRemixOp = CHANNEL_REMIX_NOP;            } else {                mChannelRemixOp = CHANNEL_STEREO_CROSSMIX_L2R;            }        } else {            mChannelRemixOp = CHANNEL_REMIX_NOP;        }    }}

读取输入设备的线程,不停的读取mPcmReadBuf里的数据

void *AudioALSACaptureDataProviderNormal::readThread(void *arg){    pthread_detach(pthread_self());    status_t retval = NO_ERROR;    AudioALSACaptureDataProviderNormal *pDataProvider = static_cast<AudioALSACaptureDataProviderNormal *>(arg);    uint32_t open_index = pDataProvider->mOpenIndex;    char nameset[32];    sprintf(nameset, "%s%d", __FUNCTION__, pDataProvider->mCaptureDataProviderType);    prctl(PR_SET_NAME, (unsigned long)nameset, 0, 0, 0);    // read raw data from alsa driver    char linear_buffer[kReadBufferSize];    uint32_t Read_Size = kReadBufferSize;    uint32_t kReadBufferSize_new;    while (pDataProvider->mEnable == true)    {        retval = pDataProvider->mEnableLock.lock_timeout(500);        if (pDataProvider->mEnable == false)        {            pDataProvider->mEnableLock.unlock();            break;        }        clock_gettime(CLOCK_REALTIME, &pDataProvider->mNewtime);        pDataProvider->timerec[0] = calc_time_diff(pDataProvider->mNewtime, pDataProvider->mOldtime);        pDataProvider->mOldtime = pDataProvider->mNewtime;        if (pDataProvider->mCaptureDropSize > 0)        {            Read_Size = (pDataProvider->mCaptureDropSize > kReadBufferSize) ?                          kReadBufferSize : pDataProvider->mCaptureDropSize;            int retval = pcm_read(pDataProvider->mPcm, linear_buffer, Read_Size);            pDataProvider->mCaptureDropSize -= Read_Size;            pDataProvider->mEnableLock.unlock();            continue;        } else        {            int retval = pcm_read(pDataProvider->mPcm, linear_buffer, kReadBufferSize);        }        clock_gettime(CLOCK_REALTIME, &pDataProvider->mNewtime);        pDataProvider->timerec[1] = calc_time_diff(pDataProvider->mNewtime, pDataProvider->mOldtime);        pDataProvider->mOldtime = pDataProvider->mNewtime;        //struct timespec tempTimeStamp;        pDataProvider->GetCaptureTimeStamp(&pDataProvider->mStreamAttributeSource.Time_Info, kReadBufferSize);        // use ringbuf format to save buffer info        pDataProvider->mPcmReadBuf.pBufBase = linear_buffer;        pDataProvider->mPcmReadBuf.bufLen   = kReadBufferSize + 1; // +1: avoid pRead == pWrite        pDataProvider->mPcmReadBuf.pRead    = linear_buffer;        pDataProvider->mPcmReadBuf.pWrite   = linear_buffer + kReadBufferSize;        pDataProvider->mEnableLock.unlock();        pDataProvider->provideCaptureDataToAllClients(open_index);//处理mPcmReadBuf里的输入数据        clock_gettime(CLOCK_REALTIME, &pDataProvider->mNewtime);        pDataProvider->timerec[2] = calc_time_diff(pDataProvider->mNewtime, pDataProvider->mOldtime);        pDataProvider->mOldtime = pDataProvider->mNewtime;    }    pthread_exit(NULL);    return NULL;}

处理输入到BesRecord的数据mPcmReadBuf,最后将处理好的数据保存在pSrcDataLinearBuf

void AudioALSACaptureDataProviderBase::provideCaptureDataToAllClients(const uint32_t open_index){    AudioALSACaptureDataClient *pCaptureDataClient = NULL;    WritePcmDumpData();    for (size_t i = 0; i < mCaptureDataClientVector.size(); i++)    {        pCaptureDataClient = mCaptureDataClientVector[i];        pCaptureDataClient->copyCaptureDataToClient(mPcmReadBuf);    }}uint32_t AudioALSACaptureDataClient::copyCaptureDataToClient(RingBuf pcm_read_buf){    uint32_t freeSpace = RingBuf_getFreeSpace(&mRawDataBuf);    uint32_t dataSize = RingBuf_getDataCount(&pcm_read_buf);    RingBuf_copyFromRingBuf(&mRawDataBuf, &pcm_read_buf, dataSize);//pcm_read_bu>>mRawDataBuf    // SRC    uint32_t kNumRawData = RingBuf_getDataCount(&mRawDataBuf);    uint32_t num_free_space = RingBuf_getFreeSpace(&mSrcDataBuf);    //BesRecord PreProcess effect    if (((mStreamAttributeTarget->BesRecord_Info.besrecord_enable) && !mBypassBesRecord))    {        char *pRawDataLinearBuf = new char[kNumRawData];        RingBuf_copyToLinear(pRawDataLinearBuf, &mRawDataBuf, kNumRawData);//mRawDataBuf>>pRawDataLinearBuf        if(mStreamAttributeSource->audio_format != AUDIO_FORMAT_PCM_16_BIT)        {            kNumRawData = TransferFormat(pRawDataLinearBuf,mStreamAttributeSource->audio_format,                                         AUDIO_FORMAT_PCM_16_BIT,kNumRawData);        }        uint32_t ProcesseddataSize = kNumRawData;        uint32_t SRC1outputLength = kNumRawData * mBesRecSRCSizeFactor;        char *pSRC1DataLinearBuf = new char[SRC1outputLength];        char *p_read = pRawDataLinearBuf;        uint32_t num_raw_data_left = kNumRawData;        uint32_t num_converted_data = SRC1outputLength;        uint32_t consumed = num_raw_data_left;        //如果输入设备到BesRecord的格式有差异就需要进行格式转换        if (mNeedBesRecordSRC && (mBliSrcHandler1 != 0))        {            mBliSrcHandler1->process((int16_t *)p_read, &num_raw_data_left,                            (int16_t *)pSRC1DataLinearBuf, &num_converted_data);            consumed -= num_raw_data_left;            p_read += consumed;            ProcesseddataSize = BesRecordPreprocess(pSRC1DataLinearBuf, num_converted_data);            //transform data format back to StreamAttribue needed after BesRecord process            if (mBliSrcHandler2 != 0)            {                uint32_t SRC2outputLength = ProcesseddataSize * mBesRecSRCSizeFactor2;                char *pSRC2DataLinearBuf = new char[SRC2outputLength];                p_read = pSRC1DataLinearBuf;                num_raw_data_left = ProcesseddataSize;                consumed = ProcesseddataSize;                mBliSrcHandler2->process((int16_t *)p_read, &num_raw_data_left,                            (int16_t *)pSRC2DataLinearBuf, &SRC2outputLength);                consumed -= num_raw_data_left;                p_read += consumed;            } else            {                RingBuf_copyFromLinear(&mSrcDataBuf, pSRC1DataLinearBuf, ProcesseddataSize);            }        } else    //无需转换设备到BesRecord的格式,普通录音        {            ProcesseddataSize = BesRecordPreprocess(pRawDataLinearBuf, kNumRawData);            //transform data format back to StreamAttribue needed after BesRecord processed            if (mBliSrcHandler2 != 0)            {                uint32_t SRC2outputLength = ProcesseddataSize * mBesRecSRCSizeFactor2;                char *pSRC2DataLinearBuf = new char[SRC2outputLength];                p_read = pRawDataLinearBuf;                num_raw_data_left = ProcesseddataSize;                consumed = ProcesseddataSize;                mBliSrcHandler2->process((int16_t *)p_read, &num_raw_data_left,                            (int16_t *)pSRC2DataLinearBuf, &SRC2outputLength);                consumed -= num_raw_data_left;                p_read += consumed;            } else //普通录音,pRawDataLinearBuf>>mSrcDataBuf            {                RingBuf_copyFromLinear(&mSrcDataBuf, pRawDataLinearBuf, ProcesseddataSize);            }        }    } else    //no need to do BesRecord PreProcess, transform data to mStreamAttributeTarget format    {        if (mBliSrc == NULL) // No need SRC        {            if (mStreamAttributeTarget->audio_format != mStreamAttributeSource->audio_format)            {                char *pRawDataLinearBuf = new char[kNumRawData];                RingBuf_copyToLinear(pRawDataLinearBuf, &mRawDataBuf, kNumRawData);                kNumRawData = TransferFormat(pRawDataLinearBuf,mStreamAttributeSource->audio_format,                                             mStreamAttributeTarget->audio_format,kNumRawData);                RingBuf_copyFromLinear(&mSrcDataBuf, pRawDataLinearBuf, kNumRawData);            } else            {                RingBuf_copyFromRingBuf(&mSrcDataBuf, &mRawDataBuf, kNumRawData);            }        } else // Need SRC        {            char *pRawDataLinearBuf = new char[kNumRawData];            RingBuf_copyToLinear(pRawDataLinearBuf, &mRawDataBuf, kNumRawData);            char *pSrcDataLinearBuf = new char[num_free_space];            char *p_read = pRawDataLinearBuf;            uint32_t num_raw_data_left = kNumRawData;            uint32_t num_converted_data = num_free_space; // max convert num_free_space            uint32_t consumed = num_raw_data_left;            if (mStreamAttributeTarget->audio_format == AUDIO_FORMAT_PCM_16_BIT )            {                mBliSrc->process((int16_t *)p_read, &num_raw_data_left,                                (int16_t *)pSrcDataLinearBuf, &num_converted_data);            } else            {                mBliSrc->process((int32_t *)p_read, &num_raw_data_left,                                (int32_t *)pSrcDataLinearBuf, &num_converted_data);            }            consumed -= num_raw_data_left;            p_read += consumed;            RingBuf_copyFromLinear(&mSrcDataBuf, pSrcDataLinearBuf, num_converted_data);        }    }    freeSpace = RingBuf_getFreeSpace(&mProcessedDataBuf);    dataSize = RingBuf_getDataCount(&mSrcDataBuf);    uint32_t ProcessdataSize = dataSize;    //android native effect, use the same sample rate as mStreamAttributeTarget    //如果上层添加了mtk effect,这里就会处理    if ((mAudioPreProcessEffect->num_preprocessors > 0) && (IsVoIPEnable() == false))    {        char *pSrcDataLinearBuf = new char[dataSize];        uint32_t native_processed_byte = 0;        RingBuf_copyToLinear(pSrcDataLinearBuf, &mSrcDataBuf, dataSize);        if (IsNeedChannelRemix()) {            ProcessdataSize = ApplyChannelRemix((short *)pSrcDataLinearBuf, dataSize);        }        native_processed_byte = NativePreprocess(pSrcDataLinearBuf, ProcessdataSize);        RingBuf_copyFromLinear(&mProcessedDataBuf, pSrcDataLinearBuf, native_processed_byte);    } else    //no need to do native effect, copy data from mSrcDataBuf to mProcessedDataBuf directly    {        if (IsNeedChannelRemix())//录音机,需要重新混音, mSrcDataBuf>>mProcessedDataBuf        {            ApplyChannelRemixWithRingBuf(&mSrcDataBuf, &mProcessedDataBuf);        } else //录像机,不需要重新混音, mSrcDataBuf>>pSrcDataLinearBuf        {            RingBuf_copyFromRingBuf(&mProcessedDataBuf, &mSrcDataBuf, dataSize);        }    }    return 0;}

使用BesRecord进行音频数据的预处理,会区分普通录音和VoIP,VoIP会进行回音消除。

uint32_t AudioALSACaptureDataClient::BesRecordPreprocess(void *buffer , uint32_t bytes){    struct InBufferInfo InBufinfo = {0};    uint32_t retSize = bytes;    if (!mBypassBesRecord)    {        InBufinfo.pBufBase = (short *)buffer;        InBufinfo.BufLen = bytes;        InBufinfo.time_stamp_queued = GetSystemTime(false);        InBufinfo.bHasRemainInfo = true;        InBufinfo.time_stamp_predict = GetCaptureTimeStamp();        retSize = mSPELayer->Process(&InBufinfo);//具体的处理函数    }    return retSize;}

进行声道转换,输入设备提供的是双声道的数据,而录音机需要的是单声道的数据。

ssize_t AudioALSACaptureDataClient::ApplyChannelRemixWithRingBuf(RingBuf *srcBuffer, RingBuf *dstBuffer){    ssize_t remixSize = 0;    size_t dataSize = RingBuf_getDataCount(srcBuffer);    size_t availSize = RingBuf_getFreeSpace(dstBuffer);    size_t dataSizeAfterProcess;    char *tempBuffer = NULL;    size_t tempBufferSize;    if (mChannelRemixOp == CHANNEL_MONO_TO_STEREO) {        dataSizeAfterProcess = dataSize << 1;    } else if (mChannelRemixOp == CHANNEL_STEREO_DOWNMIX ||               mChannelRemixOp == CHANNEL_STEREO_DOWNMIX_L_ONLY ||               mChannelRemixOp == CHANNEL_STEREO_DOWNMIX_R_ONLY) {        dataSizeAfterProcess = dataSize >> 1;//录音机需要将双声道转换为单声道,处理之后数据量减少一半    } else {        dataSizeAfterProcess = dataSize;    }    //申请处理后的存储空间    tempBufferSize = (dataSizeAfterProcess > dataSize) ? dataSizeAfterProcess : dataSize;    tempBuffer = new char[tempBufferSize];    //转换声道数,处理数据    RingBuf_copyToLinear(tempBuffer, srcBuffer, dataSize);    remixSize = ApplyChannelRemix((short *)tempBuffer, dataSize);    RingBuf_copyFromLinear(dstBuffer, tempBuffer, remixSize);    return remixSize;}

根据不同的目标声道数将双声道数据进行转换

ssize_t AudioALSACaptureDataClient::ApplyChannelRemix(short *buffer, size_t bytes){    ssize_t remixSize = 0;    uint32_t remixOp = mChannelRemixOp;    int frameCount;    if (remixOp == CHANNEL_STEREO_CROSSMIX_L2R)    {        frameCount = bytes >> 2;        for (int i = 0; i < frameCount; i++) {            *(buffer + 1) = *buffer;            buffer += 2;        }        remixSize = bytes;    }    else if (remixOp == CHANNEL_STEREO_CROSSMIX_R2L)    {        frameCount = bytes >> 2;        for (int i = 0; i < frameCount; i++) {            *buffer = *(buffer + 1);            buffer += 2;        }        remixSize = bytes;    }    else if (remixOp == CHANNEL_STEREO_DOWNMIX)    {        short mix;        short *monoBuffer = buffer;        frameCount = bytes >> 2;        for (int i = 0; i < frameCount; i++) {            mix = (*buffer + *(buffer + 1)) >> 1;            *monoBuffer = mix;            monoBuffer++;            buffer += 2;        }        remixSize = bytes >> 1;    }    else if (remixOp == CHANNEL_STEREO_DOWNMIX_L_ONLY)//录音机,保留左声道    {        short *monoBuffer = buffer;        frameCount = bytes >> 2;//每个frame等于16*2个byte        for (int i = 0; i < frameCount; i++) {            *monoBuffer = *buffer;            monoBuffer++;            buffer += 2;        }        remixSize = bytes >> 1;//处理之后的数据量减半    }    else if (remixOp == CHANNEL_STEREO_DOWNMIX_R_ONLY)    {        short *monoBuffer = buffer;        frameCount = bytes >> 2;        for (int i = 0; i < frameCount; i++) {            *monoBuffer = *(buffer+1);            monoBuffer++;            buffer += 2;        }        remixSize = bytes >> 1;    }    else if (remixOp == CHANNEL_MONO_TO_STEREO)    {        frameCount = bytes >> 1;        short *monoBuffer = buffer + frameCount - 1;        short *stereoBuffer = buffer + (frameCount * 2) - 1;        short data;        for (int i = 0; i < frameCount; i++) {             data = *monoBuffer--;            *stereoBuffer-- = data;            *stereoBuffer-- = data;        }        remixSize = bytes << 1;    }    return remixSize;}

打开输入设备处理数据之后,接着会读取数据

ssize_t AudioALSACaptureHandlerNormal::read(void *buffer, ssize_t bytes){    mCaptureDataClient->read(buffer, bytes);    //============Voice UI&Unlock REFERECE=============    AudioVUnlockDL *VUnlockhdl = AudioVUnlockDL::getInstance();    if (VUnlockhdl != NULL)    {        struct timespec systemtime;        memset(&systemtime, 0, sizeof(timespec));        VUnlockhdl->SetUplinkStartTime(systemtime, 0);    }    //===========================================    return bytes;}

客户端从mProcessedDataBuf读取处理好的数据,每次读取ReadDataBytes字节

ssize_t AudioALSACaptureDataClient::read(void *buffer, ssize_t bytes){    char *pWrite = (char *)buffer;    char *pStart = (char *)buffer;    uint32_t RingBufferSize = 0;    uint32_t ReadDataBytes = bytes;    int TryCount = 8;    do    {        CheckNativeEffect();    //add here for alsaStreamIn lock holding        CheckDynamicSpeechMask();        if (dropBesRecordDataSize > 0)        {            /* Drop distortion data */            RingBufferSize = RingBuf_getDataCount(&mProcessedDataBuf);            if (RingBufferSize >= dropBesRecordDataSize)            {                // Drop dropBesRecordDataSize bytes from RingBuffer                while(dropBesRecordDataSize > 0)                {                    uint32_t dropSize = dropBesRecordDataSize > ReadDataBytes ?                                         ReadDataBytes : dropBesRecordDataSize;                    RingBuf_copyToLinear((char *)pWrite, &mProcessedDataBuf, dropSize);                    dropBesRecordDataSize -= dropSize;                }            }            else            {                // Drop RingBufferSize from RingBuffer                while(RingBufferSize > 0 && dropBesRecordDataSize > 0)                {                    uint32_t dropSize = dropBesRecordDataSize > ReadDataBytes ?                                         ReadDataBytes : dropBesRecordDataSize;                    dropSize = dropSize > RingBufferSize ? RingBufferSize : dropSize;                    RingBuf_copyToLinear((char *)pWrite, &mProcessedDataBuf, dropSize);                    RingBufferSize -= dropSize;                    dropBesRecordDataSize -= dropSize;                }            }        }        if (dropBesRecordDataSize == 0)        {            RingBufferSize = RingBuf_getDataCount(&mProcessedDataBuf);            if (RingBufferSize >= ReadDataBytes) // ring buffer is enough, copy & exit            {                RingBuf_copyToLinear((char *)pWrite, &mProcessedDataBuf, ReadDataBytes);                ReadDataBytes = 0;                mLock.unlock();                break;            }            else // ring buffer is not enough, copy all data            {                RingBuf_copyToLinear((char *)pWrite, &mProcessedDataBuf, RingBufferSize);                ReadDataBytes -= RingBufferSize;                pWrite += RingBufferSize;            }        }        // wait for new data        if (mWaitWorkCV.waitRelative(mLock, milliseconds(300)) != NO_ERROR)        {            ALOGW("%s(), waitRelative fail", __FUNCTION__);            mLock.unlock();            break;        }        TryCount--;    }    while (ReadDataBytes > 0 && (TryCount != 0 || dropBesRecordDataSize != 0));    if (IsNeedApplyVolume())    {        ApplyVolume(buffer, bytes);    }    return bytes - ReadDataBytes;}
原创粉丝点击