Fix aggressive low-end rolloff in DcBlock
#209
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
The current
DcBlockimplementation in DaisySP is aggressively rolling off low frequencies. This is due to the fixed coefficient of0.99being used instead of one dynamically calculated based on the sample rate and approximate target corner frequency.This change adds a dynamic pole calculation based on an approximate corner frequency of 10Hz at the given sample rate using
1 - fc/fswhich is fairly reasonable for corner frequencies below ~100Hz. The exact -3dB corner frequency of the original one-pole lowpass filter can be calculated exactly, but the curve changes when subtracting the filtered signal from the original to achieve a DC-blocking highpass as done here.For reference, here is the filter amplitude response (at fs = 48kHz) with the original hard-coded pole coefficient of 0.99:
https://www.desmos.com/calculator/ymsix8p9aa
And here is the amplitude response with a dynamic pole coefficient (set initially for a ~10Hz corner freq):
https://www.desmos.com/calculator/uhcegka8st
Note the significant difference - in the first example, there is already an attenuation of about -8dB at 100Hz, which only increases as the frequency gets lower. In the second example, there is only about a -0.7dB reduction at 20Hz which is much more reasonable in terms of the effect on the frequency response of the overall filter acting as a DC Blocker.
Note: the logarithmic display of the desmos graph tool requires a non-zero minimum axis value - set it to linear to see that there is truly infinite attenuation as it approaches DC (0Hz)
Testing
I have been using this code in various projects for quite some time as a remedy for the originally aggressive highpass rolloff from the version with the hard-coded coefficient. The theoretical analysis above also confirms the validity of the change.
For further assurance, a
DcBlockcould be added to the simple oscillator example for the Seed, noting the reduction in amplitude of the output signal at frequencies < 100Hz in the original version compared to the update.Finally - comparing the result of the change for a 48kHz sample rate, we get a coef of
1 - fc/fs ~= 0.9997which is the only effective change to the code. Just a different pole coefficient.