Hi Will,

First of all, cheers for the book and the software. I started around February and I'm really pleased with how far I've been all to get into all of this as someone no background in programming or DSP outside of a CSound module I did a few years ago!

Anyway; so I'm trying to implement the high shelf using a modified Biquad you describe in your book. Basically by calculating theta, mu, beta, delta and gamma and plugging in the values as shown , dumping those into the BiQuad object and then doing the summing in ::processAudioFrame

float m_n_BiQuadOut = m_LeftHighShelfModule.doBiQuad(pInputBuffer[0]);

float m_n_c0 = m_n_BiQuadOut*(fMu - 1.0);

float m_n_d = pInputBuffer[0];

pOutputBuffer[0] = m_n_c0 + m_n_d;

Firstly, changing the cutoff appears to affect the sound even when no gain is applied. Secondly the gain is huge, it's easily 100dB louder than the input! I've a feeling it's to do with fMu, but I'm not so sure.

Thanks again,

Chris

Hi Chris

The code looks basically correct to me. In my implementation, I calculate the output in a separate function. My code for calculating the coeffs is:

float theta_c = 2.0*pi*fc/sampleRate;

float mu = pow(10,(boostCutdB/20.0));

float b = (1+mu)/4.0;

float c = b*tanf(theta_c/2.0);

float gamma = (1.0 - c)/(1.0 + c);

float alpha = (1.0 + gamma)/2.0;

biQuad.m_f_a0 = alpha;

biQuad.m_f_a1 = -alpha;

biQuad.m_f_a2 = 0.0;

biQuad.m_f_b1 = -gamma;

biQuad.m_f_b2 = 0.0;

// --- modified BQ

c0 = mu - 1.0;

d0 = 1.0;

Then, in the output function, I do this (CWPFilter is my big-filter object):

float CWPFilter::doFilter(float input)

{

float output = biQuad.doBiQuad(input);

output = output*c0 + input*d0;

return output;

}

I'm guessing the coeffs are not calculated correctly?

- Will

Near as I can tell, my calculation is identical. I changed it to look more like yours - but the maths has stayed the same. Still does the weird changing cutoff = variable HPF thing, and also has miles of gain.

void CHighShelfModule::calculateHighShelfModuleCoeffs(float fCutoffFreq)

{

//Theta

float theta_c = (2.0*pi*fCutoffFreq)/(float)m_nSampleRate;

//Mu

float fMu = pow(10.0,(m_f_Gain_dB/20.0));

//Beta

float fBeta = (1.0 + fMu)/4.0;

//Delta

float fDelta = fBeta*(tanf(theta_c/2.0));

//Do Gamma

float fGamma = (1.0 - fDelta)/(1 + fDelta);

//Cook Alpha

float fAlpha = (1.0 + fGamma)/2.0;

//Cook variables for BiQuad object

m_LeftHighShelfModule.m_f_a0 = fAlpha;

m_LeftHighShelfModule.m_f_a1 = -fAlpha;

m_LeftHighShelfModule.m_f_a2 = 0.0;

m_LeftHighShelfModule.m_f_b1 = -fGamma;

m_LeftHighShelfModule.m_f_b2 = 0.0;

m_RightHighShelfModule.m_f_a0 = fAlpha;

m_RightHighShelfModule.m_f_a1 = -fAlpha;

m_RightHighShelfModule.m_f_a2 = 0.0;

m_RightHighShelfModule.m_f_b1 = -fGamma;

m_RightHighShelfModule.m_f_b2 = 0.0;

}

Hmmm - yeah, this looks the same.

But, I know the high shelf algorithm works so there must be something else going on...

I've had students with similar filter issues when they accidentally use one of the filters twice (i.e. calling the left filter doBiquad() for both left and right channels). But if you are running the Low Shelf filter OK, then that is not the issue - BTW, do you have the Low Shelf running?

WP

Hi Will,

Sorry for being slow to get back to you. I'm crazy busy mid week these days! Anyway, I decided to take your advice and build the low shelf filter to see if it would work and met an interesting compiler error with the same basic code - fMu wasn't transferring itself from ::calculateLowShelfModuleCoeffs to ::processAudioFrame. So I decided to redeclare it:

float m_n_BiQuadOut = m_LeftLowShelfModule.doBiQuad(pInputBuffer[0]);

float m_n_d = pInputBuffer[0];

float fMu = pow(10.0,(m_f_Gain_dB/20.0));

float m_n_c0 = m_n_BiQuadOut*(fMu - 1.0);

pOutputBuffer[0] = m_n_c0 + m_n_d;

And it works perfectly! Same for the High Shelf. No crazy gain issues. I'm guessing fMu was becoming some wacky value and this was causing the strange behaviour. However this isn't very efficient as I'm now doing the calc twice- is there another way to pass the variable from one to the other?

I think you have a scope problem (curly brackets, explained on page 24 of the FX book). I'm guessing your ffMu value is going out of scope since it is declared in a separate function; try declaring fMu on the object instead (m_fMu) and use it for calculations and processing - that way, it will persist between function calls.

- Will

Most Users Ever Online: 152

Currently Online:

7 Guest(s)

Currently Browsing this Page:

1 Guest(s)

Top Posters:

Skyler: 48

Derek: 46

Frodson: 45

Peter: 43

TheSmile: 43

clau_ste: 39

JimmyM: 33

Gwen: 32

EZB: 24

lppier: 23

Member Stats:

Guest Posters: 1

Members: 617

Moderators: 1

Admins: 4

Forum Stats:

Groups: 12

Forums: 38

Topics: 651

Posts: 2558

Newest Members:

TheJonDoe, DoubleLiines.com, jmf11, dan, Luke Bilodeau, Carlos_1, ant, marclingk, TheCammen, HubbertModerators: W Pirkle: 444

Administrators: Tom: 74, JD Young: 80, Will Pirkle: 0, W Pirkle: 444