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

【C】dump 音频

最近更新时间2023.03.17 15:43:42

首次发布时间2023.03.17 15:43:42

使用说明
完整例子(以调试“回声消除”为例)
#include "sami_core.h"

// help function
std::vector<uint8_t> loadModelAsBinary(const std::string& path) {
    std::ifstream file(path, std::ios::binary | std::ios::ate);
    std::streamsize size = file.tellg();
    file.seekg(0, std::ios::beg);

    std::vector<uint8_t> buffer(size);
    if(file.read((char*)buffer.data(), size)) { return buffer; }

    return {};
}

// step 0, load model
const std::string model_path = "/path/to/aec.model";
std::vector<uint_8> model_buffer = loadModelAsBinary(model_path);
assert(model_buffer.size() > 0);

// step 1, create aec handle
const int sample_rate = 44100; // 44100 needs aec44k.model, 16000 needs aec.model
const int num_channels = 2;
const int block_size = 512;
SAMICoreHandle handle = nullptr;
SAMICoreExecutorContextCreateParameter create_param;
memset(&create_param,0,sizeof(create_param));
create_param.sampleRate = sample_rate;
create_param.numChannel = num_channels;
create_param.maxBlockSize = block_size;
create_param.modelBuffer = (const char*)(model_buffer.data());
create_param.modelLen = model_buffer.size();
int ret = SAMICoreCreateHandleByIdentify(&handle, SAMICoreIdentify::SAMICoreIdentify_RNNAEC, & create_param);
assert(ret == SAMI_OK);

SAMICoreDebugConfig debug_config;
debug_config.enableFileDump = true;
debug_config.dumpPath = "/path/to/dump/"; //set a directory instead of a file for dump
debug_config.fileNamePrefix = "anything_you_want_to_mark";//fileNamePrefix will be the first "word" of the dumped file name
debug_config.sample_rate = sample_rate;
debug_config.channel = num_channels;
ret = SAMICoreInitDebugConfig(handle, &debug_config);

// step 2, create input and output audio block 
SAMICoreAudioBuffer in_mic_buffer;
SAMICoreAudioBuffer in_ref_buffer;
SAMICoreAudioBuffer out_buffer;

in_mic_buffer.numberChannels = num_channels;
in_mic_buffer.numberSamples = block_size;
in_mic_buffer.data = new float*[num_channels];
in_mic_buffer.isInterleave = 0;

in_ref_buffer.numberChannels = num_channels;
in_ref_buffer.numberSamples = block_size;
in_ref_buffer.data = new float*[num_channels];
in_ref_buffer.isInterleave = 0;

out_buffer.numberChannels = num_channels;
out_buffer.numberSamples = block_size;
out_buffer.data = new float*[num_channels];
out_buffer.isInterleave = 0;

for(int c = 0; c < int(num_channels); ++c){
    in_mic_buffer.data[c] = new float[block_size];
    in_ref_buffer.data[c] = new float[block_size];
    out_buffer.data[c] = new float[block_size];
}

SAMICoreAecInput aec_input;
aec_input.mic = &in_mic_buffer;
aec_input.ref = &in_ref_buffer;

SAMICoreBlock in_block;
SAMICoreBlock out_block;

in_block.numberAudioData = 1;
in_block.dataType = SAMICoreDataType_AecInput;
in_block.audioData = &aec_input;

out_block.numberAudioData = 1;
out_block.dataType = SAMICoreDataType_AudioBuffer;
out_block.audioData = &out_buffer;

// step 3, process block by block
for(;hasAudioSamples();)
{
    copyMicSamplesToInputBuffer(in_mic_buffer);
    copyRefSamplesToInputBuffer(in_ref_buffer);

    int ret = SAMICoreProcess(handle, &in_block, &out_block);
    assert(ret == SAMI_OK);

    // do something after process
    doSomethingAfterProcess(out_buffer);
}

// step 4, remember release resource
ret = SAMICoreDestroyHandle(handle);
assert(ret == SAMI_OK);

for(int c = 0; c < int(num_channels); ++c) {
    delete[] in_mic_buffer.data[c];
    delete[] in_ref_buffer.data[c];
    delete[] out_buffer.data[c];
}

delete[] in_mic_buffer.data;
delete[] in_ref_buffer.data;
delete[] out_buffer.data;
使用步骤

〇、创建文件夹路径

会在该路径下保存dump出来的文件,只需要指定文件路径,不需要指定文件名。最后会在该路径下生成命名为"audiosdk_$fileNamePrefix_$handleAddress_input_$sampleRate_$channelNum.wav"、
"audiosdk_$fileNamePrefix_$handleAddress_output_$sampleRate_$channelNum.wav"这两个文件,分别对应输入数据和输出数据。若是为了调试回声消除(见【C】回声消除-V2 ),会在该路径下生成
"audiosdk_$fileNamePrefix_$handleAddress_mic_$sampleRate_$channelNum.wav"、
"audiosdk_$fileNamePrefix_$handleAddress_ref_$sampleRate_$channelNum.wav"、
"audiosdk_$fileNamePrefix_$handleAddress_output_$sampleRate_$channelNum.wav"
这3个文件,分别代表输入的mic数据、输入的ref数据、处理后的输出数据。

一、在创建算法句柄后初始化Debug 设置

在通过 SAMICoreCreateHandleByIdentify 创建算法句柄 handle后(见SAMI core各功能接口文档“使用步骤”中的“创建算法句柄”小节),调用SAMICoreInitDebugConfig初始化Debug设置。

SAMICoreDebugConfig debug_config;
debug_config.dumpPath = "/path/to/dump/"; //set a directory instead of a file for dump
debug_config.fileNamePrefix = "anything_you_want_to_mark";//fileNamePrefix will be the second "word" of the dumped file name
debug_config.sampleRate = sample_rate;
debug_config.channel = num_channels;
ret = SAMICoreInitDebugConfig(handle, &debug_config);

以下情况会初始化失败:

  1. 没有正确传入handle,例如在SAMICoreCreateHandleByIdentify前就调用SAMICoreInitDebugConfig.

二、创建 SAMICoreBlock 用于存放输入和输出

见SAMI core 各功能接口“使用步骤”中的“创建 SAMICoreBlock 用于存放输入和输出”小节示例中采用这种方法。

三、处理音频

见SAMI core 各功能接口“使用步骤”中的“处理音频”小节示例中采用这种方法。

四、释放dump Audio资源

ret = SAMICoreReleaseDebugConfig(handle);

五、释放资源

释放 handle

ret = SAMICoreDestroyHandle(handle);

六、备注

下述接口需在同一条线程调用
SAMICoreInitDebugConfig
SAMICoreReleaseDebugConfig
SAMICoreProcess