C source code needed for frequency analysis.

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

I'm looking for C or C++ source code for frequency analysis. Now before you start recommending libX, libY or MostAwesomeSetOfSoundLibsEverZ, please let me explain precisely what I'm looking for.

I need to pass a waveform or a window to a waveform to a function and determine the highest frequency in used and determine from a list of bands where the heaviest frequencies lay. I'd like to cut and paste only the routines needed to accomplish this from working code.

Due to my limited understanding of DSP mathematics, it is currently beyond me how to accomplish this. I've seen and used DSP libs without fully understanding the underlying math; so if this can be accomplished reasonably with standard filter algorithms, I would appreciate the knowledge.

Thanks for reading.

Post

Althouogh I've never used any fft-lib myself that would probably be a good wat to go.

A cluncier manual solution would be to make a sort of binary search with lowpass filter, or linear or whatever..

The most simple linear solution..

copy the window/buffer so youo have something youo can throw away after finished use.
apply highpass at 100Hz, look through the buffer after values if still values over magic threshold more filtering is needed, go on with 200Hz ...and so on.

This wont give you an exact value of the higher frequency and is brute force..

What do you intend to use it for?
David Guda gudaaudio.com

Post

This is exactly what fast fourier transforms do. You give them a bunch of samples, and they turn said samples into measurements of frequencies divided in bands.

This one does exactly that, and only that:
http://www.kvraudio.com/forum/viewtopic ... 3&t=415474

Post

ChocoBilly wrote:I'm looking for C or C++ source code for frequency analysis...I need to pass a waveform or a window to a waveform to a function and determine the highest frequency in used and determine from a list of bands where the heaviest frequencies lay...
You don't define "waveform", but I'm pretty sure that you don't mean a cycle of a periodic wave, therefore suggestions of using an fft won't be of much help. You'd need to get a continuous spectrum from overlapped ffts, then you'd still need further techniques to interpret that into bands of frequencies. Your description isn't detailed enough to know if you need to track temporal information for frequencies, but in general it seems that a sinusoidal model will do what you want—maybe overkill, maybe not, depending on exactly what you are doing. There's a lot that's open to interpretation and what you are going to do, so I don't know if you'll find a lib or cut&paste that will do the job without you doing a fair amount of work and understanding the concepts.

I took this course, and it covered this sort of thing well. Most of the work was done in a Python/C source code library: sms-tools

You can "preview" the course—watch the course video, go through the material, etc. It's a big undertaking, and I suspect more than you'll want to go through (I was one of the few who saw it through and passed the course—it was a lot of work; my initial goal was to just experience a MOOC, and this had good subject matter, but I did learn a lot frequency tracking techniques). But if you look at some of it (especially sinusoidal model), it might give you an idea of what you need and what you might not need.
My audio DSP blog: earlevel.com

Post

Unless I am mis-reading something, it sounds like a sonogram would give you the information you are looking for? Obviously that would be a visual representation, but you could present the numerical data in a similar way.

Post

Thanks to everyone that responded. For some reason I got notification other threads had been updated but not this one. I truly wish I had seen all your replies sooner. And I should have explained better.

Often, I need to deal with a large number of wave files, and need to be able to batch process them. A while ago, I needed to encode a large number of waves into a proprietary compression format. Had I been able to analyze the wave files I could have improved the encoded quality by limiting the frequencies encoded while keeping a fixed sample rate overall. I could have loaded them one by one into a program like Audacity and looked at the spectrum and noted where the highest audible frequency ended. That wasn't practical.

I came to the same conclusion many of you did, use an FFT. There's also the question of how. I see tons of math and some code and very little correlation between code and what it's doing. And of course when it's optimized, you have even less of an idea of what's going on. I found a lot of FFT code and not a lot explaining what I really needed to do with it.

After much trial and error, this is what I've done.

1. Pick a power of 2 from 2K to 32K
2. Use it to run a Hanning window over the data.
3. Use the power of 2 for the sample rate and number of samples. (I question whether this is correct and wonder if the source code I used has a bug.) It doesn't matter what the sample rate really is, since the index of any entry it can be scaled to give the actual sample rate.
4. Get the power by adding the squares of the real and imaginary and take the square root. Make a new array with these values
5. Find the highest power. Use this as the reference for 0 dB. Convert the power array using the linear to dB formula for volume.

For sanity, I plotted the array to a bitmap and see very similar results to Audacity on a variety of wave files. All that remains is to modify the code to loop over all the data not just the 1st power of 2 sized window. Then merge the dB converted power array for each new pass onto a history that just keeps the highest value. I'll need to look at the max gain of the wave and further adjust the power array with that value.

I sometimes see noise at the very high end that I know isn't there. But it may be too small to actually care about. I'll plot some lines on dB boundaries I care about and see if it's below that.

I'll probably overlap the window on the subsequent FFTs as I've read that's what you do but I don't really get why. Or if there's something special to the overlap like a fade in for the new region to compensate for erroneous values created at the edges.

@earlevel That course link looks interesting. I'll look for it to come around again.

Thanks to all,

Post

Well, I seem to have it working now. There were a couple of problems. The FFT code I used had a problem as I suspected and used sample rate and number of samples independently requiring only the number of samples to be a power of 2; it seemed fine if both values were the same but I replaced it anyway. The other problem was when there was any amount of silence, the output was not valid. I fixed this by adding another step at the end.

6. Calculate the RMS (root mean square) of the block being processed. Convert this to dB value which will be negative and add it to the power value of each power entry in the power array.

This produced believable results but not identical to the spectrums produced by Audacity or SoundForge which both produce different curves with the same settings. I also don't understand why the SoundForge shows lower dB than Audacity or mine. And I also don't understand why using larger window sizes makes all algorithms show a lower power curve.

Other mysteries are why certain frequencies give each algorithm trouble. Creating a 48 kHz wave made of 4 sine waves at 1,4,6&8 kHz shows up uniquely different in all 3. And another of 440 Hz and 4400 Hz sine wave produced the most sidelobe/leakage.

I ended up not using an overlap and it doesn't seem to be an issue that I can tell. I didn't want to make a backup of the wave or the overlap region to run the Hanning window over the next block. I also don't know if this would be a straight overlap or if the overlap region needs to be massaged in some way.

I would like to make this function as correct as possible but it serves my needs as it is.

Post Reply

Return to “DSP and Plugin Development”