做成接口

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. 【实时数仓】Day00:数据流程、课程内容、框架结构、知识点总结

    一.数据流程 1.离线数仓 2.实时数仓 二.课程内容 1.数据采集层(ODS) 2.DWD层与DIM层数据准备 3.DWM层业务实现 4.DWS层业务实现 5.ClickHouse 6.数据可视化接 ...

  2. <三>function函数对象类型的应用示例

    std::function是一组函数对象包装类的模板,实现了一个泛型的回调机制.function与函数指针比较相似,优点在于它允许用户在目标的实现上拥有更大的弹性,即目标既可以是普通函数,也可以是函数 ...

  3. 《HTTP权威指南》– 7.缓存

    Web缓存的概念 Web缓存是可以自动保存常见文档副本的HTTP设备. 使用缓存的优点: 减少了数据的数据传输,节省了网络费用: 缓解了网络瓶颈的问题,不需要更多的带宽就能更快地加载页面: 降低了原始 ...

  4. nuxt之vuex的使用

    先来了解一下官网:https://www.nuxtjs.cn/guide/vuex-store 一.首先在 store 文件下新建一个index.js文件 const state = () => ...

  5. 【机器学习】李宏毅——Domain Adaptation(领域自适应)

    在前面介绍的模型中,一般我们都会假设训练资料和测试资料符合相同的分布,这样模型才能够有较好的效果.而如果训练资料和测试资料是来自于不同的分布,这样就会让模型在测试集上的效果很差,这种问题称为Domai ...

  6. TiDB上百T数据拆分实践

    背景 提高TiDB可用性,需要把多点已有上百T TiDB集群拆分出2套 挑战 1.现有需要拆分的12套TiDB集群的版本多(4.0.9.5.1.1.5.1.2都有),每个版本拆分方法存在不一样 2.其 ...

  7. Linux基础:ssh与scp

    登陆 登陆服务器 ssh user@hostname user: 用户名 hostname :IP地址或域名 第一次登陆会提示 The authenticity of host '123.57.47. ...

  8. Mac对文件夹加密

    一.打开磁盘工具 电脑左上角文件->新建映像->基于文件夹新建映像->选择相对应的文件夹,进行aes加密->输入加密密码 然后保存文件就好了

  9. 小H的小屋

    题解 [NOI2004]小H的小屋 前记 又鸽了好久,这回可要努力更新了 2019.6.2,痛下杀心,把电脑上所有的游戏都删掉了,提前160天奋力备考NOIP.目标:A类省队! 我是传送门 题解 这道 ...

  10. GIS数据下载合集:遥感、土壤、气象、行政区数据...

      本文介绍GIS领域相关的各类综合数据免费获取网站,包括遥感数据.气象数据.土地数据.土壤数据.农业数据.行政区数据.社会数据.经济数据等等.   数据较多,大家可以直接通过下方目录加以总览:点击数 ...