A audio noise filter in JavaScript speech / non-speech classifcation

A few days ago I have written a small post about Reading Web Audio API with JavaScript. But no matter how silent I am acting on my working place, my computer is always producing the following noise.

JavaScript audio noise

I will try to create a small lightweight noise spectrum estimation and elimination filter in JavaScript that is based on the research of Quantile based noise estimation for spectral subtraction and Wiener filtering.

Noise spectrum estimation based on frame wise speech / non-speech classifcation

The following approach assumes that there are pure noise frames or speech plus noise frames and that the first frames are only noise. The unfilled or empty bars in the example below are representing the calculated noise.

JavaScript

Here is the JavaScript code behind the noise spectrum estimation based on frame wise speech / non-speech classifcation.

function snsNoiseFilter(alphaValue, betaValue) {
    this.alpha = alphaValue;
    if (this.alpha === undefined) {
        this.alpha = 1.8;
    }
    this.beta = betaValue;
    if (this.beta === undefined) {
        this.beta = 0.03;
    }
    this.noise;
    this.noiseSum = 0;
    var sumFunction = function(a, b) {
        return a + b;
    };

    this.getNoise = function(input) {
        if (this.noiseSum == 0) {
            this.noise = input;
            this.noiseSum = this.noise.reduce(sumFunction, 0);
            return this.noise;
        }
        var inputSum = input.reduce(sumFunction, 0);
        var xnr = inputSum / this.noiseSum;
        if (xnr > this.alpha) {
            return this.noise;
        }
        var oneMinusBetaFactor = 1 - this.beta;
        for (var i = 0; i < input.length; i++) {
            this.noise[i] = oneMinusBetaFactor * this.noise[i] + this.beta * input[i];
        }
        this.noiseSum = oneMinusBetaFactor * inputSum + this.beta * this.noiseSum;
        return this.noise;
    };
}

You just have to create a instance of snsNoiseFilter and can call getNoise with the given audio data from getByteFrequencyData function for example.

// Create analyser and check for navigator.getUserMedia navigator.getUserMedia = ( navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia ); var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); var source; var stream; var analyser = audioCtx.createAnalyser(); analyser.minDecibels = -90; analyser.maxDecibels = -10; analyser.smoothingTimeConstant = 0.85; analyser.fftSize = 128; var bufferLength = analyser.frequencyBinCount; var distortion = audioCtx.createWaveShaper(); var gainNode = audioCtx.createGain(); var biquadFilter = audioCtx.createBiquadFilter(); var convolver = audioCtx.createConvolver();
var noiseFilter = new snsNoiseFilter();
// Bind function readAudioData to navigator.getUserMedia if (navigator.getUserMedia) { navigator.getUserMedia( {audio: true}, function(stream) { source = audioCtx.createMediaStreamSource(stream); source.connect(analyser); analyser.connect(distortion); distortion.connect(biquadFilter); biquadFilter.connect(convolver); convolver.connect(gainNode); gainNode.connect(audioCtx.destination); readAudioData(); }, function(err) { console.log(err); } ); } else { console.log('UserMedia not supported on your browser'); }
var readAudioData = function() { requestAnimationFrame(readAudioData); var dataArray = new Uint8Array(bufferLength); analyser.getByteFrequencyData(dataArray); var noise = noiseFilter.getNoise(dataArray); console.log(noise); }
Next Previous