Noise Filtering
About Noise Filtering
Noise filtering is an essential aspect of voice communications applications. It involves the removal of unwanted sounds or noise from the audio signal, which can interfere with the clarity and quality of the voice communication. Noise can come from various sources, such as background sounds, electronic interference, or even the speaker's own voice. Noise filtering algorithms use various techniques to identify and remove these unwanted sounds, such as spectral subtraction, adaptive filtering, and wavelet analysis. The goal of noise filtering is to improve the intelligibility and quality of the voice communication, making it easier for the listener to understand the speaker's message.
Switchboard Editor example
This example plays an audio file that contains speech with noise in the background and removes the noise using the RNNoise NoiseFilterNode.
This example uses the RNNoise Extension.
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(context: Context) {
val audioEngine = AudioEngine(context)
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->processBuffer(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)