6

I'm working on a project to find the instantaneous frequency of a multicomponent audio signal in Python. I am currently using a Butterworth bandpass filter combined with scipy.signal.lfilter to extract around my desired frequency region. I then use the analytic signal (from scipy.signal.hilbert) to get the instantaneous phase, which can be unwrapped to give frequency.

As a relative novice to signal processing, I have two main questions:

  1. I have read that in many applications, it is preferable to use scipy.signal.filtfilt over scipy.signal.lfilter. Certainly when I apply filtfilt to my data, I get a significantly smoother looking instantaneous frequency signal. I would like to know the major differences between the two, bearing in mind that I would like to get an output which is as close to the "true" instantaneous frequency as possible.

  2. The instantaneous frequency data is nonstationary, which means that in some instances I must use a wider bandpass filter to capture all my desired data. This appears to introduce additional noise, and occassional instabilities, into my signal. Are there ways to deal with these kinds of problems, for example with a better designed filter?

EDIT

In response to flebool, below are some images of the data I am looking at. First, a comparison of filt and filtfilt: Comparison of <code>filt</code> and <code>filtfilt</code> Both the above signals have had the same Butterworth filter applied (although the filter function is different), followed by extraction of instantaneous frequency (which is what is plotted, as a function of time). filtfilt seems to shift and smooth the data. Is one of these signals a better approximation of the "true" signal?

Note that this graph shows just a subset of a particular signal.

Second, the effect of increasing the Butterworth filter size: Widening the filter This is for the same subset of data as figure 1. The legend shows the lower and upper bound for the filter, respectively (the red trace is the filt version of the data in figure 1).

Although it may not be clear here why I would use a larger pass band, in some instances the data may be located at various points between, say, 600 and 800Hz. It is here that I would require a broader filter design. You can see that additional noise enters the trace as the filter gets wider; I'd like to know if there's a way to optimise/improve my filter design.

allhands
  • 345
  • 1
  • 4
  • 12

2 Answers2

1

To your first problem I can't speak intelligently on but scipy is generally well documented so I'd start reading through some of their stuff.

To your second problem a better designed filter would certainly help. You say the data is "non-stationary," do you know where it will be? Or what kind frequencies it might occupy? For example if the signal is centered around 1 of 3 frequencies that you know a-priori you could have three different filters and run the signal through all 3 (only one giving you the output you want of course).

If you don't know have that kind of knowledge about the signal I would first do a wider BPF, then do some peak detection, and apply a more stringent BPF when you know where the data you would like is located

sedavidw
  • 11,116
  • 13
  • 61
  • 95
  • Thanks for your response. I have a general idea (to an accuracy of a few hundred Hz) of the frequency band occupied by a signal. The problem is that different signals occupy different breadths of frequency space. Some signals appear nonstationary, whereas others are more "regular". What I mean by this is that some signals have a narrow peak in their frequency distribution, but others tend to have a broad, or even multiple, peaks in the frequency distribution. It is the latter type of signal which seems to be causing me problems in terms of filter design. – allhands Jun 26 '13 at 08:57
  • allhands, it would be nice to see some data to get a better feeling of the problem. – gg349 Jun 26 '13 at 10:04
1

Some sparse comments:

1) On the top picture: I can't comment on what is best between filt and filtfilt, though the shift in frequency of filtfilt is worrying. You can obtain a similar result by applying a low-pass filter to the filt signal.

2) There isn't a "true" instantaneous frequency, unless the signal was specifically generated with a certain tone. In my experience unwrapping the phase of the Hilbert transform does a good job in many cases, though. It becomes less and less reliable as the ratio of noise to signal intensity grows.

3) Regarding the bottom picture, you say that sometimes you need a large bandpass filter. Is this because the signal is very long, and the instantaneous frequency moves around between 500 and 800 Hz? If so, you may want to proceed windowing the signal to a length at which the filtered signal has a distinct peak in the Fourier spectrum, extract that peak, tailor your bandbass filter to that peak, apply Hilbert to the windowed signal, extract the phase, filter the phase.

This is worth doing if you are sure the signal has other harmonics except noise and the one you are interested in, and it takes a while. Before doing so I would want to be sure the data I obtain is wrong.

If it is simply 1 harmonic + noise, I would lowpass+hilbert+extract instantaneous phase + lowpass again on the instantaneous phase

gg349
  • 21,996
  • 5
  • 54
  • 64
  • 1
    1) I think the freq shift of `filtfilt` may be related to `lfilter` causing a phase shift of 90 degrees. As `filtfilt` runs forwards then backwards along the signal, this shift is corrected. It would seem that the effect we are seeing is just a reduction in noise. 2) We do have a poor signal to noise ratio. 3) That is indeed why I sometimes require a large bandpass. The signal contains multiple harmonics of the frequencies you see above, some of which we require. That is why we use bandpass, not lowpass. However, could a combination of bandpass+hilbert+phase+bandpass work? – allhands Jun 27 '13 at 12:57
  • 1
    sure, if you have other harmonics at lower frequencies get rid of them, but do not apply the bandpass to the instantaneous phase, stick to a lowpass, because the dynamics of the instantaneous phase may be far slower. And if the signal is really noisy, your phase will have poor information and won't actually mean much – gg349 Jun 27 '13 at 14:50
  • Thanks for your response. The data we are obtaining at the moment appear to be what we'd expect (so I think we are doing a reasonable job in removing noise) - I was just looking for ways to perhaps improve on what we have. I will try lowpass filtering the instantaneous phase -- it seems that in any case (i.e. using `filtfilt` or adding another lowpass filter) some extra filtering will be required. Could you comment at all on the effects of repeated filtering on a signal? – allhands Jun 28 '13 at 09:23
  • 1
    To evaluate the instantaneous frequency you subtract adjacent values of the instantaneous phase from Hilbert, so that noise propagates in the subtraction operation. You also divide by the timestep size, which I guess is your sampling frequency. I would feel fine at low-pass filtering those timescales. – gg349 Jun 28 '13 at 10:07