0

we have chirp signal starts from 50Hz and it goes up to 10Hkz with stationary noise mixed in the system output and would like to remove the stationary noise mixed with chirp and to retain original chirp signal(data) and any suggestions would be welcome using python, thanks.

filter/stationary noise reduction approach for the chirp signal (50hz to 10Khz) using python.

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
VJA
  • 33
  • 1
  • 6
  • try this on https://dsp.stackexchange.com/ – Christoph Rackwitz Jun 29 '23 at 08:50
  • if possible repeat measurements and do average. Are you measuring impulse response? – dankal444 Jun 29 '23 at 09:53
  • One approach to this would be to de-noise in the frequency domain. The magnitude spectrum of your signal will have a noisy baseline with sharp peaks at whatever the chirp is at that moment. Take sliding window FFTs and zero out the frequency bins below some threshold (should be easy to set since the chirp will be quite high above the noise floor. It isn't a perfect de-noiser, but it will help. There are lots of details to futz with to make it sharper---window size, overlap, etc. – dmedine Jun 30 '23 at 00:52

1 Answers1

1

Here is some code that demonstrates what I suggested in my comment:

import scipy.signal
import numpy as np
import matplotlib.pyplot as plt

t = np.linspace(0,5, 44100*5)
w = scipy.signal.chirp(t, f0=50, f1=10000, t1=5, method='linear')
mu, sigma = 0, .1
s = np.random.normal(mu, sigma,len(t))
sig = w+s
n = 0
win_len = 512
hop = 64
win = np.hanning(win_len)
denoised = np.zeros([len(t)])
while n<len(t):
    if n+win_len > len(t):
        # zero pad if we run out of samples
        input = np.zeros([win_len])
        end_pt = len(t)-n-1
        for i in range(0,end_pt):
            input[i]+=sig[n+i]
    else:
        input = sig[n:n+win_len]
    input = input * win # window the signal
    dft = np.fft.fft(input)
    mags = abs(dft)

    ft_idx = 0
    # zero out the bins that are only noise
    zero = np.zeros(1, dtype=complex)
    for m in mags:
        if m<40:
            dft[ft_idx] = zero[0]
        ft_idx +=1 
    output = win*np.real(np.fft.ifft(dft))/(win_len/hop)# since the input is real,
    # the idft of the fft will also be real
    # we must take care to also window the idft so
    # that the overlap add is smooth

    # take care not to overflow
    if n+win_len > len(t):
        end_pt = len(t)-n-1
        for i in range(0,end_pt):
            denoised[n+i]+=output[i]
    else:
        denoised[n:n+win_len] += output
    n+=hop
plt.plot(t[0:5000], sig[0:5000])
plt.plot(t[0:5000], denoised[0:5000])
plt.show()

Output: enter image description here

Obviously it is not perfect. For one thing, the signal we keep is both attenuated (due to the brute force thresholding in the magnitude spedtrum) and the peak amplitudes are warbly (a byproduct of the random noise that we keep in the bins we do not attenuate). More work would be needed to get rid of those effects.

dmedine
  • 1,430
  • 8
  • 25
  • Thank so much for your time and it was very much helpful to us, thank you. and we do also use the python function: reduce_noise() from noisereduce for stationary and non stationary noise reduction and it works for chirp as well but your input was much helpful to us, thank you – VJA Jul 12 '23 at 20:15