RNNoise的编译与集成

RNNoise 擅长处理风扇声、电流声、键盘声、空调声这类"非语音噪声",我们可以使用RNNoise消声降噪,减少噪音对录音的影响,本篇博客介绍rnnoise编译与android studio工程的集成

1.源码拉取

复制代码
git clone https://github.com/xiph/rnnoise.git rnnoise-main

刚拉取的源码一定缺少如下两个文件

复制代码
src/rnnoise_data.h
src/rnnoise_data.c

这个时候需要进入到rnnoise-main目录下,执行如下指令

复制代码
$hash = (Get-Content .\model_version).Trim()
$url = "https://media.xiph.org/rnnoise/models/rnnoise_data-$hash.tar.gz"

Invoke-WebRequest -Uri $url -OutFile "rnnoise_data-$hash.tar.gz"
tar -xzf "rnnoise_data-$hash.tar.gz"

执行完毕后确认文件的存在

复制代码
rnnoise-main\src\rnnoise_data.h
rnnoise-main\src\rnnoise_data.c

2.源码集成

Android Studio 不一定直接跑 RNNoise,更常见做法是把 RNNoise的src/、include/ 放进app/src/main/cpp/,自己写 CMakeLists.txt

配置CMakeLists.txt, 把src/rnnoise_data.c和src/rnnoise_tables.c加上

复制代码
cmake_minimum_required(VERSION 3.22.1)

project("rnnoise_jni")

add_library(
        rnnoise_jni
        SHARED

        native-lib.cpp

        src/denoise.c
        src/rnn.c
        src/pitch.c
        src/kiss_fft.c
        src/celt_lpc.c
        src/nnet.c
        src/nnet_default.c
        src/parse_lpcnet_weights.c
        src/rnnoise_tables.c
        src/rnnoise_data.c
)

target_include_directories(
        rnnoise_jni
        PRIVATE
        include
        src
)

target_link_libraries(
        rnnoise_jni
        android
        log
        m
)

build.gradle里面启用CMake

复制代码
android {

...........................................................

    defaultConfig {
        ..................................................

        //设置架构
        ndk {
            abiFilters "arm64-v8a", "armeabi-v7a"
        }
    }

    // 配置CMakeLists.txt
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
        }
    }

.............................................................

}

配置CMakeLists.txt,设置架构,要生成aar给多个工程调用,就得把RNNoise 做成Android Library模块,不要再绑定MainActivity。

app模块改成library模块,把 app/build.gradle的插件改成 library

复制代码
plugins {
    id 'com.android.application'
}

改成

plugins {
    id 'com.android.library'
}

删掉

applicationId "xxx"

AndroidManifest.xml只剩一个空壳

复制代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">


</manifest>

新增 RNNoise.java

复制代码
package com.yang.rnnoise;

public class RNNoise {
    static {
        System.loadLibrary("rnnoise_jni");
    }

    private RNNoise() {
    }

    public static native int getFrameSize();

    public static native long createDenoiseState();

    public static native void destroyDenoiseState(long handle);

    public static native float processFrame(long handle, float[] input, float[] output);
}

RNNoise.java用于给第三方调用,System.loadLibrary("rnnoise_jni") 必须和 CMake 里的库名一致

执行编译指令

复制代码
.\gradlew assembleRelease

生成的aar在app/build/outputs/aar/app-release.aar目录,将aar集成到第三方应用就可以调用了

复制代码
import com.yang.rnnoise.RNNoise;

int frameSize = RNNoise.getFrameSize();
long handle = RNNoise.createDenoiseState();

float[] input = new float[frameSize];
float[] output = new float[frameSize];

float vad = RNNoise.processFrame(handle, input, output);

RNNoise.destroyDenoiseState(handle);