Recursive Moving Average Filter

Python. I implemented the recursive moving point average filter to clean background noise of test some audio files. It basically works in time domain. That’s way, it is more faster than FFT algorithms when we keep point number is small enough. It is very basic and works very fast. It is very optimal filter for some audio types such as telephone or normal speech to clean background noise. However, it is not good for musical instruments with many harmonics such as strings. When I tested this implementation with a string sound, it lost its some of properties. I will do more some experimental implementations based on this technique later on.

import os
import numpy as np
import scipy.io.wavfile as wavfile
 
def MovingAverageFilter(fileName, N = 7):
 
    #Moving point number has to be an odd positive integer, not too big
    #fs: sampling rate of the wav file, x: integer point array

    if (N % 2 == 0 or N > 19):
        raise ValueError("Please check moving point number")
        
    if (os.path.isfile(fileName) == False):					
        raise ValueError("Input file is not valid")
            
    fs, x = wavfile.read(fileName)

    #We only accept mono and 44.1khz audio files for this implementation  
    
    if (len(x.shape) != 1):                                  
            raise ValueError("Audio file is not mono")
    if (fs != 44100):                                        
            raise ValueError("Sampling rate of input sound is not 44100")
            
    size_x = len(x)
    noised_x = x + np.random.normal(loc = 0., scale = 30., size = size_x) 

    y = np.zeros((size_x), dtype = float)         #output signal
    segment = int((N - 1) / 2)                    #for symmetric averaging   
    accValue = 0                                  #recursive accumulation
    
    for i in range(N + 1):
        accValue = accValue + noised_x[i]
    y[segment] = accValue / N                     #moving average midpoint
    
    for j in range(segment, size_x - segment):
        accValue = accValue + noised_x[j + segment] - noised_x[j - (segment+1)]
        y[j] = accValue / N   
    
    difference = noised_x - y                     #for losing properties
    
    wavfile.write("Noised-Audio.wav", 44100, noised_x.astype(np.int16))
    wavfile.write("Cleaned-Audio.wav", 44100, y.astype(np.int16))
    wavfile.write("Difference-Audio.wav", 44100, difference.astype(np.int16))
    
    return

#Run it with your test audio file 
MovingAverageFilter('C:/Users/[yourname]/Desktop/test.wav')
[1] Advanced Digital Signal Processing and Noise Reduction, Saeed V. Vaseghi

[2] The Scientist and Engineer’s Guide to Digital Signal Processing, Steven W. Smith

[3] Signal Smoothing Algortihms