RNNoise Extension
About RNNoise
RNNoise is a noise suppression library based on a recurrent neural network written in C. You can find the source and more information at https://github.com/xiph/rnnoise.
Why use the RNNoise Extension instead of RNNoise directly?
- There is no need to think about low level C code, the RNNoise Extension supports most programming languages for mobile and desktop.
- You’ll be able to focus on the application features, the RNNoise Extension handles audio IO and scheduling for you.
- You’ll still have in depth access to the various audio processing layers if you need, in a neat and convenient way.
- Mix and match many well known third party audio libraries with RNNoise that are supported, without the need to convert audio formats.
About RNNoise Extension
The RNNoise Extension provides the following audio nodes for a Switchboard SDK audio graph:
Node | Description |
---|---|
NoiseFilterNode | Removes background noise from voice signal. |
Switchboard Editor example
Code Example
- JSON
- Swift
- Kotlin
- C++
- JavaScript
{
"nodes": {
{ "id": "audioPlayerNode", "type": "AudioPlayerNode" },
{ "id": "channelSplitterNode", "type": "ChannelSplitterNode" },
{ "id": "noiseFilterNode", "type": "RNNoise.NoiseFilterNode" },
{ "id": "monoToMultiChannelNode", "type": "MonoToMultiChannelNode" }
},
"connections": {
{ "sourceNode": "audioPlayerNode", "destinationNode": "channelSplitterNode" },
{ "sourceNode": "channelSplitterNode", "destinationNode": "noiseFilterNode" },
{ "sourceNode": "noiseFilterNode", "destinationNode": "monoToMultiChannelNode" },
{ "sourceNode": "monoToMultiChannelNode", "destinationNode": "outputNode" }
},
"tracks": {
"audioPlayerNode": "Noisy-Speech.wav"
}
}
import SwitchboardRNNoise
import SwitchboardSDK
class RNNoiseFilterExample {
let audioGraph = SBAudioGraph()
let audioPlayerNode = SBAudioPlayerNode()
let channelSplitterNode = SBChannelSplitterNode()
let noiseFilterNode = SBRNNoiseFilterNode()
let monoToMultiChannelNode = SBMonoToMultiChannelNode()
let audioEngine = SBAudioEngine()
init() {
audioGraph.addNode(audioPlayerNode)
audioGraph.addNode(channelSplitterNode)
audioGraph.addNode(noiseFilterNode)
audioGraph.addNode(monoToMultiChannelNode)
audioGraph.connect(audioPlayerNode, to: channelSplitterNode)
audioGraph.connect(channelSplitterNode, to: noiseFilterNode)
audioGraph.connect(noiseFilterNode, to: monoToMultiChannelNode)
audioGraph.connect(monoToMultiChannelNode, to: audioGraph.outputNode)
audioEngine.start(audioGraph)
audioPlayerNode.stream(Bundle.main.url(forResource: "Noisy-Speech", withExtension: "wav")!.path, withFormat: .wav)
}
}
import com.synervoz.switchboard.sdk.audioengine.AudioEngine
import com.synervoz.switchboard.sdk.audiograph.AudioGraph
import com.synervoz.switchboard.sdk.audiographnodes.AudioPlayerNode
import com.synervoz.switchboard.sdk.audiographnodes.ChannelSplitterNode
import com.synervoz.switchboard.sdk.audiographnodes.MonoToMultiChannelNode
import com.synervoz.switchboardrnnoise.audiographnodes.RNNoiseFilterNode
class RNNoiseFilterExample {
val audioEngine = AudioEngine()
val audioPlayerNode = AudioPlayerNode()
val channelSplitterNode = ChannelSplitterNode()
val noiseFilterNode = RNNoiseFilterNode()
val monoToMultiChannelNode = MonoToMultiChannelNode()
val audioGraph = AudioGraph()
init {
audioGraph.addNode(audioPlayerNode)
audioGraph.addNode(channelSplitterNode)
audioGraph.addNode(noiseFilterNode)
audioGraph.addNode(monoToMultiChannelNode)
audioGraph.connect(audioPlayerNode, channelSplitterNode)
audioGraph.connect(channelSplitterNode, noiseFilterNode)
audioGraph.connect(noiseFilterNode, monoToMultiChannelNode)
audioGraph.connect(monoToMultiChannelNode, audioGraph.outputNode)
audioEngine.start(audioGraph)
}
}
#include "AudioGraph.hpp"
#include "AudioPlayerNode.hpp"
#include "ChannelSplitterNode.hpp"
#include "MonoToMultiChannelNode.hpp"
#include "NoiseFilterNode.hpp"
using namespace switchboard;
using namespace switchboard::extensions::rnnoise;
class RNNoiseFilterExample {
public:
RNNoiseFilterExample() {
// Adding nodes to audio graph
audioGraph.addNode(audioPlayerNode);
audioGraph.addNode(channelSplitterNode);
audioGraph.addNode(noiseFilterNode);
audioGraph.addNode(monoToMultiChannelNode);
// Connecting audio nodes
audioGraph.connect(audioPlayerNode, channelSplitterNode);
audioGraph.connect(channelSplitterNode, noiseFilterNode);
audioGraph.connect(noiseFilterNode, monoToMultiChannelNode);
audioGraph.connect(monoToMultiChannelNode, audioGraph.getOutputNode());
// Starting the graph
audioGraph.start();
}
// Example method called by the audio processing pipeline on each buffer
bool process(float** buffers, const uint numberOfChannels, const uint numberOfFrames, const uint sampleRate) {
AudioBuffer<float> outBuffer = AudioBuffer<float>(numberOfChannels, numberOfFrames, false, sampleRate, buffers);
const bool result = audioGraph->process(nullptr, &outBuffer);
return result;
}
private:
AudioGraph audioGraph;
AudioPlayerNode audioPlayerNode;
ChannelSplitterNode channelSplitterNode;
NoiseFilterNode noiseFilterNode;
MonoToMultiChannelNode monoToMultiChannelNode;
};
// Change the import to reflect the location of library
// relative to this publically accessible AudioWorklet
import SwitchboardSDK from '../libs/switchboard-sdk/SwitchboardSDK.js'
class SwitchboardRnNoiseProcessor extends AudioWorkletProcessor {
constructor(options) {
super()
this.sampleRate = options.processorOptions.sampleRate
this.port.onmessage = (event) => this.onMessage(event.data)
}
sendMessage(message, transfer = []) {
this.port.postMessage(message, transfer)
}
onMessage(message) {
if (message.wasmArrayBuffer) {
const switchboardSdkConfigObject = {
extensions: [],
wasmBytes: message.wasmArrayBuffer,
}
this.configure(switchboardSdkConfigObject)
}
}
configure(sdkConfig) {
this.switchboard = new SwitchboardSDK()
this.switchboard.configure(sdkConfig).then((response) => {
this.constructAudioGraph()
})
}
constructAudioGraph() {
const inputChannelLayout = [1]
const outputChannelLayout = [1]
const maxNumFrames = 128
let audioGraph = this.switchboard.createAudioGraph(
inputChannelLayout,
outputChannelLayout,
maxNumFrames,
this.sampleRate
)
let noiseFilterNode = new this.switchboard.classes.NoiseFilterNode()
let audioGraphInputNode = audioGraph.getInputNode()
let audioGraphOutputNode = audioGraph.getOutputNode()
audioGraph.addNode(noiseFilterNode)
audioGraph.connect(audioGraphInputNode, noiseFilterNode)
audioGraph.connect(noiseFilterNode, audioGraphOutputNode)
audioGraph.start()
this.noiseFilterNode = noiseFilterNode
this.audioGraph = audioGraph
}
destruct() {
this.audioGraph.destruct()
this.noiseFilterNode.destruct()
}
process(inputs, outputs, parameters) {
return this.audioGraph.processGraph(inputs, outputs)
}
}
registerProcessor('SwitchboardRnNoiseProcessor', SwitchboardRnNoiseProcessor)
Download SDK Extension
You can download this SDK extension from our Downloads Page.
Visit the page to access the latest version and start integrating it into your project!