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

博客详细阐述了录音录像设备的输入通路处理,包括创建handler、配置输入设备、判断重采样需求、数据关联、读取线程、混音检查、数据处理、声道转换等步骤,确保音频数据预处理和声道适配符合录音或VoIP的需求。
摘要由CSDN通过智能技术生成
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(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值