FFT in Snap!?

We would like to display the spectral composition of acoustic waveforms. One of our collaborators, Yuxin, has begun to look into the possibility of writing a Fast Fourier Transform (FFT) routine to do this.

However, we don't want to re-invent the wheel. Has anyone done this already?

Uhh... well, are you able to use this?
[scratchblocks]
(microphone [spectrum v] :: sensing)
[/scratchblocks]

Yes, we do make use of the Microphone [Spectrum] block.

However, the spectral analysis routine employed by that block can only be applied to new sounds captured by the computer's microphone. We don't know of a way of applying it to an existing sound sample that may have been imported into Snap! (for example).

Does this work?
[scratchblocks] ([samples v] of sound [ v] :: sound) [/scratchblocks]

@snapenilk We use the Samples of Sound block to play and display sounds. However, we're not aware of a spectral analysis routine in an existing Snap! library that can be used to analyze a sound sample. We wanted to check to see if this already existed before we begin to explore ways to construct an FFT routine in Snap!

I'm not sure, are you looking for a challenge or a solution?
There is a minimal example of Web Audio API and "analyser" to get FFT out of an array of samples.

For random noise and sawtooth wave, results look plausible (or, at least somehow depends on the data :smiley: ) but I have no reference data to fine-tune parameters and validate results.


Stage (4)

Also, parametrization is required.

Thanks for sharing the information. It seems to use Javascript function. We are actually trying to figure out if there is an existing FFT implementation made up of pure Snap! blocks.

@dardoro @yw7vv To follow up on Yuxin's comment (above), we have developed low-pass and high-pass acoustic filters in Snap! The graph below depicts the waveform for the phrase "One Two Three" before filtering (in light tan) and after a low-pass filter with a cutoff frequency of 100 Hz has been applied.

image

We would like to provide a way to display the spectral composition of the sound before and after filtering. If that could be done completely in Snap! that would be ideal. However, if that proves to be too complex, your suggestion of using the Web Audio API is a good one.

For anyone who would like to explore, here's a link to the low-pass filter:

There is a test project
The spectrum of "choir" sound is displayed.
Red is a spectrum of raw, unaltered samples.
Green is modified by the WebAudio Filter (low pass) script pic (1)
Blue is a result of the built-in Web Audio low-pass filter.
It seems that "Low Pass..." has a very low Q coefficient compared to built-in.
Stage (5)

2 s of 48KHz sound gives 90k samples. With the complexity of FFT O(n lg( n)) it requires 1.5x10^6 calculations. Even with some clever hyperblocks, performance may be an issue.

@dardoro That's cool. Thanks for the sharing. We will try to implement it in Snap! blocks. If it proves to be too complex, I think the Javascript function is also good. In order to implement it, we need to use complex number. Therefore, I just wonder if you have developed something that can generate complex number or used Screen Shot 2021-02-15 at 11.38.28 AM|666x122 to import complex number from JS.

Built-in Bignums library has support for complex numbers.
bignums

Cool, thanks! I will try it.

@dardoro @yw7vv The filter that Yuxin created is a first-order filter. This filter rolls off at a 20 dB drop in amplitude per decade.

The Web Audio low-pass filter is likely a more complex filter; hence, the difference in output.

Because we wanted our filter routine to be as accessible as possible for novices, we chose the simplest possible filter that we could construct. Hence the choice of the first-order filter.

The graph of spectral output that you posted illustrates why we think it would be helpful to include a spectral display along with the filter. As Yuxin explores various approaches, we'll follow up with posts in this strand.

Thanks for all of your assistance with this.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.