godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.15k stars 20.21k forks source link

Interpolation for sounds is based on resource type (audible distortion with slightly-higher-sample-rate .wav files) #58216

Open wareya opened 2 years ago

wareya commented 2 years ago

Godot version

3.4 and 4.1

System information

Windows 10

Issue description

.wav sounds are always played back with linear interpolation, and .ogg and .mp3 sounds are always played back with hermite interpolation. This causes noticeable harmonic distortion when playing back 48khz or higher .wav sounds on projects/systems configured to run at 44.1khz. On the other hand, the harmonic distortion on .ogg and .mp3 sounds is almost inaudible.

(This is technically aliasing, not harmonic distortion, but it's aliasing of the harmonic overtones generated by the interpolation algorithm, so calling it harmonic distortion is more intuitive.)

The user currently has no way to control this other than to store multiple sounds for different project sample rates. The interpolation method should either be configurable or just be hermite everywhere.

(If it's just hermite everywhere, then users that want the rich harmonic overtones you can get by using linear interpolation for ~8khz or ~16khz sound effects would instead be expected to pre-upsample to 44.1khz or 48khz with an external program.)

As discussed here, this is unlikely to have a significant performance impact on modern systems, because both interpolation methods are cache- and pipeline-friendly, involve relatively few operations, and only involve basic arithmetic (no trig).

Note:

This is distinct from getting aliasing with extremely high-sample-rate audio files (e.g. 96khz, 192khz). For example, right now, if you play back a 96khz file of any type that has an exactly 44000hz tone in it in a 44.1khz project, an aliasing tone will be heard at 100hz (with some harmonics). This will happen regardless of interpolation method because a destination nyquist frequency lowpass is not being done. So if someone opens such an issue in the future, it is not a duplicate of this issue, and this issue is not a duplicate of such an issue if such an issue is already open. I'm not sure whether that's should be considered a bug since nobody should really have audio files with audible tones above ~20khz, but it's worth noting.

Steps to reproduce

Play back a 48khz .wav with a lot of high pitched harmonic information in a 44.1khz godot project. Play back the same 48khz wav but converted to ogg (still 48khz). The .ogg will have significantly less harmonic distortion than the .wav.

https://user-images.githubusercontent.com/585488/154381162-84e84216-bd67-4af3-8fa3-f1fffec8fe07.mp4

image

In this test, there is significantly more distortion around 600hz with the .wav than with the .ogg.

Minimal reproduction project

No project, but a collection of loose files to test how things "should" sound:

https://github.com/godotengine/godot/files/8064241/entrance_bell_edit_original_and_resampled.zip

Load into a project configured to run at 44.1khz. entrance_bell_edit.wav and entrance_bell_edit.ogg are the original 48khz files. The _resample files were resampled by hand outside of godot to be 44.1khz instead. They both have more distortion, but the cubic/hermite resampling adds significantly less distortion (sounds like how the .ogg sounds in godot), as expected.

(The resampled files are larger because they're 32-bit instead of 16-bit, but that doesn't add any distortion.)

akien-mga commented 1 year ago

Is this still reproducible in 4.0 RC 3 or later?

wareya commented 1 year ago

Still an issue in Godot 4.x (tested in Godot 4.1.1 mono).