做成接口

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.shconfigure,--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

然后运行可执行文件即可。

【KAWAKO】RNNoise-将模型做成接口并交叉编译到RK3308上的更多相关文章

  1. 接口的多态使用; 接口应用实例:U盘、打印机可以使用共同的USB接口,插入到电脑上实现各自的功能。

    接口的多态使用 接口应用实例:U盘.打印机可以使用共同的USB接口,插入到电脑上实现各自的功能.

  2. ZBrush中如何把模型的细节映射到低模上

    我们在ZBrush®雕刻模型的时候,发现模型布线不利于雕刻,这使我们不得不对模型进行重建细分,而重建细分之后的模型细节已经没有了,这个时候我们就需要把原来高模的细节映射到新的模型上面. 接下来我们介绍 ...

  3. 【java高级编程】jdk自带事件模型编程接口

    事件类 java.util.EventObject java.beans.PropertyChangeEvent 事件监听接口 java.util.EventListener java.beans.P ...

  4. 手把手教你玩转SOCKET模型之重叠I/O篇(上)

    “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人.我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付 ...

  5. 【微信上传素材接口--永久性】微信永久性上传、获取返回的medie_id 和url

    上传图片到微信服务器获得media_id和url (永久性) 其他接口类:https://www.cnblogs.com/gjw-hsf/p/7375261.html 转载地址:https://blo ...

  6. Retrofit/Okhttp API接口加固技术实践(上)

    作者:Tamic 地址:http://blog.csdn.net/sk719887916/article/details/61914609 写这篇文章,我纠结了非常久,究竟是属于app安全系列,还是属 ...

  7. U811.1接口EAI系列之六--物料上传--VB语言

    1. 业务系统同步U811.1存货档案通用方法. 2.具体代码处理如下: 作者:王春天 2013-11-06 地址:http://www.cnblogs.com/spring_wang/p/34098 ...

  8. Maven+TestNG+ReportNG/Allure接口自动化测试框架初探(上)

    转载:http://www.51testing.com/html/58/n-3721258.html 由于一直忙于功能和性能测试,接口自动化测试框架改造的工作被耽搁了好久.近期闲暇一些,可以来做点有意 ...

  9. 小数运算需要注意什么? 接口和抽象类 WinForm窗体上两个panel,怎么实现一个panel固定漂浮在另一个panel之上

    小数运算需要注意什么? 1. 生活中0.1+0.2=0.3, 计算机中可不是这样,为什么呢? 大家都知道计算机类型都是有数据范围的.整形int范围是 正负21亿左右,小数类型同样也是有范围的,但是即使 ...

  10. python脚本实现接口自动化轻松搞定上千条接口用例

    接口自动化目前是测试圈主流的一个话题,我也在网上搜索了很多关于自动化的关键词,大多数博主分享的python做接口自动化都是以开源的框架,比如:pytest.unittest+ddt(数据驱动) 最常见 ...

随机推荐

  1. Devexpress 图表显示数据标签

    dev的图标功能非常强大其中有一些设置可以更好的展现出数据 设置Series的标签 series.LabelsVisibility = DevExpress.Utils.DefaultBoolean. ...

  2. Mybatis-plus多数据源 + 数据库连接明文加密

    核心依赖 <!--mybatis-plus 核心组件--> <dependency> <groupId>com.baomidou</groupId> & ...

  3. 树莓派编译opencv4

    前言 我用的是 树莓派3b 编译的 opencv4.1.0,如果不想编译可以直接下载我编译好的. 下载地址 直接 make install,或者按照我后续步骤复制动态链接库. 准备 需要调节虚拟内存大 ...

  4. 浏览器直接修改网站的js代码

    1.按下F12打开控制台,找到源代码,然后是替换 2.在本地创建一个文件夹,会提示风险,点击允许 3.再找到你要修改的js文件代码,右击选择保存并覆盖 这样代码会保存到你刚刚创建的本地文件夹当中,接着 ...

  5. 监控Kubernetes集群证书过期时间的三种方案

    前言 Kubernetes 中大量用到了证书, 比如 ca证书.以及 kubelet.apiserver.proxy.etcd等组件,还有 kubeconfig 文件. 如果证书过期,轻则无法登录 K ...

  6. loadrunner11汉化时提示模块插件无法注册的解决方法

    安装汉化程序时,关闭杀毒软件.

  7. 基于.NetCore开发博客项目 StarBlog - (21) 开始开发RESTFul接口

    前言 最近电脑坏了,开源项目的进度也受到一些影响 这篇酝酿很久了,作为本系列第二部分(API接口开发)的第一篇,得想一个好的开头,想着想着就鸽了好久,索性不扯那么多了,直接开写吧~ 关于RESTFul ...

  8. cs231n__4.2 神经网络 Neural networks

    CS231n 学习笔记 4.2 神经网络 Neural networks 之前我们已经使用了 很多线性分类函数 现在我们不用单变换的: 我们首先有线性层,然后有这个非线性计算,继而在顶层再加入另一个线 ...

  9. 第三章 --------------------XAML的属性和事件

    1.XAML注释是什么样子的? 在之前的章节有提起过,但是这一节我还是想系统的学习XAML,XAML的注释如下 <!-- //这其中填写注释 --> Notice:在注释的部分编译器是不编 ...

  10. [深度学习] imgaug边界框增强笔记

    imgaug边界框增强笔记主要是讲述基于imgaug库对目标检测图像的边界框进行图像增强.本文需要掌握imgaug库的基本使用,imgaug库的基本使用见[深度学习] imgaug库使用笔记. 文章目 ...