I was reading a paper and the authors say that they extract FFT spectrograms and log-scale in frequency domain. I understand how the general spectrogram is computed, but how to make it log-scale in frequency domain? Or maybe there are libraries in Python, which already implement this one?

  • 1
    $\begingroup$ Just calculate the log of the frequency axis? $\endgroup$ – MBaz Jun 2 '16 at 17:41
  • $\begingroup$ This answer might come in handy. $\endgroup$ – jojek Jun 3 '16 at 7:49

You can use either interpolation between FFT bins, or something like an MFCC triangular filter bank, except using equal delta_log spaced triangles instead of Mel-spaced triangles, or both.

| improve this answer | |
  • $\begingroup$ Thank you for your comment. The question is how to do the interpolation between fft bins? Do you average/weight the magnitutes? $\endgroup$ – Egor Lakomkin Jun 3 '16 at 12:19
  • $\begingroup$ Sinc kernel interpolation is better than parabolic or linear for FFT results. $\endgroup$ – hotpaw2 Jun 3 '16 at 14:46

With the speed of today's computers (and some optimized code) I have found a great advantage in doing Pitch Detection with a modified Logarithmic DFT instead of a FFT.

For pitch detection you are basically searching for a note's harmonics (partials) which coincidentally reside in the same frequency channels that we see on a piano's keyboard -- that is, 12 frequency channels within each octave (E, F, F#, G, G#, A, A#, B, C, C#, D, D#). The frequencies of the horizontal channels are to be logarithmically located along a vertical axis of frequency (see diagram below). So when I perform Pitch Detection (see link to my C++ source code) I construct a modified Log DFT which only probes each of the frequency channels which align to the frequencies of notes on a piano.

Since it is a DFT, we can individually adjust the center frequency for each channel so that they are logarithmically spaced and align with the frequencies of notes on a piano. And since it is a DFT, we can individually adjust the bandwidth for each of the channels by changing the number of samples used in summation -- more samples means a more narrow bandwidth for the channel. Because of the way that I gather data for my modified Logarithmic DFT, I do NOT have to apply a windowing function (nor do add and overlap) to the signal to get accurate results (number of samples in summation must be some multiple of samples in the channel's target period, usually the number samples in 17 periods).

If you look at the sonogram below (created by my C++ code), you will see a 3 second Logarithmic DFT from a guitar solo on a polyphonic mp3 recording. Notice how fine-tuned each of the horizontal channels are -- there is little bandwidth overlap, and the harmonics are clearly defined. For each note in this Log DFT we can identify their multiple harmonics extending vertically, because each harmonic will have the same time-width. Despite being a polyphonic recording, the presence of an individual note within the guitar solo is easily apparent to the naked eye.

Now being retired, I have decided to release the source code for my pitch detection engine within a free demonstration app called PitchScope Player. PitchScope Player is available on the web, and you could download the executable for Windows to see my algorithm at work on a mp3 file of your choosing. The below link to GitHub.com will lead you to my full C++ source code for Player, and you can either view and/or compile that Windows code.

To construct a Logarithmic DFT, study the DFTrowProbeCircQue class as defined in SPitchCalc.cpp

To step through a simple version of my Pitch Detection algorithm, study Make_NoteList_No_Audio() in the PitchPlayerApp.cpp file.



enter image description here

| improve this answer | |
  • $\begingroup$ You are misusing established terminology. DFT is something very specific and not what you describe here, logarithmic or not. What you have is a logarithmically spaced bank of bandpass filters. $\endgroup$ – Jazzmaniac Jul 5 '16 at 19:50
  • $\begingroup$ While it is true that this ‘transform’ is mostly a set of bandpass filters, it is still very effective within my pitch detection application (PitchScope Player). I have experimented with retaining the phase data from the transform, in an attempt to create an Inverse of the Transform which could resynthesize the signal to some extent. Despite the subtle misuse of terminology, I still feel that the Answer is an excellent starting point and tutorial for developers who are new to Pitch Detection techniques for the analysis of music. $\endgroup$ – James Paul Millard Jul 5 '16 at 20:03
  • $\begingroup$ Within the source code, my 'transform' is in fact very close to a traditional DFT. When I created the transform, I took the source code for the analysis portion of a DFT, and just made minor changes so that I could alter the target-frequency of the original DFT channels, and also alter the bandwidth of those original DFT channels. I was always disappointed by the automatic use of a FFT in the analysis of music, and wanted to come up with a more efficient and more focused way to do Pitch Detection as it pertains to music. $\endgroup$ – James Paul Millard Jul 5 '16 at 20:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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