fix(loudness): add preamp cut to prevent clipping from compensation boost#303
Open
iscle wants to merge 1 commit into
Open
fix(loudness): add preamp cut to prevent clipping from compensation boost#303iscle wants to merge 1 commit into
iscle wants to merge 1 commit into
Conversation
…oost LoudnessCompensator applied frequency-dependent boosts (bass/treble) at low volumes without attenuating the signal first. On hardware-volume devices like Bluetooth headphones, the signal is at full amplitude in the pipeline while the compensator applies large boosts based on the low device volume — pushing bass peaks well above unity. The SoftLimiter (0.95 threshold, 0.05 headroom) then hard-clips these peaks, causing audible distortion especially at lower listening levels. Add a preamp gain stage (via the existing BiquadProcessor.preProcess hook) that attenuates by the peak boost of the realized biquad response before the EQ cascade runs. This ensures no frequency exceeds the original signal level after compensation, matching the pattern already used by AutoEQProcessor. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced May 21, 2026
|
This PR is needed badly. I downloaded this app just for the loudness compensation feature and discovered it produced terrible clipping / distortion on both my iMac 5K built-in speakers and wired headphones at low volumes. |
Please try my fixed version #317 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Heads-up: This PR and fix was generated by Claude, but I did manually review it and test it! No sloppy unsupervised AI code here :)
Summary
LoudnessCompensatorthat attenuates the signal by the peak boost of the realized biquad response before the EQ cascade runs, preventing clippingBiquadProcessor.preProcesspattern already used byAutoEQProcessorProblem
On hardware-volume devices like Bluetooth headphones, the audio signal stays at full amplitude in the processing pipeline (volume is controlled by the device, not digitally). Meanwhile,
LoudnessCompensatorsees the low device volume, computes a low phon level, and applies large frequency-dependent boosts (10–20 dB bass/treble at low volumes per ISO 226:2023 contours).This pushes bass/treble peaks well above unity. The downstream
SoftLimiter(threshold 0.95, ceiling 1.0 — only 0.05 headroom) then crushes these peaks, causing audible non-linear distortion. The lower the volume, the larger the compensation boost, and the worse the clipping.Fix
Before the biquad cascade, apply a preamp cut equal to the inverse of the peak realized response:
This ensures no frequency exceeds the original signal level after compensation. The
preProcesshook (vDSP_vsmul) is RT-safe with zero allocations.Related
Partially addresses #302 — the distortion component of the reported audio issues when loudness features are enabled. The volume-pumping behavior described in #302 is a separate concern in
LoudnessEqualizer(dynamic gain leveler) involving over-aggressive boost settings and measurement/smoothing timing, which would need a separate fix.Test plan
xcodebuild,CODE_SIGNING_ALLOWED=NO)ISO226ContoursTestsandProcessingPipelineTestspass🤖 Generated with Claude Code