I'm a little fuzzy on how the Fourier transform works. It's supposed to map time domain to frequency domain, and vice versa, so my intuition says that if I wanted to make an equalizer, I'd take the FFT of the audio stream, multiply e.g. the first third of the values by 0.5, take the inverse FFT, and send that to the speakers, and I'd get audio with the base cut by half. I've attempted this sort of thing multiple times in the past ~15 years, and it never seems to work out.
Here's some test code I'm working on to mess with this: https://github.com/Erhannis/JModemTest. ATM it reads from the mic, does test processing, and plays to the speakers.
(Be aware it depends on https://github.com/Erhannis/MathNStuff, which you'll need to mvn install
.)
Complications I run into:
#1, the FFT works on finite chunks of data, not on streams of data. You could just apply it over successive chunks, but then you'd get a discontinuity at the boundary, right? So your audio would have weird clicks in it.
#2, the FFT works on complex data. I vaguely understand that the complex component in the frequency domain represents phase, and that it's necessary, so I guess I'll live with it, but
#3 it seems like changing anything in the frequency domain gives you a non-zero complex component once you take the inverse FFT, and I don't think there's a physical analogue to that. (I.e., it gives you invalid data.) Is there a way to ensure your processing will yield data that gives real values once inverse-FFT'd? Or a usually-acceptable way of discarding/salvaging the imaginary component? (Like, a particular class of real-preserving processing functions, or "yeah, you can ignore the imaginary values at the end", or "use the magnitude of the complex values" (tried that, didn't seem to make a difference to the audio, shrug.))
#4 After a tiny multiplication to a few freq-domain values gave me complete static, I remembered that the FFT is kinda mirrored, so I mirrored the multiplications across the array. This gave me audio that was recognizable - but littered with glitches and chunks of static. I don't understand what mathematical process would cause that, nor how to fix it.
Long story short - how do you modify data in the frequency domain (presumably using Fourier transforms) without turning it into garbage?
Edit: AHA! In reusing some of my code for something else, I noticed that some of my byte conversions were backwards! My code works much better, now - still not great, presumably for the reasons given below, but it doesn't turn the output into garbage, and it does stuff audibly resembling the intended result! Taking all this into account, I'd say that the keys for getting not-garbage are 0. get your byte orders right, and 1. make sure your changes in the frequency domain are symmetrical after chopping off the first value.