这里演示 webRTC 的 3A算法测试类。
【01】准备工作
仅编译 example:
cd src
set DEPOT_TOOLS_WIN_TOOLCHAIN=0
gn gen out/Default
ninja -C out/Default examples
在 src/example 下创建自己的测试目录 audio/aec,创建 test.cc :
该类只创建了一个 APM 音频处理对象:
#include "iostream"
#include "modules/audio_processing/include/audio_processing.h"
int main(){
std::cout << "Start ->" << std::endl;
rtc::scoped_refptr<webrtc::AudioProcessing> apm = webrtc::AudioProcessingBuilder().Create();
std::cout << "End ->" << std::endl;
return 0;
}
然后修改 example/BUILD.gn ,加入上面可执行测试类:
直接追加在 rtc_executable("peerconnection_server") 后面即可:
# 音频处理测试类
rtc_executable("audio_aec_test") {
testonly = true
sources = [ "audio/aec/test.cpp" ]
deps = [
# 音频处理的模块
"../modules/audio_processing",
"../modules/audio_processing:api",
]
}
同时在分组 example 里面追加可执行类的依赖:
deps += [
":peerconnection_server",
":stunserver",
":turnserver",
":audio_aec_test" # 追加在这三个可执行类后面即可
]
【01】测试类
//
// Created by tangyufan on 10/10/2022.
//
#include "iostream"
#include "modules/audio_processing/include/audio_processing.h"
#include "api/audio/echo_canceller3_config.h"
#include "api/audio/echo_control.h"
// 引入头文件参考 peerconnection
// 测试用例参考 audio_processing_unittest.cc
int main(int argc, char **argv){
std::cout << "Start ->" << std::endl;
// 采样率和声道数
int kSampleRateHz = 8000;
int kNumChannels = 1;
// fread 每次读取10ms的数据
float frame_step = 10;
int size = kSampleRateHz * frame_step / 1000.0;
int delay = 100;
int analog_level = 60;
FILE *far_file = fopen("C:\\workspace\\webRTC\\webRTC-code\\src\\data\\audio_processing\\far.wav", "rb");
FILE *near_file = fopen("C:\\workspace\\webRTC\\webRTC-code\\src\\data\\audio_processing\\near.wav", "rb");
FILE *aec_out_file = fopen("C:\\workspace\\webRTC\\webRTC-code\\src\\data\\audio_processing\\out.raw", "wb");
rtc::scoped_refptr<webrtc::AudioProcessing> apm = webrtc::AudioProcessingBuilder().Create();
// 只开启 aec
webrtc::AudioProcessing::Config config;
config.echo_canceller.enabled = true;
config.echo_canceller.mobile_mode = false;
config.high_pass_filter.enabled = false;
config.gain_controller1.enabled = false;
config.gain_controller2.enabled = false;
config.noise_suppression.enabled = false;
apm->ApplyConfig(config);
apm->set_stream_delay_ms(delay);
apm->set_stream_analog_level(analog_level);
webrtc::StreamConfig inStreamConfig = webrtc::StreamConfig(kSampleRateHz, kNumChannels);
webrtc::StreamConfig outStreamConfig = webrtc::StreamConfig(kSampleRateHz, kNumChannels);
int16_t *far_frame = (int16_t*)malloc(1024);
int16_t *near_frame = (int16_t*)malloc(1024);
int16_t *out_frame = (int16_t*)malloc(1024);
std::cout << "Do parse ->" << std::endl;
int read_count = 0;
while (true){
read_count = fread((char*)far_frame,sizeof(int16_t),size,far_file);
if(read_count != size){
fseek(near_file, read_count * sizeof(int16_t), SEEK_CUR);
}
apm->ProcessReverseStream(far_frame,inStreamConfig,outStreamConfig,NULL);
read_count = fread((char*)near_frame,sizeof(int16_t),size,near_file);
if (read_count != size) {
std::cout << "Do parse break ->" << std::endl;
break;
}
apm->ProcessStream(near_frame,inStreamConfig,outStreamConfig,out_frame);
fwrite (out_frame,sizeof(int16_t),size,aec_out_file);
}
fclose(far_file);
fclose(near_file);
fclose(aec_out_file);
free(far_frame);
free(near_frame);
free(out_frame);
std::cout << "End ->" << std::endl;
return 0;
}