Reduce Audio Sampling Bandwidth for FHT/FFT

Status
Not open for further replies.

Holes Flow

New Member
Experts,
I am looking for a way to use the standard arduino FFT (no FHT for non-AVR) but only for a small section of the audio spectrum.
Instead of breaking down the entire spectrum, resulting in wide bins even after /2, I'd like to only sample 2 or 3kHz of the spectrum, and thereby have a more fine-grained analysis, and use less computational power (i.e. make it faster)...
All the examples, like ArduinoFFT, are apparently sampling virtually all of 20Hz-20kHz... If I can let the code focus on a smaller part of the spectrum, I'm hoping for more passes/second and a smaller bin size that will run efficiently on an ESP32 or even ESP8266.
Anyone have any experience in taking the shotgun approach and using a rifle?
TIA!
 
Add a analog audio filter ahead of your digital project.
Like a anti alias filter for the high frequencies. Then also include a high pass filter to remove the low frequencies.
I don't know if that is what you are looking for.

What ate you trying to build?
 
Thanks for writing, ron.

I actually found myself spending too much time making bandpass filters, when I realized it isn't the audio frequencies being attenuated that I needed, but faster processing of a narrow part of the spectrum-and it doesn't need to be accurate, just precise. What is missing is my FHT/FFT expertise.

To answer your question, I'm building on the cheap (FPGA, at least topically, seems powerful but not cheap) a USB powered device that will be ESP-32 driven (unless I can really knock the processor needed with this post, in which case esp8266). With a microphone, it needs to sense relatively short bursts of sound (this is why samples/second important), but only in a narrow part of the audio spectrum. This is why I'm trying to find a way to feed the Analog pin whatever, then have the frequency determinant portion not process the entire spectrum. Like I said above, doing so (overkill) drastically increases the time/sample, and worse makes each bin 'wider', lessening discretion.

The thing with accuracy vs. precision is that it only cares if the same frequency repeats. Accuracy is honestly something I don't expect it to do. Precision (repeatability) is more important.

Think of it like this might help... I'm looking for a signal, and if I had no idea what frequency it was going to be at, I would need to search the entire spectrum. Because nothing is free, I'll miss it because it takes too long (given finite processing) to make each pass. The signal duration is likely well under the scan rate. But then, I find out it will be within a certain range of frequencies. I still don't know the exact frequency, but it doesn't matter-as long as I can pick it up.

Now, in theory, I should be able to tell the FHT/FFT algorithm to no longer look at everything, but only those frequencies that make up that part of the analog input signal. It might be thought of as an in-code bandpass filter(?). This way, I have no passive filter losses, no need to make active bandpass (neither of which would speed things up).

Another example to help would be to think of audio communication/signal. Perhaps notes, or frequencies were the signals, and the discrimination of which was above/below the other determined the formatting/protocol of the information. You wouldn't care what the exact frequency was, just identifying the presence of a series of quick tones whose information lie in the 'pulses' at frequencies relative to each other. You'd need fast, discriminatory processing, right? But because the tones are communicating based on their relative position to each other, tightly packed in the frequency domain, you don't need difficult absolute frequency discrimination.

Come to think of it, doing the above in reality (above/below human hearing) sounds interesting...

Does this help?
 
Last edited:
With a FPGA you can parallel many functions:
In the front end of your project you could build a 10k to 13khz band pass filter.
Nexe build a wall of filters. 10-10.5khz, 10.5-11, 11-11.5, 11.5-12, 12-12.5, 12.5-13khz
I don't know if 6 outputs is enough. Just a thought.

Next idea. Remember the 20 to 10k scanning filter, that scans slowly.
Build a version 10khz to 13khz wide band scan very fast. To scan fast the filter needs to be wide. This filter can't really pull out a frequency but it could tell you that there is more energy in the 10.5 to 11 range and less in all the others. Now you know about where to look so another filter is pointed in that range only.
 
With a FPGA you can parallel many functions:
In the front end of your project you could build a 10k to 13khz band pass filter.

Thanks for writing, Ron. I can't seem to get a simple RC filter to do anything right now-even with a SG & scope. Everything goes through unimpeded in all but the most extreme values. Even with the online calculators & 1/2πRC for LPF... Disheartening after all those years in electronics (called EE these days) school & the military!

Nexe build a wall of filters. 10-10.5khz, 10.5-11, 11-11.5, 11.5-12, 12-12.5, 12.5-13khz
I don't know if 6 outputs is enough. Just a thought.

I'd be happy with a LPF at -3db at 3KHz, at this rate...

Next idea. Remember the 20 to 10k scanning filter, that scans slowly.
Build a version 10khz to 13khz wide band scan very fast.
To scan fast the filter needs to be wide.

My bench/beta is to first utilize the 500Hz to 2.5Khz range, and nail that down as my band pass for any FHT/FFT. Everything else attenuated as far down as it can be. I've been trying op amps for active BPF, but practically speaking, where am I going to cheaply come up with -Vcc from a USB? If I could just focus on 1/2 the wave (isn't this the basis for FHT?), but I'm too far ahead of myself. I feel like an idiot for not being able to get real world ASG sweeps to go through passive HPFs and LPFs the way they're supposed to.
 
Old thread... are you still trying to do this?

It sounds like you need Bandpass Sampling.

Sample the signal, (fs = 2*highest frequency), then multiply by a complex sine wave (real and imaginary parts), low-pass filter and decimate (real /imag as separate chains), (filter and decimate again in stages if you want to reduce the bandwidth even further), then run a complex->complex FFT. Because you've decimated, you've reduced your sample rate (and hence FFT size, OR if you keep the FFT size the same you've increased your frequency resolution). You've also shifted what the frequency bins represent - they will be centred around the frequency of the complex sine wave you used in the first step.

Depending on the processor, the heterodyne/filter/decimate stages might end up taking more CPU than just doing the FFT in the first place.
I can dig up some proper references or even code if you're still interested. Matlab (or Octave) is the best way to play with this stuff - create some signals, and run them through filters/ffts and plot each step, it really helps with understanding how it all works.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…