Make realtime Discrate fournier transform from i2S mic

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
zaord
Posts: 96
Joined: Fri Jan 31, 2020 3:56 pm

Make realtime Discrate fournier transform from i2S mic

Post by zaord » Tue Nov 09, 2021 4:18 pm

Hi ! :) ,
I have seen that you finish the i2s implementation. A lot of thanks to Mike (and maybe the others ) !
I am trying to compute the discrete fft continously while the signal is readed from i2s microphone.

Do you have any idea how to start with this ?
I would need to use uasyncia i exepect ?
I will use INMP441 MEMS i2s mic.
This is to make a beatting frequency meter (for accordions tuning) :)

Best regards

zaord
Posts: 96
Joined: Fri Jan 31, 2020 3:56 pm

Re: Make realtime Discrate fournier transform from i2S mic

Post by zaord » Fri Nov 12, 2021 3:46 pm

Do you think I could use this code exemple and adapt it to micropython ?
https://mzucker.github.io/2016/08/07/ukulele-tuner.html

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Make realtime Discrate fournier transform from i2S mic

Post by pythoncoder » Sat Nov 13, 2021 6:40 pm

That uses numpy which isn't available for MicroPython. However there is a micro version ulab which is based on numpy and which can do fft.

For instrument tuning I wonder if the Goertzel algorithm would be worth considering? See this forum thread.
Peter Hinch
Index to my micropython libraries.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

An alternative

Post by pythoncoder » Sun Nov 14, 2021 11:08 am

Another thought for instrument tuning.

If you collect a set of samples from the mic, remove any DC component, and multiply by a set of samples at the expected frequency, the result will contain sum and difference frequency components. This is like listening for the beat frequency between the off-key note and a correctly tuned instrument. Simple filtering will remove the f and 2*f components, leaving the beat frequency. You then just need a way to display the frequency of the remaining signal. Tune for zero frequency.

The thought being that this can be highly accurate.
Peter Hinch
Index to my micropython libraries.

zaord
Posts: 96
Joined: Fri Jan 31, 2020 3:56 pm

Re: Make realtime Discrate fournier transform from i2S mic

Post by zaord » Fri Dec 03, 2021 9:16 pm

Thanks you Peter for this clue.
My question here, is that I don't know really any target frequency.
In accordion tuning, you have 2 reeds (cantilever beams) one tuned and one is out of tune. Making those two working at the same time create the typical beat frequency of accordion.
The first thing to do is to tune the 1rst voice, and for that I use a stroboscopic tuner, which is really precize and nice.
Then the second sep is to have a very constant beatinf frequency over all the range, and for this I need to create a 'beating frequency meter' which could works over all the range (from 50 Hz to 2300 Hz )
So I don't know if Goertzel algorythm is ok ..
I was thinking about hilbert transform to get the enveloppe and trying to get the frequency of it, but I don't know.

If you have any idea, thanks by advance :)

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Make realtime Discrate fournier transform from i2S mic

Post by pythoncoder » Sat Dec 04, 2021 2:25 pm

This is more complicated than I realised. At risk of stating the obvious, if you add two sine waves of frequencies f1 and f2, the resultant output contains only f1 and f2. There is no component at f1-f2 or f1+f2. To get sum and difference components you need a nonlinear element.

To measure the difference frequency you could apply the waveform to a nonlinear circuit and filter out components at f1, f2, and f1+f2 - i.e. pass the output of the nonlinear element through a low pass filter. Obviously f1 and f2 vary over the range of the instrument so the LPF would be best implemented as a digital FIR or IIR filter with a variable clock rate.

An alternative, as you suggest, is measuring the envelope. This is another nonlinear process which can create a difference frequency, by producing a signal proportional to the instantaneous amplitude of f1+f2.

In practice the signals are not sinewaves so will have multiple harmonics: the difference frequency will contain other components e.g. m*f1 - n*f2 where m and n are integers. It would need some thought to figure out whether filtering these out was a practical proposition, given that the difference frequency is unknown (because that's what you want to measure).

An interesting problem.
Peter Hinch
Index to my micropython libraries.

zaord
Posts: 96
Joined: Fri Jan 31, 2020 3:56 pm

Re: Make realtime Discrate fournier transform from i2S mic

Post by zaord » Sun Dec 05, 2021 1:58 pm

Do you think is a good start to try to make this working with python and numpy , test it and then trying a implementation on micropython ?

zaord
Posts: 96
Joined: Fri Jan 31, 2020 3:56 pm

Re: Make realtime Discrate fournier transform from i2S mic

Post by zaord » Sun Dec 05, 2021 2:04 pm

From my old acoustic reaserch team when I was in engineering school, I get this :

Using this code to find the enveloppe (in python)
import numpy as np
from scipy.signal import hilbert
# x1 and x2 are the two audio sources
y = hilbert(x1+x2)
plt.plot(np.abs(y))

But then , how could I have the beating frequency ?
Best

zaord
Posts: 96
Joined: Fri Jan 31, 2020 3:56 pm

Re: Make realtime Discrate fournier transform from i2S mic

Post by zaord » Sun Dec 05, 2021 2:05 pm

Then if I need to have access to the fondamental frequencies of multiple harmonic sounds, they talk me abou Empirical Mode Decomposition (EMD), and Hilbert–Huang transform.
Do you have exeprience with whose methods ?

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Envelope extraction

Post by pythoncoder » Tue Dec 07, 2021 10:41 am

No, sorry.

Going back to first principles of AM radio detection you have a set of samples at N*Nyquist. If necessary remove any DC component (subtract the mean value) so your signal is symmetrical about 0. Invert all negative samples: this is the nonlinear detection process which produces a signal with a component at the modulation (envelope) frequency. Pass through a low pass filter to remove the 2*fundamental and you have your envelope.

While your signal isn't the same as an AM waveform I think this detection method should work. You might want to simulate it first to make sure.

All of these operations are simple and fast on a microcontroller.
Peter Hinch
Index to my micropython libraries.

Post Reply