目录
做成接口
RNNoise已经将推理过程整理成了一个函数(src/denoise.c中的rnnoise_process_frame函数),我们只需要写一个类,其中包含2~3个方法(构造函数、推理函数、析构函数)即可。
比如我们创建rnnoise_inference.cpp与rnnoise_inference.h文件,构建Rnnoise类,其中包含一个构造函数和一个推理函数:
rnnoise_inference.h
#ifndef RNNOISE_INFERENCE
#define RNNOISE_INFERENCE
#include "rnnoise.h"
class Rnnoise{
private:
DenoiseState *st;
public:
Rnnoise();
double inference(float *x);
};
#endif
rnnoise_inference.cpp
#include "rnnoise_inference.h"
Rnnoise::Rnnoise(){
st = rnnoise_create(NULL);
}
double Rnnoise::inference(float *x){
double vad_output = 1;
vad_output = rnnoise_process_frame(this->st, x, x);
return vad_output;
}
使用方法(主要部分)
#include "rnnoisevhd.h"
int main(int argc, char **argv) {
...
float vad = 1.0;
Rnnoise rnnoise;
while(1) {
...
vad = rnnoise.inference(x); // x是单帧的音频数据(20ms帧长时就是长度为20*16的数组,读取x的过程可以参考RNNoise的例程)
...
}
...
}
因为我只需要vad推理的结果,不需要denoise的结果,所以把inference函数写成这样。如果需要denoise后的音频的话对inference函数做微调即可。如果不需要音频,只需要denoise的22个频带增益的话,需要修改一下src/denoise.c中rnnoise_process_frame函数,将最后对音频进行调整的步骤删掉,并且return出22个频带增益。
交叉编译
编译出动态链接库
因为rnnoise原始工程是使用工程根目录下的autogen.sh和configure文件进行编译,所以在运行configure的时候指定host=交叉编译链就好,运行完configure后再make一下,example文件夹中就会生成例程的rnnoise_demo可执行文件。
但由于我们是要做成接口并且对接口进行交叉编译,并且我不太会改configure文件里的内容,所以我另外写了个CMakeLists.txt (我只会用CMakeLists。。。),单独编译。
首先在工程根目录运行autogen.sh和configure,--host用于指定交叉编译链(注意不要加后面的“-gcc”或“-g++”),然后make。
./autogen.sh
./configure --host=aarch64-linux-gnu
make clean
make
然后进入src文件夹, 修改compile.sh,将gcc替换为我们的交叉编译链。
#!/bin/sh
aarch64-linux-gnu-gcc -DTRAINING=1 -Wall -W -O3 -g -I../include denoise.c kiss_fft.c pitch.c celt_lpc.c rnn.c rnn_data.c -o denoise_training -lm
然后运行compile.sh
./compile.sh
此时会发现工程根目录下出现了个.lib的隐藏文件夹,其中的librnnoise.so.0我们稍后会用到。
然后在工程根目录下创建一个CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(aaa)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(PATH ${PROJECT_SOURCE_DIR})
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O3 -Wall -g2 -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall -fPIC")
SET(CMAKE_BUILD_TYPE "Debug")
message(${PATH})
#RK3308
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
set(RNNoise_DIR /home/rua/rnnoise)
include_directories(${RNNoise_DIR}/examples)
include_directories(${RNNoise_DIR}/include)
include_directories(${RNNoise_DIR}/src)
add_library(rrnoise SHARED ${RNNoise_DIR}/examples/rnnoise_inference.cpp)
target_link_libraries(rrnoise ${RNNoise_DIR}/.libs/librnnoise.so.0)
老四连。
mkdir build
cd build
cmake ..
make
build目录下会出现librrnoise.so文件。
我们使用的时候需要用到build文件夹中的librrnoise.so文件,和前面生成的.lib文件夹中的librnnoise.so.0文件。
使用编译出的动态链接库进行推理
单独构建一个工程,目录如下
-
build:编译例程的可执行文件用。
-
data:存放测试用的音频文件。
-
include:存放一些乱七八糟的.h头文件。
-
lib:存放前文说到的两个动态链接库(librrnoise.so、librnnoise.so.0)。
-
src:存放例程。
首先将刚才RNNoise工程中include、src文件夹中所有的.h文件,和我们写的接口的rnnoise_inference.h文件通通复制进这里的include文件夹中。
接着把librrnoise.so、librnnoise.so.0复制进lib文件夹中。
然后在src文件夹中创建一个demo.cpp,编写例程代码(此过程省略)。
最后写CMakeLists.txt并且进行编译。
cmake_minimum_required(VERSION 3.10)
project(aaa)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(PATH ${PROJECT_SOURCE_DIR})
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O3 -Wall -g2 -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall -fPIC")
SET(CMAKE_BUILD_TYPE "Debug")
message(${PATH})
#RK3308
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
set(RNNoise_DIR /home/rua/rnnoisevad)
include_directories(${RNNoise_DIR}/include)
add_executable(demo ${RNNoise_DIR}/src/demo.cpp)
target_link_libraries(demo ${RNNoise_DIR}/lib/librrnoise.so)
编译后在build文件夹中出现可执行文件
随后把该可执行文件、lib文件夹中的两个动态链接库、我们需要处理的音频文件一起扔进板子里。
将两个动态链接库所在的路径添加进查找路径。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/.so
然后运行可执行文件即可。
标签:CMAKE,inference,RNNoise,编译,rnnoise,RK3308,include,KAWAKO From: https://www.cnblogs.com/KAWAKO/p/17074492.html