Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to obtain fundamental frequency and harmonics? #4

Closed
danielcrenna opened this issue Sep 23, 2019 · 4 comments
Closed

How to obtain fundamental frequency and harmonics? #4

danielcrenna opened this issue Sep 23, 2019 · 4 comments

Comments

@danielcrenna
Copy link

danielcrenna commented Sep 23, 2019

Hi Scott,

I'm brand new to audio programming, so I may be off the mark here, but I'm wondering if there is any way to assist obtaining the fundamental frequencies from the spectrogram/FFT output.

I'm trying to obtain the fundamental frequencies after serializing the FFT data that is created for the spectrogram, so I can create a new waveform with modified frequencies to the input waveform.

Does the Waterfall demo already output the fundamental/peak frequency? Does the spectrogram account for power spectral density?

@swharden
Copy link
Owner

Hi @danielcrenna, it may be easier for you to interact with the sound card, take the FFT, and skip the spectrograph entirely.

This project shows how to create a real-time FFT graph: https://github.com/swharden/Csharp-Data-Visualization/tree/master/examples/2019-06-08-audio-fft and finding the fundamental frequencies just involves finding the peaks.

Also the audio monitor demo of ScottPlot here: https://github.com/swharden/ScottPlot/tree/master/demos/src/audio-monitor already does peak detection and displays the fundamental frequency in the corner

I hope these demos help get you started!

@swharden
Copy link
Owner

swharden commented Sep 24, 2019

I'm brand new to audio programming

I originally misread this to mean you are new to programming - it seems by your GitHub this is not the case so I'll give you a more thorough answer! I use the NAudio library for this task. All that useful code is collected into this one file that calculates FFTs: https://github.com/swharden/Spectrogram/blob/master/src/Spectrogram/Operations.cs

Making spectrographs is a lot of analytical noise. What you need for frequency detection is:

  • get a segment of audio data - the FFT algorithm requires this be a number of samples which is a power of two.
  • window it (multiply it by a Gaussian-like windowing function, usually a Hamming window) so it starts and ends at zero to produce a nice FFT with clean peaks
  • perform the FFT, and the output will be real and imaginary
  • collapse the FFT into real only using realOnly = sqrt(real*real + imaginary*imaginary)
  • collapse the left and right sides of the FFT, halving the number of points
  • optionally convert the output to Decibels by db = 20 * math.log10(abs(realOnly))
  • matching frequency up to index is easy when you consider the collapsed FFT output will be 1/2 the input size, evenly spaced units between 0 Hz and 1/2 the sampling rate (e.g., 1024 points of 24 kHz audio will collapse to 512 points evenly spanning frequencies 0 to 12 kHz).

I'm trying to obtain the fundamental frequencies ...

Fundamental frequencies will be a peak, and harmonics are every multiple of that peak (e.g., 200 Hz, 400 Hz, 600 Hz, 800 Hz, etc). You'll know what index values these are by the frequency calculation mentioned above.

... so I can create a new waveform with modified frequencies to the input waveform.

Let's say you want to remove all frequencies between 500Hz and 1kHz.

  • To do this, take the FFT but do not convert it to real only.
  • Identify the index positions corresponding to the frequency range to want to remove and set those values (real and imaginary) to zero.
  • perform the inverse FFT. I'm not sure if NAudio has this but I assume they do.
  • Your output if the iFFT will be identical to your original audio sample (same length and sample rate) with 500Hz-1kHz frequencies removed.

I hope this helps!
Scott

edit: I may be off by a factor of 2 when it comes to the number of points to expect. I also didn't mention a mirroring phenomenon which may be collapsed. With a little trial and error, and graphing the output, you'll probably quickly figure it out! There are many tutorials on FFT audio processing and, although a heavy topic, will prove useful to review if you're going to undertake this challenge because it's a bit complicated and easy to get wrong

@danielcrenna
Copy link
Author

@swharden Thank you for being so generous with your time! I had a discussion with another programmer friend of mine about an hour before you posted your follow-up, and through that I learned that the iFFT is essentially for getting things back into time-space from frequency-space, which was one of the fundamental bits I was missing, and your comments are a nice roadmap to move forward. I'll certainly follow-up if I produce anything useful. Much obliged.

@swharden
Copy link
Owner

I'm glad I was able to help!

I'll certainly follow-up if I produce anything useful.

If you come up with a simple-case example how to do these things, let me know and I'd be happy to host it or link to it on a few of my pages.

Good luck!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants