fft filter producing pops with low frequency attenuation

13 replies to this topic

#1rouncer

Senior Member

• Members
• 2725 posts

Posted 12 June 2012 - 07:02 PM

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 fftsize=11;
int size=2048;
int j;

for(j=0;j<samples;j+=size)
{
int k;
for(k=0;k<size;k++)
{
GRe[k]=in[j+k];
GIm[k]=0;
}
FFT(1,fftsize,GRe,GIm);

for(k=0;k<size/2;k++)
{
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

double amp=hypot(GRe[k],GIm[k]);
double phase=atan2(GRe[k],GIm[k]);

float vol=data[b]*2; //this is just accessing the graph that attenuates the frequencies
if(vol>=1) {vol*=16;vol-=15;};

amp*=vol;
GRe[k]=sinf(phase)*amp;
GIm[k]=cosf(phase)*amp;
amp=hypot(GRe[(size-1)-k],GIm[(size-1)-k]);
phase=atan2(GRe[(size-1)-k],GIm[(size-1)-k]);
amp*=vol;
GRe[(size-1)-k]=sinf(phase)*amp;
GIm[(size-1)-k]=cosf(phase)*amp;

}

FFT(0,fftsize,GRe,GIm);

for(k=0;k<size;k++)
{
out[j+k]=GRe[k];
}
}

}



you used to be able to fit a game on a disk, then you used to be able to fit a game on a cd, then you used to be able to fit a game on a dvd, now you can barely fit one on your harddrive.

#2Reedbeta

DevMaster Staff

• 5309 posts
• LocationSanta Clara, CA

Posted 12 June 2012 - 07:18 PM

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.
reedbeta.com - developer blog, OpenGL demos, and other projects

#3rouncer

Senior Member

• Members
• 2725 posts

Posted 12 June 2012 - 09:37 PM

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.
you used to be able to fit a game on a disk, then you used to be able to fit a game on a cd, then you used to be able to fit a game on a dvd, now you can barely fit one on your harddrive.

#4}:+()___ (Smile)

Member

• Members
• 169 posts

Posted 12 June 2012 - 09:40 PM

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.

Second,
   double amp=hypot(GRe[k],GIm[k]);
double phase=atan2(GRe[k],GIm[k]);
amp*=vol;
GRe[k]=sinf(phase)*amp;
GIm[k]=cosf(phase)*amp;


is a very slow equivalent of

GRe[k]*=vol;
GIm[k]*=vol;


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.
Sorry my broken english!

#5rouncer

Senior Member

• Members
• 2725 posts

Posted 12 June 2012 - 09:54 PM

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.
you used to be able to fit a game on a disk, then you used to be able to fit a game on a cd, then you used to be able to fit a game on a dvd, now you can barely fit one on your harddrive.

#6rouncer

Senior Member

• Members
• 2725 posts

Posted 12 June 2012 - 09:57 PM

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.
you used to be able to fit a game on a disk, then you used to be able to fit a game on a cd, then you used to be able to fit a game on a dvd, now you can barely fit one on your harddrive.

#7rouncer

Senior Member

• Members
• 2725 posts

Posted 12 June 2012 - 10:28 PM

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.
you used to be able to fit a game on a disk, then you used to be able to fit a game on a cd, then you used to be able to fit a game on a dvd, now you can barely fit one on your harddrive.

#8}:+()___ (Smile)

Member

• Members
• 169 posts

Posted 12 June 2012 - 10:30 PM

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.
Sorry my broken english!

#9rouncer

Senior Member

• Members
• 2725 posts

Posted 12 June 2012 - 10:39 PM

i used this notch filter as a bass booster on a saw, and came up with this brass synth.
http://soundcloud.com/rouncer81/st

Ill try that filter, thanks a lot. err, im not sure what to do with complex<double>?
you used to be able to fit a game on a disk, then you used to be able to fit a game on a cd, then you used to be able to fit a game on a dvd, now you can barely fit one on your harddrive.

#10}:+()___ (Smile)

Member

• Members
• 169 posts

Posted 12 June 2012 - 11:13 PM

complex<double> is simply
struct
{
double real, imag;
};

with defined mathematical operations. C99 have its analog in <complex.h> (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.
Sorry my broken english!

#11rouncer

Senior Member

• Members
• 2725 posts

Posted 12 June 2012 - 11:51 PM

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.
you used to be able to fit a game on a disk, then you used to be able to fit a game on a cd, then you used to be able to fit a game on a dvd, now you can barely fit one on your harddrive.

#12}:+()___ (Smile)

Member

• Members
• 169 posts

Posted 13 June 2012 - 12:17 AM

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?
Sorry my broken english!

#13rouncer

Senior Member

• Members
• 2725 posts

Posted 13 June 2012 - 01:51 AM

good sub response is what i need, maybe your filter is good enough its just maybe im not using these filters right, its tough...
you used to be able to fit a game on a disk, then you used to be able to fit a game on a cd, then you used to be able to fit a game on a dvd, now you can barely fit one on your harddrive.

#14Stainless

Member

• Members
• 582 posts
• LocationSouthampton

Posted 13 June 2012 - 10:08 AM

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.

1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users