3
$\begingroup$

This is my first question at this site, please excuse me if I'm not asking the question properly.

I have an acoustic signal of a test and I want to remove the "thin" peaks, because they don't really affect the structure that I'm studying. For that I've thought of a Low pass filter in order to retain only frequencies below 300 Hz.

My aim is to count the peaks of the filtered signal above 3 sigma (Standard Deviation). I'm programming in C# and I don't know if there is a direct (and simpler way) of doing this but what I'm doing now is

  1. Discrete Fourier Transform to my signal (SPL/s -> SPL/Hz)

  2. rescale what I obtain (bins = sampling frequency)

  3. Cut frequencies above 300 Hz

  4. Inverse DFT

It seems logical to me but I'm not sure if I'm doing it correctly. I have this little problem while doing the FT, is that I don't know how to scale properly the magnitude axis (y): if I transform and then I do the inverse transform I don't get the original signal but an attenuated one. What's happening here?

And my other question is about the symmetric nature of a FT. If I do a Fourier Transform to my signal I get a mirrored spectrum that goes till 8000 Hz, can I simply cut at my desired frequency (is what I'm doing now)? Thanks for your time.

$\endgroup$
5
$\begingroup$

I have an acoustic signal of a test and I want to remove the "thin" peaks, because they don't really affect the structure that I'm studying. For that I've thought of a Low pass filter in order to retain only frequencies below 300 Hz.

If this is accurate, that is, you have an acoustic signal that exists from baseband to 300 Hz, then yes, what you want to do is a digital low-pass filtering operation to retain all energy below 300 Hz, and discard energies above that.

My aim is to count the peaks of the filtered signal above 3 sigma (Standard Deviation). I'm programming in C# and I don't know if there is a direct (and simpler way) of doing this but what I'm doing now is

Your intuition is correct - you want to remove frequencies below 300 Hz, so naturally you think to transform your signal into the Fourier domain, clobber unwanted frequencies, and then transform back. There are some issues with this method:

  • Firstly, this method is taboo in the DSP community, (and for decent reasons), although there are cases where you can get away with it, depending on your application. Some background: Nulling out unwanted co-efficients in a transform domain and inverse transforming back into the original domain is used in denoising especially in wavelets, and it also makes intuitive sense, (and correctly so). The problem with doing this in the Fourier domain is that the basis function of the DFT are global, and not local like they are in wavelets. In other words, you can clobber our wavelet co-efficients and affect only local areas in your signal (ie, small parts of your signal) - but doing so in the Fourier domain affects all your signal.
  • Expanding on the above background, when you "boxcar" your frequency domain, (ie, mask it with 1s and 0s that either allow or disallow certain frequencies), this is the same as convolving your time-domain signal with a sinc function, that carries on forever. This is why simply culling out unwanted frequencies - while acceptable in some applications - will introduce 'ringing/smearing' in the time domain.
  • Instead what is usually done, is that people create filters (masks in the frequency domain that are not sharp 1s and 0s, but more graceful), such that their equivalent transform back into the time-domain does not have the effective infinite extent of sinc function, (that is, the decay of the sidelobes is much faster than that of a sinc). This then provides a nice trade-off between removing unwanted frequencies, and not having to pay the price of extreme ringing/smearing in the time domain.

Armed with this task at hand, what you need to do is the following:

  • Create a digital low pass filter in some other software such as MATLAB or Python. You can create a simple FIR filter for your purposes. (Do not use an IIR because you are working with an audio application and default IIR filters will warp your phase, but thats another story). When you make your filter, you will simply have a vector of numbers, of a length you chose. The larger the length of the filter, the sharper the transitions in the frequency domain, but also the larger the delay, so this is a trade-off you can experiment with. At the end of the say though, you will $1$ by $N$ vector of numbers. This is your filter. Let us call it $h[n]$
  • You have your audio signal, let us call that $s[n]$. The planets are not aligned, so most likely your audio signal is of a different length than your filter, and let us say it is of length $M$. So your signal $s[n]$ is simply a $1$ by $M$ vector of numbers.
  • Your objective is to filter $s[n]$ by $h[n]$. There are a number of ways to do this. Since you already seem to have access to the FFT in C#, we will use the FFT method. In the FFT method, you want to multiply the Fourier transform of your filter, (call it $H(f)$), with the Fourier Transform of your signal, (call it $S(f)$).
  • We doing a linear convolution, (as opposed to a circular one), but in the frequency domain, so we have to take extra care when it comes to FFT sizes. If you did the linear convolution in the time domain, the resulting filtered signal would be of length $N + M -1$. This is then the FFT size you need to use.
  • You are almost done. All you need to do now is take the $N+M-1$ length FFT of your filter, $h[n]$. Take the $N+M-1$ length FFT of your signal, $s[n]$. Multiply them together. Then take the $N+M-1$ length IFFT of this element-by-element product, and viola, you have filtered your signal.

Hope this helped.

$\endgroup$
  • $\begingroup$ Thank you so much for your time. It's a lot of information to digest so I will re-read this a couple of times the next days. $\endgroup$ – Sturm Aug 7 '13 at 23:14
2
$\begingroup$

Is there any specific reason as to why you implement your low-pass filter using an FFT? Unless you have some good reasons for doing the FFT direct filtering will be easier for you I think. I also believe it will be significantly more efficient computationally.

With regards to your FFT->iFFF scaling issue, can't you see if it is a fixed scaling that is not accounted for? If this is not the case it might be an issue with the way you provide your arguments to the FFT or some other issue that is hard to figure out unless you provide example code.

There is also an issue with the way you implement the low-pass filter. You can't just zero out the bins and do an inverse IFFT. Maybe it will work for you but your output is time-aliased (your circular convolution wraps around).

Anyway much more info on how you to the FFT filtering would help in providing more useful feedback.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.