rouncer at June 12th, 2012 15:02 — #1
im using a 2048 long fft, when i attenuate low frequency sine waves it produces popping, how do i get rid of this?
im processing samples in lots of 2048.
void ffteq_process(int samples, int* in, int* out, float* data, int*& memory)
int b=(31-((powf(1.0/(8192.0*256.0),(float)k/(float)(size/2)))*31))+1; //theres 32 controllers
//to control frequency so i access them here
float vol=data[b]*2; //this is just accessing the graph that attenuates the frequencies
reedbeta at June 12th, 2012 15:18 — #2
I'd guess it's happening because the ends of the FFT frames are no longer continuous with the next frame after processing. You might try overlapping the FFT frames a bit and blending across. For instance maybe frame 0 would be samples 0-2047, frame 1 would be 1792-3839 (I overlapped the range by 256), and in the overlapping region from 1792-2047 you'd blend from frame 0 to frame 1.
rouncer at June 12th, 2012 17:37 — #3
yeh that worked, i thought i had a problem at first, but no - it works fine!! its a really nice eq too, and it just so happens to instance many times, the computer makes short work of the fft, and its got good bass response at 2048. cool.
smile_ at June 12th, 2012 17:40 — #4
First, keep in mind that fixed size FFT is an approximation of the real frequency representation of some signal (real representation have infinite window). Consequence is that your attenuation function must be smooth enough, i. e. for consecutive frequencies must not differ much. If it's not smooth enough then you have popping and another errors.
is a very slow equivalent of
I recommend you to study complex numbers before working with frequency domain.
Third, for 32-band equalizer or similar processing, doing FFT is probably overkill. You can implement simple analog filters with equivalent simple function of untransformed sound values.
rouncer at June 12th, 2012 17:54 — #5
heres a shot of my music program so far!
those yellow and blue dots are the synthesizer, it repeats back a wave at a high varying frequency to make a nice bleep. the fft eq can soon turn the bleep into drums with a bit of clipping.
rouncer at June 12th, 2012 17:57 — #6
Thanks for the advice smile, that code adjustment will be going in for sure, I tried an iir filter eq (composed of about 7 notches), but I couldnt find a notch or peak filter that could filter bass very well, the best I got was a 2 pole 2 zeroes but it was really bad actually, the fft filter almost worked first time... im yet to get an amazing sound out of it yet tho... which i know filters are good for if you get them right.
rouncer at June 12th, 2012 18:28 — #7
funnily, i was mucking around with the notch filter again and i was getting better results.... theres something cool about iir filters musically... hmm its strange, anyway i just clipped a bit of bass into this saw tooth and i got some sick brass... that im not getting out of the fft eq. wierd.
smile_ at June 12th, 2012 18:30 — #8
Well, to produce good filter you must know analog circuit theory (and complex numbers as part of it). For a peak filter you can use the following code
double peak_filter(double val)
static const double step = 1.0 / 44100;
static const double freq = 440, beta = 44;
static const complex<double> mul = exp(complex<double>(-beta, freq) * step);
static complex<double> accum = 0;
return (accum = (accum - val) * mul + val).real;
It filters a band of width beta around frequency freq. I can't remember formula for notch filter but it has the same complexity.
rouncer at June 12th, 2012 18:39 — #9
i used this notch filter as a bass booster on a saw, and came up with this brass synth.
Ill try that filter, thanks a lot. err, im not sure what to do with complex\?
smile_ at June 12th, 2012 19:13 — #10
complex\ is simply
double real, imag;
with defined mathematical operations. C99 have its analog in \ (dunno about MSVC support though, use C++ version):
double complex mul = cexp((-beta + freq * I) * step);
Or you can fallback to real numbers:
double mul_re = cos(freq * step) * exp(-beta * step);
double mul_im = sin(freq * step) * exp(-beta * step);
static double acc_re = 0, acc_im = 0;
double res_re = (acc_re - val) * mul_re - acc_im * mul_im + val;
double res_im = (acc_re - val) * mul_im + acc_im * mul_re;
acc_re = res_re; acc_im = res_im; return res_re;
Oops, fixed error in filer code from my previous post.
rouncer at June 12th, 2012 19:51 — #11
i tried the filter, it worked but it has poor bass response, bass seems to be the hardest to get and is the most important to have!!! a good bass boost before you distort is always what you do, I need a bass peak that works right down into the sub frequencies.
smile_ at June 12th, 2012 20:17 — #12
What exactly do you want to get? What frequency response do you want to achieve? My filter works independent of frequency, maybe you don't have enough sound output quality?
rouncer at June 12th, 2012 21:51 — #13
good sub response is what i need, maybe your filter is good enough its just maybe im not using these filters right, its tough...
stainless at June 13th, 2012 06:08 — #14
That's the problem with sound, it's subjective and varies with hardware.
With graphics you can screen grab it and study it in detail and everyone can pretty much see the same thing. If you wrote a wav file from your code we could listen to it, but there is no way of getting all of us to hear the same thing.
Why don't you grab a copy of a MOD tracker and compare that with the output of your software, then at least you have an idea if it is your code that's wrong, or your setup is not giving you the sound you want.