FFT filter

jebb's icon

Hello,

I want to do a patcher that takes, as input :
* a soundfile containing a constant pitch note (of pipe organ)
* its fondamental frequency f0 in an input box

It should give, as output :
* the signal which is obtained with the soundfile, by keeping only the harmonics (multiple frequencies) of f0.

Thanks a lot in advance, I don't know how to design this in Max/Msp.

jebb

PS : I.e. it will give something like the sinusoidal part of the sound (which is of constant pitch).

Floating Point's icon

SOunds like you need to do a dft rather than an fft. But I'm not aware of any dft externals that you could achieve this with.
You might be better off using a parallel array of bandpass filters, set at integer multiples of the fundamental, and analyse the amplitude of the signal coming out each filter, then resythesize using pure sine waves at those amplitudes.
T

jebb's icon

Hi, Thanks for the answer. I'm a bit lost, I don't know where to begin, with which objects ? If it doesn't take more than 2 minutes for you, would you build a small patcher and post it here as an attachment ?

Thanks a lot in advance
jebb

AlexHarker's icon

Hi,

1- @jebb - to do this properly is more than a couple of minutes work, so I haven't posted any response (you asked the same question in another thread more directly to me) - I've got a lot of other stuff on at the moment.

2 - @Terry McDermott - in what way are you distinguishing a DFT (discrete fourier transform) from an FFT (fast fourier transform). An FFT implements a fast algorithm to achieve a DFT.

(currently this is explained about 3 paras down).

Or (I suppose more obviously) in the first sentence here::

I ask because this distinction came up in another thread, and it could potentially confuse people as I cannot understand what you are getting at - if you mean something else from the abbreviations as I understand them (or something more specific), please clarify... thanks...

3 - @jebb

Try looking at the pfft~ and other related objects helpfiles - and working through the max tutorials - there a some on spectral processing somewhere - you'll probably need to look at several earlier tutorials before tackiling these...

Alex

MIB's icon

have you had a look at sigmund~? it has a sinusoid tracking function that might get you what you are after...

Floating Point's icon

"2 - @Terry McDermott - in what way are you distinguishing a DFT (discrete fourier transform) from an FFT (fast fourier transform). An FFT implements a fast algorithm to achieve a DFT."

I am probably being too esoteric, but I think that if you want to analyse a harmonic sound _and_ you know what the fundamental frequency of that sound is (and the sound does not change in pitch), then a DFT is more accurate than an FFT, because you are able to alter the window size to be the same length as the period of the fundamental (in FFT the window size must be a power of 2 in order for the algorithm to work) , and so the bins fall in line with the harmonics of the fundamental, and you get less artifacts... but perhaps any noise in the source signal would ruin this theoretical advantage... the conditions of the problem (organ pipes are harmonic and unchanging in pitch, and the fundamental is known) would lend itself to DFT (in the sense of its _difference_ from an FFT, not in the sense that the FFT is an implementation of the more general DFT)

But it's slow, and doesn't exist as far as I know as an external in Max, so probably shouldn't have mentioned it.

jebb, this https://cycling74.com/forums/smoothing-the-discontinuous-stepped-output-from-peakamp might guide you towards amplitude tracking-- I don't know if the amplitude tracking of parallel bandpass filter idea would be good enough for your needs, but it might work.
T

AlexHarker's icon

Thanks for the clarification - that makes sense now.

jebb's icon

Hello,
Thanks a lot for all the informations.

@MIB : unfortunately, sigmund~ is unavailable for windows

@TerryMcDermott and AlexHarker : when you speak about FFT filters or bandpass filters, do you mean :
1/ I do a FFT (or DFT), then I choose the "bins" corresponding to the multiple of fundamental, and then I resynthesize with sinosoids ?

or

2/ "standard" bandpass filters (like the one I can find in any DAW, as VST for example, with "curves", "Q", 12 or 24 or 48dB/oct, etc.)

?

Thanks in advance if someone has a couple of minutes for posting (even just a beginning of) a patcher ;)

AlexHarker's icon

A bandpass filter may be implemented in many ways. Some filters use recursive calculations in the time domain (IIRs - infinite impulse response), some use non-recursive calculations (FIR - finite impulse response).

It's impossible to know exactly what the filters in your DAW are -as they could work any way...

The characteristics of each are different. An FFT can be used to compute an FIR in an efficient manner - it also allows a simple method of filter design. If we multiply the contents of each bin with a coefficient, that coefficient corresponds to the gain of the filter at the bin frequency, and hence we see that the frequency response has the shape of the coefficients we specify (ie - we can directly specify the frequency response). The relationship of coefficients to frequency response in the time domain is much more complicated and hard to control.

In addition FIR filters implemented with an FFT (where we essentially convolve in the frequency domain with a real only valued signal - the desired frequency response) do not ring, and also have linear phase. These characteristics are desirable in a more 'surgical' kind of filter where we want to alter the character of the sound as little as possible save the modifications we wish to make.

In implementing a filter like this we need to create a smooth frequency response, with some tail off each side of each frequency we wish to keep in order to prevent distortion from so called brick-wall filtering (it sounds terrible).

This can be done in Max, but it takes a bit of time to construct the appropriate filter. The basic method is actually very easy, but putting together the filter response is the harder bit...

I wouldn't personally choose to resynthesize , as this is a very complex task, and achieving similar fidelity to the original will be very hard indeed. What I originally was getting at in the other thread, was that you *might* be able to get better noise reduction by using your prior knowledge of the sound to remove (or reduce) frequencies which you already know you are not interested in. Whether or not you will get noticeably better results I do not know for sure....

A.

jebb's icon

Thanks again for all these informations !

There is something that I don't understand. Partial tracking + resynthesis is a term very often mentionned about these subjects...

So it is very strange that I do not find anywhere any MAX/MSP patcher that shows a sinusoid tracking + sinusoid resynthesis.

Such algorithms should be available somewhere, don't you think so ? In Max? Pd ? Supercollider ? Some other language ?

Emmanuel Jourdan's icon

You might want to give a try to zsa.freqpeak~ from zsa.descriptors library which outputs a list of partials and amplitude.

Floating Point's icon

Here is some partial tracking software-- I think it's free and downloadable (I've never used it)
http://www.klingbeil.com/spear/

volker böhm's icon

> (in FFT the window size must be a power of 2 in order for the algorithm to work)

strictly speaking this is not true. while most implementations do depend on a power of 2 size (like fft~ and pfft~ in max) there are others, that don't have that limitation. so, "FFT itself" doesn't depend on power of 2 sizes.
e.g. FFTW is a library where arbitrary FFT sizes can be calculated.

jebb's icon

I'm still stuck on this problem.

To start with something easy, how would you that :
A filter that keeps only frequencies around f0, 2*f0, 3*f0, 4*f0, etc.
(ie a huge number of bandpass :) )

Would someone be able to do a quick patcher for this simple task ? Thanks really a lot in advance, because I'm stuck !

ztutz's icon

Take a look at the help page for fffb~, which implements your "huge number of bandpass" filters. If you use an H argument and don't connect the first outlet, you've got what you are asking for.