I'd guessed it'd be an artifact of short FFT window but it seems to get more dense (rather than the other way around) at lower frequencies.. so what the hell?
Are you sure your graphing is correct?
There's no FFT involved.mystran wrote:Uhm.. exactly how did you manage to get ripple like that from a 2nd order filter?
I'd guessed it'd be an artifact of short FFT window but it seems to get more dense (rather than the other way around) at lower frequencies.. so what the hell?
Are you sure your graphing is correct?
Code: Select all
void LowPass::SetParams( double q, double frequencyNormalized )
{
double w0, cs, sn, al;
// http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
w0 = M_2_PI * frequencyNormalized;
cs = cos(w0);
sn = sin(w0);
al = cs / ( 2 * q );
b0 = ( 1 - cs ) / 2;
b1 = 1 - cs;
b2 = ( 1 - cs ) / 2;
a0 = 1 + al;
a1 = -2 * cs;
a2 = 1 - al;
Optimize();
}
void BiQuad::Optimize( void )
{
// optimize filter coefficients
a1/=a0;
a2/=a0;
b0/=a0;
b1/=a0;
b2/=a0;
a0 =1;
}

Code: Select all
if( frequency<=params->f )
*idealMagnitude=1;
else
*idealMagnitude=0;
Code: Select all
int i;
double p=log10( freqHi-freqLo );
for( i=0;i<count;i++ )
{
double freq=freqLo+::pow( 10, p*i/(count-1) );
double sampleRate=freq*double(m_nsine);
::memcpy( m_out, m_sine, m_nsine*sizeof(m_sine[0]) );
double ideal=0;
if( m_proc!=0 )
m_proc( m_nsine, m_out, sampleRate, freq, &ideal, m_opaque );
if( ideal<0.00001 )
m_ideal[i]=-1000;
else
m_ideal[i]=20*log10(ideal);
double a=calcmax( m_nsine, m_out );
if( a<0.00001 )
m_level[i]=-1000;
else
m_level[i]=20*log10(a/m_a0);
}
Yes.mystran wrote:So you are filtering a sinewave and measuring the amplitude of the output to get the graph?
Well if it doesn't work, then it is producing graphs that are shockingly similar to what you would expect from a working version, for the case of the 3-band eq. Its only the biquad thats acting funny. 3-band eq is looking like a champ.mystran wrote:I can't exactly see how that could possibly work except maybe if you used complex sinusoids but picked the complex magnitude to eliminate phase.. but at least I think it'd explain the ripple..
Ah, maybe I'm not understanding what exactly is it that you do... i guess if you run the sine continuously for a while such that it's steady state and then pick a peak amplitude that'd be workable.. but you need a few cycles minimum to stabilize it, otherwise you can get ripple depending on time-domain properties of the filter (since it's not linear-phase) [edit: and even if it was linear-phase you'd need to stabilize it into steady state, but then it'd be trivial as you'd just make sure to fill all the taps from the sine]thevinn wrote:
Others said that my approach should work. It sure seems like it should work. I mean, I took the concepts of magnitude response to different frequencies quite literally and applied them. What makes you say it shouldn't work?
Its like, I understand each word individually but then when you put them together I am left scratching my head.mystran wrote:Ah, maybe I'm not understanding what exactly is it that you do... i guess if you run the sine continuously for a while such that it's steady state and then pick a peak amplitude that'd be workable.. but you need a few cycles minimum to stabilize it, otherwise you can get ripple depending on time-domain properties of the filter (since it's not linear-phase) [edit: and even if it was linear-phase you'd need to stabilize it into steady state, but then it'd be trivial as you'd just make sure to fill all the taps from the sine]
Great explanation. I was wondering how these things worked. I read up on phase response and I get it now. I see what you mean about phase differences being used to cancel things out.mystran wrote:The way IIR filters work, is basically by delaying different frequencies by different amounts, such that when the result is combined with another copy of the signal without the delay (or with different delay), some frequencies (the pass-band) will be in phase, while others (the stop band) will be out of phase and cancel.
Its definitely been in the back of my mind. There is a noticable discontinuity when the sine wave starts up (first sample==1.0). The filter gets re-initialized for each test frequency and that means its sample history has zeroes. Using the sine, I get -24dB falloff at the cutoff frequency. With a cosine I am getting -19dB falloff. There should not be a difference but there is. So I can confirm that my method of measurement is not independent of phase.mystran wrote:What I was wondering was whether you might not have taken this into account; if you looked at a single sample of the output (where there was a peak in the input) the peak might have shifted (depending on frequency) which might give you a lot of ripple in the measurement.
Things start getting funky at the low frequencies. I will try only calculating the magnitude resposne of the last half of the buffer and see if that changes things.but I admit that for low-order filters you don't need a hugely long signal to stabilize the response and your 2k samples should be enough unless your cutoff frequency is very low.
that was what i was first thinking too. but there's still a catch, even when the the filter has stabilized: simply measuring the highest absolute value of the output sinusoid will still have an error because you can't be sure that the peaks of the (input- or output) sinusiod will coincide with sample instants. that is to say: the maximum amplitude may occur in between samples as in intersample peaks.mystran wrote: i guess if you run the sine continuously for a while such that it's steady state and then pick a peak amplitude that'd be workable.. but you need a few cycles minimum to stabilize it, otherwise you can get ripple depending on time-domain properties of the filter (since it's not linear-phase)
for a biquad lowpass a-la RBJ, a Q value of 1/sqrt(2)=0.707... will give the fastest transition between passband and stopband without overshooting unity gain (without a resonant bump). ...if that's goodthevinn wrote:Can someone please give me a good value for Q for a low pass?
I've switched over to taking the average of the sum of the absolute values of the samples as the magnitude ("a"). It incorporates every sample. I also compute this for the original sine wave ("a0") for the formulaRobin from www.rs-met.com wrote:peaks of the (input- or output) sinusiod will coincide with sample instants. that is to say: the maximum amplitude may occur in between samples as in intersample peaks.
Code: Select all
dB = 20 * log ( a / a0 )
Submit: News, Plugins, Hosts & Apps | Advertise @ KVR | Developer Account | About KVR / Contact Us | Privacy Statement
© KVR Audio, Inc. 2000-2026