Image file of Frequency Analyisis

Short version:
Does anyone know to generate an image file of the frequency analysis of an audio file? Bonus points for bulk exporting a folder’s worth of files.

Basically, I want to make the right half (or the whole thing) of this image:

AKWF_0014

Long version:
I’ve started playing with the Adventure Kid Single-cycle waveforms for wavetable synthesis on my Deluge:

Fun stuff. Given there’s some 4000+ of them, I wanted to make a little printed reference for myself so I had a rough idea of what they each sounded like as opposed to randomly scrolling through all of them, so I started laying out a PDF reference in InDesign using the visual guide on AK’s site:

https://www.adventurekid.se/AKRTfiles/AKWF/view/waveforms_index.html

Easy enough so far. The only bummer is that it seems all of the images in the ‘stereo’ folder are missing, which is quickly turning out to be one of my fav set of waveforms. So, I figured I would try and figure out a way to make my own image files of them. I got as far as using an app called TwistedWave to bulk export images of all the waveforms. But I can’t find any options for generating the frequency analysis images. I went down the timewarp zone and installed Audacity and I can generate a screen capture of the Frequency Analysis window, but doing that for 200 files is not exciting.

Any ideas on app that can do this? Or what app was originally used to generate those images?

Also, let me know if anyone wants the PDF when I’m done, ha.

I’m not sure of a stand alone app, but you could use a programming language like Python for example, to generate the amplitude of the Fourier transform (the spectrum) of each wave in a folder.

1 Like

Yeah, I saw a couple things on github, but they were feeling over my head. :slight_smile:

This is how I would do it.

https://trac.ffmpeg.org/wiki/Waveform

1 Like

That creates waveforms, not the frequency analysis chart, right?

This one is pretty simple, fast, and works reliably. I’ve used it on tens of thousands of files.

That said, the FFMPEG option looks pretty sweet. :slight_smile:

2 Likes

Doh! Yes, you are correct, but ffmpeg has different filters that can make a spectrogram. My google fu is not fast enough for me this morning and I gotta hit the road, but I did stumble on this:

2 Likes

Here’s the appropriate ffmpeg filter. A little more googling and you can probably find an example for the command line.
https://ffmpeg.org/ffmpeg-filters.html#showspectrumpic

and it looks like this thing can also make spectrogram images:
http://sox.sourceforge.net/Main/HomePage

So, there’s several different ways to accomplish this.

2 Likes
2 Likes

@bpcmusic
Great little app, unfortunately it only outputs waveforms not a Frequency Analysis chart

@jasonw22 @red
Thanks a bunch for these suggestions. I checked out ffmpeg, sox, and librosa and they all output spectrograms, but I’m looking for a frequency analysis chart not a spectrogram

So, something that looks more like this:

And less like this:

But seriously, appreciate all the suggestions so far! :smile:

2 Likes

That purple image you posted? It’s a spectrogram! I think you just need to tweak your parameters until you get the image you’re looking for.

Ha, I was afraid you might say that! :wink: OK, I’ll keep bopping around with those gits, I don’t think sox is gonna do it.

I really do think ffmpeg is what you want.

Here’s a really long video where ffmpeg generated a spectrogram for the entire audio file:

I don’t remember the command line parameters, because I found them on the web. But they made use of the showspectrumpic filter in ffmpeg.

1 Like

OK, I did it. Took quite a bit of trial and error, and you may want to tweak things further. Especially “scale=lin” in the first script. You might like “scale=log” better. Refer to the ffmpeg filters documentation to see what’s possible.
https://ffmpeg.org/ffmpeg-filters.html#showspectrumpic

AKWF_spectrographs.zip (253.0 KB)

I wrote this little shell script (there’s probably a more clever unix-y way to do this, but I was feeling lazy).

for i in ~/Music/AKWF/AKWF_stereo/*.wav;
  do name=`echo $i | cut -d'.' -f1`;
  echo $name;
  ffmpeg -i "$i" -lavfi showspectrumpic=s=1980x1040:orientation=horizontal:color=fiery:legend=disabled:scale=lin:mode=separate "${name}.jpg";
done

Then I had to scale it down (for some reason the spectrographs looked totally wacked if created at the smaller size to begin with).

for i in ~/Music/AKWF/AKWF_stereo/*.jpg;
  do name=`echo $i | cut -d'.' -f1`;
  echo $name;
  ffmpeg -i "$i" -vf scale=w=iw/10:h=ih/10 "${name}-resized.jpg";
done

Flip it vertically (it was upside down, to my eyes)

for i in ~/Music/AKWF/AKWF_stereo/*-resized.jpg;
  do name=`echo $i | cut -d'.' -f1`;
  echo $name;
  ffmpeg -i "$i" -vf vflip "${name}-flipped.jpg";
done

Make it grayscale (there is no gray color palette for the spectrographs for some reason)

for i in ~/Music/AKWF/AKWF_stereo/*-flipped.jpg;
  do name=`echo $i | cut -d'.' -f1`;
  echo $name;
  ffmpeg -i "$i" -vf format=gray,format=yuv422p "${name}-desat.jpg";
done

Invert the colors (so it is black on white instead of white on black)

for i in ~/Music/AKWF/AKWF_stereo/*-desat.jpg;
  do name=`echo $i | cut -d'.' -f1`;
  echo $name;
  ffmpeg -i "$i" -vf lutrgb="r=negval:g=negval:b=negval"  "${name}-invert.jpg";
done
2 Likes

Ha, we are both hacking this at the same time. Looks like you got a bit further than me, my linux/terminal skills are amateur at best. Gonna take a peek at these! Thanks!

1 Like

Pretty sure that someone is about to tell me that mine are as well! :wink:

i’m gonna be the nerd that tries to clarify terminology.

although the term is kinda generic, common usage of “spectrogram” is for an image of the spectrum over time - that is, taking periodic snapshots of the spectrum with a sliding analysis window (STFT), and rendering the result as a heatmap or waterfall (in three dimensions.)

what the OP wants is perhaps most clearly described as a spectrum plot. that is, taking a single DFT of the entire signal and plotting the bin amplitudes (in two dimensions.) this is a less common use case because it really only makes sense for very small slices of time like single waveforms.

ffmpeg only produces spectrograms.

i’m afraid i can’t think of an accessible, batchable tool to make spectrum plots of signals. as pointed out, it is an easy thing to code up in any environment with access to FFT and bitmap generation libraries. librosa has a builtin function, but it requires NumPy and getting that set up is maybe a little much for the casual python user.

sox stat -freq is close to what you want, but is hardcoded to use a 4096-point DFT. for longer samples it performs repeated DFTs. a shell-only solution could process the [freq, amp] pairs from sox, average the amps if there are multiple windows in the signal, and use imagemagick or similar to build a bitmap.

if you can compile a c/c++ program, i can maybe throw something together, since i happen to be building a frequency scope widget right this very minute.

4 Likes

Thank you for the clarification! I sensed this distinction but didn’t have any terminology for it.

That being said, these single cycle waveforms do have a length. So, while it’s not a spectrum plot of a single DFT, I’m imagining that they may look pretty similar regardless? Or am I way off there?

I guess one way to find out is to either write some code, or use yours (which I would personally appreciate greatly!)

they’re not really the same plots, though they show the same information (sort of.)

ffmpeg is using some fixed window size that i don’t know, call it N.

with the default orientation, each vertical slice of the image (one pixel? i dunno) represents the spectrum of a chunk of N samples.

to render the next vertical slice it looks at the next N samples, probably with some overlap factor (to improve time resolution without sacrificing frequency resolution.) additionally, it will be applying some kind of windowing function to eliminate artifacts arising from the truncation at the window boundaries. (the choice of the windowing function is a tradeoff between resolution and bin leakage.)

if your input signal happens to be N samples long, then yes, you should get a single vertical slice that has the same information as a spectrum plot, but the amplitude dimension is mapped to pixel color value (using some arbitrary palette) instead of to the Y axis. not as easy to read.

i’ll make a little thingy while i happen to be on this task

2 Likes

Sweet, thanks! And thanks for the explanation.