Any audio engineers around willing to take a look at this?

If it's not ZDoom, it goes here.
Post Reply
User avatar
KynikossDragonn
Posts: 272
Joined: Sat Dec 12, 2020 10:59 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Void Linux
Graphics Processor: Intel (Modern GZDoom)
Location: Independence, KS, USA
Contact:

Any audio engineers around willing to take a look at this?

Post by KynikossDragonn »

There was this pull request to pull in a "custom fixed point audio resampler" for DXX-ReBirth and one of the highlights was "high order brickwall filter like SB16".

The audio is completely messed up as a result of this producing extreme aliasing and ringing artefacts that quickly spirals into full blown clipping distortion when enough sounds are played at once, Audacity revealed this to me:


I'm too stupid to understand C++ and low level code, and I don't know enough audio engineering ontop of this. Is there some math going completely wrong to produce this result? This issue is extremely awful and I'd like to get this fixed but it might end up being vKLp will have to roll back everything before the pull request restoring the original audio routines that were going through SDL_mixer.

I know I'm not crazy because I've had fond memories of playing Descent on a actual MS-DOS machine on an actual SB16, I've seen Twitch streamers with similar old hardware and the audio DOES NOT screw up this badly like it's doing here.
User avatar
Chris
Posts: 3002
Joined: Thu Jul 17, 2003 12:07 am
Graphics Processor: ATI/AMD with Vulkan/Metal Support

Re: Any audio engineers around willing to take a look at this?

Post by Chris »

Given the ringing peak being around 11khz (near the nyquist frequency of 22khz, that does make me think of some kind of aliasing problem. Seeing comments in the code like

Code: Select all

// Coefficient set for half-band (e.g. 22050 -> 44100)
...
// We expect a 4x upscaling 11025 -> 44100
...
int upFactor = out_freq / freq; // Should be integer, 2 or 4
my first thought is... is that true? Your recording is 48khz, not 44100, and while it doesn't necessarily mean that's a problem (that may well do 11khz->44khz as designed, with an separate resample pass to do 44khz->48khz for system output), I'd still check those values to make sure they're as expected.

Another possible culprit is the filter_fir function doesn't seem to have any protection against overflow. Given 16-bit signed samples, and the filter peaks at 32767 or 65535 depending on the filter, a convolution could potentially overflow the signed 32-bit accumulator.

Also, the upscaling factor looks like it's handled wrong:

Code: Select all

int upFactor = out_freq / freq;
Results in upFactor=1 if there's no upscaling (e.g. 44khz->44khz), 2 if it's upscaling 2x (22->44), 4 if it's upscaling 4x (11->44), etc. Yet later on in convert_audio, it's simply checked for being non-0:

Code: Select all

auto &coeffs = upFactor ? coeffs_halfband : coeffs_quarterband;
The code would fail elsewhere if it was actually 0 (it would be trying to downscale 22khz->0hz or 11->0 or something), making it seem like an incorrect check, resulting in the wrong coefficients being used for one of the expected upscaling factors.
User avatar
KynikossDragonn
Posts: 272
Joined: Sat Dec 12, 2020 10:59 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Void Linux
Graphics Processor: Intel (Modern GZDoom)
Location: Independence, KS, USA
Contact:

Re: Any audio engineers around willing to take a look at this?

Post by KynikossDragonn »

Chris wrote: Sat Jan 07, 2023 6:14 pmYour recording is 48khz, not 44100
That's because PipeWire is resampling all audio to 48000 regardless of requested rate. The audio coming from DXX-ReBirth is still 44100, and I know the resampler in PipeWire isn't introducing this problem because the ringing is happening for other people, even on Windows.

A huge thanks for pointing out those problem areas, I'll be happy to forward this over to vLKp.
Post Reply

Return to “Off-Topic”