jaakkopasanen / AutoEq

Automatic headphone equalization from frequency responses
MIT License
13.43k stars 2.48k forks source link

Normalize convolution presets to prevent clipping #388

Closed future-figs closed 1 year ago

future-figs commented 2 years ago

I assumed that the convolution filters would be tuned to prevent digital clipping; however, with no preamp or any other audio processing, I notice digital clipping with certain audio/video files.

The pathological audio input which produces the "loudest" single audio output sample swings rail-to-rail, either positive or negative depending on the sign of the corresponding sample in the convolution kernel. So each positive sample in the kernel is multiplied by 1.0, and each negative sample is multiplied by -1.0. The resulting single worst-case output sample is equal to the sum of the absolute values of each sample in the kernel. An existing convolution kernel can be scaled such that this sum is equal to 1.0 to prevent clipping under any circumstances.

It's a simple fix to just apply preamp, as in fixed/parametric EQ, But the headphone preset pages don't explicitly specify whether to use the fixed or parametric gain, or some other number. It also adds unnecessary setup complexity, even if the number is given.

Some possible downsides:

jaakkopasanen commented 2 years ago

The convolution filters are scaled so that their frequency response does not exceed 0 dB at any given frequency. As I understand this should be perfectly sufficient for preventing any clipping, theoretical or practical. Do you have a reason to argue this is not the case?

Other potential source of problem could be the actual convolution software. Another user have reported this type of issue with Lancaster Audio convolver on Mac, see #327

future-figs commented 2 years ago

As I understand this should be perfectly sufficient for preventing any clipping, theoretical or practical. Do you have a reason to argue this is not the case?

In fact I do...phase shift. Unless the IR kernel has 0deg phase across the spectrum (or linear-phase I think?), it's possible to push two peaks/troughs into alignment.

Sorry I haven't come back to this topic in a while. Work started back up so now I'm pretty busy.

Jan 15, 2022 4:39:42 AM Jaakko Pasanen @.***>:

The convolution filters are scaled so that their frequency response does not exceed 0 dB at any given frequency. As I understand this should be perfectly sufficient for preventing any clipping, theoretical or practical. Do you have a reason to argue this is not the case?

Other potential source of problem could be the actual convolution software. Another user have reported this type of issue with Lancaster Audio convolver on Mac, see #327[https://github.com/jaakkopasanen/AutoEq/issues/327]

— Reply to this email directly, view it on GitHub[https://github.com/jaakkopasanen/AutoEq/issues/388#issuecomment-1013651915], or unsubscribe[https://github.com/notifications/unsubscribe-auth/AB6TPN2JEILZGWNJDFELCP3UWE6FTANCNFSM5J5HHDPQ]. Triage notifications on the go with GitHub Mobile for iOS[https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675] or Android[https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub]. You are receiving this because you authored the thread. [data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAABUCAYAAAAcaxDBAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAAySURBVHic7cEBDQAAAMKg909tDjegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeDVulAABbzDScQAAAABJRU5ErkJggg==###24x24:true###][Tracking image][https://github.com/notifications/beacon/AB6TPN6E7NSQMQ7W4YQAAXLUWE6FTA5CNFSM5J5HHDP2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOHRVRTSY.gif]

jaakkopasanen commented 2 years ago

@Mr-Figs It seems you are, in fact, correct in what you said in your first message. Normalizing the FIR filters by the sum of absolute filter coefficient values is quite conservative and I'm a bit hesitant to do that as it would produce several dB lower volume than parametric eq for example. The worst case scenario probably hardly ever happens but that stil leaves room for some clipping with some real signals, unfortunately it's not so simple to say how much more headroom the FIR filters should have in practice.

erdewit commented 2 years ago

What seems to work well in practice is to use something between L1 and L2 normalization. This is what I use for HiFiScan:

https://github.com/erdewit/HiFiScan/blob/7b41e81d3e56f9c92a10508418926e22a5ccea97/hifiscan/analyzer.py#L273

future-figs commented 2 years ago

Thanks for the reply.

My misunderstanding from earlier was that RMS was any different from the sum-of-abs approach that I described. They are actually mathematically identical, so the only difference is whether one is more computationally expensive. Again, shows what I know!

And yes, this approach is extremely conservative. The pathological case that might cause clipping would also probably damage your speakers, if you were ever to actually play it.

Still, guess-and-check preamp is quite annoying. Maybe the "absolutely no clipping" gain value would be more helpful just as a point of reference for the user. I think this might make sense in combination with removing normalization altogether.

Either way, we would need to figure out the normalization inside Zita first, which I haven't spent any time on.

Jul 26, 2022 8:31:52 AM Jaakko Pasanen @.***>:

@Mr-Figs[https://github.com/Mr-Figs] It seems you are, in fact, correct in what you said in your first message. Normalizing the FIR filters by the sum of absolute filter coefficient values is quite conservative and I'm a bit hesitant to do that as it would produce several dB lower volume than parametric eq for example. The worst case scenario probably hardly ever happens but that stil leaves room for some clipping with some real signals, unfortunately it's not so simple to say how much more headroom the FIR filters should have in practice.

— Reply to this email directly, view it on GitHub[https://github.com/jaakkopasanen/AutoEq/issues/388#issuecomment-1195421918], or unsubscribe[https://github.com/notifications/unsubscribe-auth/AB6TPN7DFSK6CLHE4W2NKJTVV7LDNANCNFSM5J5HHDPQ]. You are receiving this because you were mentioned.[Tracking image][https://github.com/notifications/beacon/AB6TPN4RCOQOCLEEECDNH5LVV7LDNA5CNFSM5J5HHDP2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOI5ALBXQ.gif]

jaakkopasanen commented 1 year ago

I just implemented --preamp in AutoEq so that's now a way to deal with FIR normalization. I also added a note about this in the documentation.

Since capturing the pathological case would make FIR filters so much less loud for most use cases and all other approaches don't guarantee that there won't be clipping I'm going to call this issue solved. There is no perfect solution for this problem but at least now users can adjust preamp when needed.