You need to enable JavaScript to run this app.
导航

【Java】回声消除-V2

最近更新时间2023.03.16 11:40:12

首次发布时间2023.03.16 11:40:12

使用步骤

1. 创建handle

sdk支持带模型的算法和dsp处理的算法,dsp效果的适用于性能比较低端的机器。算法模型详见回声消除介绍小节。

samiCore = new SAMICore();
boolean use_nn = true;
// 创建句柄
if (use_nn){
    SAMICoreExecutorContextCreateParameter parameter = new SAMICoreExecutorContextCreateParameter();
    parameter.sampleRate = sampleRate;
    parameter.numChannel = numChannel;
    parameter.maxBlockSize = max_block_size;
    parameter.modelBuffer = FunctionHelper.readBinaryFile(modelFileName,context);
    parameter.modelLen = parameter.modelBuffer.length;
    int ret = samiCore.SAMICoreCreateHandleByIdentify(
            SAMICoreIdentify.SAMICoreIdentify_RNNAEC, parameter);
    if (ret != SAMICoreCode.SAMI_OK) {
        System.out.println("Create SAMICoreIdentify_RNNAEC handle failed, ret " + ret);
        return ret;
    }else{
        createHandleDone = true;
    }
}else{
    // dsp aec
    SAMICore3ACreateParameter parameter = new SAMICore3ACreateParameter();
    parameter.numChannel = numChannel;
    parameter.sampleRate = sampleRate;
    parameter.maxBlockSize = max_block_size;
    int ret = samiCore.SAMICoreCreateHandleByIdentify(SAMICoreIdentify.SAMICoreIdentify_AEC, parameter);
    if (ret != SAMICoreCode.SAMI_OK) {
        System.out.println("Create SAMICoreIdentify_RNNAEC handle failed, ret " + ret);
        return ret;
    }else{
        createHandleDone = true;
    }
}

2. 初始化buffer

micAudioBuffer = new SAMICoreAudioBuffer();
micAudioBuffer.numberChannels = numChannel;
micAudioBuffer.numberSamples = max_block_size;
micAudioBuffer.data = new float[(int) micAudioBuffer.numberChannels][(int) micAudioBuffer.numberSamples];

refAudioBuffer = new SAMICoreAudioBuffer();
refAudioBuffer.numberChannels = numChannel;
refAudioBuffer.numberSamples = max_block_size;
refAudioBuffer.data = new float[(int) refAudioBuffer.numberChannels][(int) refAudioBuffer.numberSamples];

aec_input = new SAMICoreAecInput();
aec_input.mic = micAudioBuffer;
aec_input.ref = refAudioBuffer;

inBlock = new SAMICoreBlock();
inBlock.dataType = SAMICoreDataType.SAMICoreDataType_AecInput;
inBlock.audioData = new SAMICoreAecInput[1];
inBlock.audioData[0] = aec_input;

//output buffer
outAudioBuffer = new SAMICoreAudioBuffer();
outAudioBuffer.numberChannels = numChannel;
outAudioBuffer.numberSamples = max_block_size;
outAudioBuffer.data = new float[(int) outAudioBuffer.numberChannels][(int) outAudioBuffer.numberSamples];

outBlock = new SAMICoreBlock();
outBlock.dataType = SAMICoreDataType.SAMICoreDataType_AudioBuffer;
outBlock.audioData = new SAMICoreAudioBuffer[1];
outBlock.audioData[0] = outAudioBuffer;

numberChannels : 需要跟创建handle设置的一致
numberSamples:每一个处理的实际帧数,要求 numberSamples<= parameter.maxBlockSize

3. 处理数据

for (int numSamples = 0; numSamples < totalNumSamples;) {
    if((numSamples + micAudioBuffer.numberSamples) > totalNumSamples) {
        micAudioBuffer.numberSamples = totalNumSamples - numSamples;
        refAudioBuffer.numberSamples = totalNumSamples - numSamples;
        outAudioBuffer.numberSamples = totalNumSamples - numSamples;
    }

    for (int i = 0; i < micAudioBuffer.numberChannels; i++) {
        for (int j = 0; j < micAudioBuffer.numberSamples; j++) {
            micAudioBuffer.data[i][j] = mic_planar_float_data[i][numSamples + j];
        }
    }

    for (int i = 0; i < refAudioBuffer.numberChannels; i++) {
        for (int j = 0; j < refAudioBuffer.numberSamples; j++) {
            refAudioBuffer.data[i][j] = ref_planar_float_data[i][numSamples + j];
        }
    }

    int ret = samiCore.SAMICoreProcess(inBlock, outBlock);
    if (ret != SAMICoreCode.SAMI_OK) {
        System.out.println("aec process audio data failed, ret " + ret);
        return ret;
    }

    for (int i = 0; i < outAudioBuffer.numberChannels; i++) {
        for (int j = 0; j < outAudioBuffer.numberSamples; j++) {
            out_planar_float_data[i][j+numSamples] = outAudioBuffer.data[i][j];
        }
    }
    // update index
    numSamples = numSamples + micAudioBuffer.numberSamples;
}

注意检查 SAMICoreProcess 函数的返回值,处理输入不正确或者内部处理错误都会有返回值,错误码可以查看错误检查一节

4. 释放handle

if (createHandleDone){
    samiCore.SAMICoreDestroyHandle();
}