0
$\begingroup$

I have a audio recording piece of an environment that contains multiple sounds, is there a way to separate the different frequencies or wavelengths of this signal with Python or matlab?

$\endgroup$

3 Answers 3

1
$\begingroup$

As Dan has already pointed out, Short Term Fourier Transform of STFT is the way to go here. However the devil is in the details. You need to pick a fair bit of parameters that need to be optimized for your specific application. FFT length, hop size, zero padding, window, Y-scale, dynamic range, etc.

For example, the picture in Dan's answer is pretty but not super useful since all fundamental frequencies are jammed into the lower 1cm of the graph. Frequency/pitch perception is inherently logarithmic, so a logarithmic Y scale (or Mel, or Bark scale if you want to get real fancy) would be better.

If you are new to this, I recommend spending some time with interactive tool, like Audacity (https://www.audacityteam.org/) to play around with the parameters and get a feel for what they do and how they map to the specific requirements of your application. Below is a screen shot.

enter image description here

$\endgroup$
1
$\begingroup$

For frequency-band isolation, you can use bandpass filters. A band-pass filter or bandpass filter (BPF) is a device that passes frequencies within a certain range and rejects (attenuates) frequencies outside that range.

Filters can be continuous-time, or discrete-time. If you want to implement these in an programming language or matlab, you have to use digital filters. Digital filters operate in discrete-time.

There are many ways for designing bandpass filters. You can design the bandpass filter(s) directly on the digital domain. Or, you can design a filter in the continuos time domain (which is the domain of analog filters), and transform it to a IIR digital filter using the Tustin method.

There are entire books on this subject. For keeping it short and straight, I'll share with you what I do.

First, design the analog filter. Choose the frequency of interest.

The s-domain function for a standard bandpass filter is given as following:

\begin{align} H(s) = \frac{A_o(\frac{s}{Q_p\omega_p})}{1+\frac{s}{Q_p\omega_p}+\frac{s^2}{\omega_p^2}} \end{align}

Where:

$ A_o $ = Gain (in times)

$ F_p $ = Frequency of the band-pass filter.

$ Q_p $ = Q Factor of the filter.

$ s = j\omega $

$ \omega = 2 \pi f $

$ \omega_p = 2 \pi f_p $

If you substitute $ s = j \omega $ you'll have the frequency response function $ H(j\omega) $. In the complex domain, with magnitude and phase. For example below is the frequency response of a filter with $ A_o = 1 $ , $ f_p = 1 KHz $ and $ Q_p = 1 $

Response of Q=1 Fp=1Khz, bandpass filter

Then apply the Tustin method. In the H function, do the following substitution:

\begin{align} s \leftarrow \frac{2}{T} \frac{z - 1}{z + 1} \end{align}

Where T is the sampling period. Reciprocal of the sampling frequency (tipically in digital audio is 48KHz)

As a result you'll have a $ H(z) $ function. Develop the function to have following rational function form.

\begin{align} H(z) = \frac{\sum_{k=0}^N b_k z^{-k}} {1 + \sum_{k=1}^M a_k z^{-k}} \end{align}

Find the coefficients b0, b1, b2, a1 and a2. These are all you need for implementing the digital filter.

Then, the filter output in the time domain, given a sampled and time domain signal, is:

\begin{align} y_n = b_0 x_n + b_1 x_{n-1} + \cdots + b_N x_{n-N} - a_1 y_{n-1} - a_2 y_{n-2} - \cdots - a_M y_{n-M} \end{align}

Where

$ y_n $ = filter output signal

$ x_n $ = filter input signal

Note that the filter output is calculated using both previous input and output values. That means IIR filters operate with feedback. Output values are used as later input values.

$\endgroup$
1
$\begingroup$

Yes, these are tools that are part of the scipy.fftpack library. You can use the scipy.fftpack.fft function to compute the Discrete Fourier Transform, which would show you the average of each frequency over the entire sound track. When the frequency content is changing with time (as is likely the case) this may not be as useful as the Short-Time Fourier Transform (STFT) and a spectrogram which is the squared magnitude of the STFT. The STFT is also available in Python as the scipy.fftpack.stft command.

Here is an example of the spectrogram from Wikipedia where we can see the squared magnitude of each frequency over short time segments on the vertical axis versus time on the horizontal axis:

spectrogram

Also consider the CWT as OverLord has detailed in this post and many others.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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