Avatar

Please consider registering
Guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed sp_TopicIcon
High Shelf algo
No permission to create posts
May 30, 2015
5:35 pm
Avatar
chrisquigley
Member
Members
Forum Posts: 3
Member Since:
May 30, 2015
sp_UserOfflineSmall Offline

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

May 31, 2015
12:46 am
Avatar
W Pirkle
Admin
Forum Posts: 143
Member Since:
January 28, 2017
sp_UserOfflineSmall Offline

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

June 1, 2015
8:42 am
Avatar
chrisquigley
Member
Members
Forum Posts: 3
Member Since:
May 30, 2015
sp_UserOfflineSmall Offline

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;
}

June 1, 2015
7:15 pm
Avatar
W Pirkle
Admin
Forum Posts: 143
Member Since:
January 28, 2017
sp_UserOfflineSmall Offline

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

June 5, 2015
7:00 am
Avatar
chrisquigley
Member
Members
Forum Posts: 3
Member Since:
May 30, 2015
sp_UserOfflineSmall Offline

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?

June 8, 2015
6:31 pm
Avatar
W Pirkle
Admin
Forum Posts: 143
Member Since:
January 28, 2017
sp_UserOfflineSmall Offline

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

Forum Timezone: America/New_York

Most Users Ever Online: 36

Currently Online:
3 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

Skyler: 47

Peter: 41

Derek: 41

clau_ste: 39

Frodson: 38

Gwen: 32

EZB: 24

lppier: 23

Msaldaña: 18

Jorge: 17

Member Stats:

Guest Posters: 1

Members: 476

Moderators: 1

Admins: 4

Forum Stats:

Groups: 11

Forums: 30

Topics: 482

Posts: 1876

Newest Members:

sam, annaharris, Marie Weaver, kev, Steven, Mr Anderson, mguy, omelc

Moderators: W Pirkle: 143

Administrators: Tom: 65, JD Young: 80, Will Pirkle: 0, W Pirkle: 143