做成接口

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. JS基础笔记合集(1-3)

    JavaScript合集 1. JS入门基础 2. JS数据类型 3. JS运算符 4. JS流程控制 5. JS对象 6. JS函数 7. JS面向对象 8. JS数组 9. JS内置对象 我追求理 ...

  2. TCP\UDP协议 socket模块

    目录 传输层主要协议 TCP协议 三次握手 TCP协议反馈机制 四次挥手 洪水攻击 UDP协议 socket模块 socket代码简介 socket.socket() server.bind() se ...

  3. Jmeter之逻辑控制器---while控制器

    while控制器与编程语言中的while语句一样,当条件为真时继续执行,不为真时则跳出while循环体,不再执行. while控制器相对于循环控制器来说多了个条件判断,下面为while控制器使用案例. ...

  4. MySql索引下推知识分享

    作者:刘邓忠 Mysql 是大家最常用的数据库,下面为大家带来 mysql 索引下推知识点的分享,以便巩固 mysql 基础知识,如有错误,还请各位大佬们指正. 1 什么是索引下推 索引下推 (Ind ...

  5. FPGA:乒乓球比赛模拟机的设计

    简介 开发板:EGO1 开发环境:Windows10 + Xilinx Vivado 2020 数字逻辑大作业题目 7: 乒乓球比赛模拟机的设计 乒乓球比赛模拟机用发光二极管(LED)模拟乒乓球运动轨 ...

  6. 如何用 Python 隐藏你的 API 密钥

    你好,我是悦创. 博客首发:https://bornforthis.cn/posts/19.html 有时您需要在代码中存储敏感信息,例如密码或 API 密钥,而在 Python 中最简洁的方法是使用 ...

  7. 树形 dp 与树上问题

    NFLS 集训笔记 20220802 - 树形 dp 进阶与树上问题综合 \(\text{By DaiRuiChen007}\) I. 洛谷[P2585] - 三色二叉树 \(\text{Link}\ ...

  8. 【Redis技术专区】「优化案例」谈谈使用Redis慢查询日志以及Redis慢查询分析指南

    前提介绍 本篇文章主要介绍了Redis的执行的慢查询的功能的查询和配置功能,从而可以方便我们在实际工作中,进行分析Redis的性能运行状况以及对应的优化Redis性能的佐证和指标因素. 在我们5.0左 ...

  9. 微机原理与系统设计笔记2 | 8086CPU结构与功能

    打算整理汇编语言与接口微机这方面的学习记录.本部分讲解8086CPU的结构和基本功能以及特性. 参考资料 西电<微机原理与系统设计>周佳社 西交<微机原理与接口技术> 课本&l ...

  10. py之赋值,选择判断

    赋值机制 赋值之后:变量的地址就会指向同一个地址 a=123123 b=a id(a) id(b) 字符串是不论有多长内容一样地址一样 a='sadasd' b='sadasd' id(a) id(b ...