#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数据、处理后的输出数据。
在通过 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);
以下情况会初始化失败:
SAMICoreCreateHandleByIdentify
前就调用SAMICoreInitDebugConfig
.见SAMI core 各功能接口“使用步骤”中的“创建 SAMICoreBlock 用于存放输入和输出”小节示例中采用这种方法。
见SAMI core 各功能接口“使用步骤”中的“处理音频”小节示例中采用这种方法。
ret = SAMICoreReleaseDebugConfig(handle);
释放 handle
ret = SAMICoreDestroyHandle(handle);
下述接口需在同一条线程调用
SAMICoreInitDebugConfig
SAMICoreReleaseDebugConfig
SAMICoreProcess