jarikomppa / soloud

Free, easy, portable audio engine for games
http://soloud-audio.com
Other
1.76k stars 276 forks source link

Stuttering / glitchy audio on Linux platforms #308

Open ghost opened 3 years ago

ghost commented 3 years ago

Expected behavior:

Sounds are played back normally on Linux platforms.

Actual behavior:

Sounds are played back, but there are distortions, stutters and glitches on Linux platforms. (at least on platforms I have tested: two computers running Ubuntu MATE 20.04 and Pop!OS 20.10). I have tried using different buffer sizes, but the issue persists.

Steps to reproduce the problem:

Compile and run any demo or run any precompiled Windows .exe through WINE on a GNU/Linux system.

The issue also persists on a game engine I am developing, which depends on Rust bindings for SoLoud: https://github.com/JackRedstonia/stacks

Here's a video of it: https://youtu.be/kF_B-ms32jM You can hear frequent 'pops' or stutters, especially at quieter parts of the song. On GNOME 3 and MATE, alt-tabbing also somehow causes short stutters (split-second silence).

This issue does not appear on my Windows installation, at least with the game engine.

SoLoud version, operating system, backend used, any other potentially useful information:

SoLoud version 20200207. OS: GNU/Linux, at least on Ubuntu MATE 20.04 and Pop!OS 20.10. Backend used: MiniAudio, though this issue seems to occur with any backend.

ghost commented 3 years ago

Temporarily closing, will do further tests.

ghost commented 3 years ago

Reopening, can confirm this occurs in any backend.

Green-Sky commented 3 years ago

I am running Ubuntu 18.04.5, same soloud version with the SDL2-static backend and have no problems.

Can you please add stuff like the soundserver you are using? (Pulseaudio, ALSA...) this is probably Pulseaudio... Also add samplerates, the one soloud reports, as well as the one the sound-server is using (eg. for pa pactl info can tell you this)

My System is running Pulseaudio and pactl info yields:

....
Server Name: pulseaudio
Server Version: 11.1
Default Sample Specification: s16le 2ch 44100Hz
....
Anuken commented 3 years ago

This is very likely to be Pulseaudio related. I use the MiniAudio backend, and although my Ubuntu PC had no issues with sound quality, many Linux users reported similar crackling. Disabling the MiniAudio Pulseaudio backend (-DMA_NO_PULSEAUDIO) fixed it for them.

Here's a video of it:

completely unrelated to the issue but I did a double-take when the video started playing, I've listened to that song so many times

ghost commented 3 years ago

@Green-Sky Thanks, I will report back as soon as I get home.

@Anuken Where should I put the -DMA_NO_PULSEAUDIO option? Is it a compiler flag or...?

Anuken commented 3 years ago

Yes, as a compiler flag. If you're defining WITH_MINIAUDIO for SoLoud somewhere, just define MA_NO_PULSEAUDIO in the same way.

ghost commented 3 years ago

Also, with ALSA backend and a buffer size of 860 @ 44.1kHz somehow made the problem go away... I do want lower buffer sizes though, which makes the problem go back.

I'll test if it is using PulseAudio when I can, and see whether -DMA_NO_PULSEAUDIO fixes the problem.

ghost commented 3 years ago

@Green-Sky I was indeed using PulseAudio, at least that's what -DMA_DEBUG_OUTPUT told me. This issue also persists with the ALSA backend somehow (except with buffer size of 860 which is odd). I use a sample rate of 44100Hz.

Here's the debug output of MiniAudio, if that's of any help:

[miniaudio] Endian:  LE
[miniaudio] SSE2:    YES
[miniaudio] AVX2:    NO
[miniaudio] AVX512F: NO
[miniaudio] NEON:    NO
[PulseAudio] Playback attr: maxlength=352, tlength=117, prebuf=-1, minreq=-1, fragsize=117; internalBufferSizeInFrames=88
[PulseAudio] Playback actual attr: maxlength=352, tlength=144, prebuf=120, minreq=28, fragsize=117; internalBufferSizeInFrames=88
[PulseAudio]
  Built-in Audio Analogue Stereo (Playback)
    Format:      32-bit IEEE Floating Point -> 16-bit Signed Integer
    Channels:    2 -> 2
    Sample Rate: 44100 -> 44100
    Buffer Size: 88/2 (44)
    Conversion:
      Pre Format Conversion:    NO
      Post Format Conversion:   YES
      Channel Routing:          NO
      SRC:                      NO
      Channel Routing at Start: NO
      Passthrough:              NO

Here's my pactl info:

Server String: /run/user/1000/pulse/native
Library Protocol Version: 34
Server Protocol Version: 34
Is Local: yes
Client Index: 51
Tile Size: 65472
User Name: reverb
Host Name: pop-os
Server Name: pulseaudio
Server Version: 13.99.2
Default Sample Specification: s16le 2ch 44100Hz
Default Channel Map: front-left,front-right
Default Sink: alsa_output.pci-0000_00_1f.3.analog-stereo
Default Source: alsa_output.pci-0000_00_1f.3.analog-stereo.monitor
Cookie: 3dae:759c

@Anuken Seems like the problem still persists with -DMA_NO_PULSEAUDIO. Audio still crackles with SoLoud compiled with the flag. Here's what I got in the console:

[miniaudio] Endian:  LE
[miniaudio] SSE2:    YES
[miniaudio] AVX2:    NO
[miniaudio] AVX512F: NO
[miniaudio] NEON:    NO
[ALSA]
  Default Playback Device (Playback)
    Format:      32-bit IEEE Floating Point -> 32-bit IEEE Floating Point
    Channels:    2 -> 2
    Sample Rate: 44100 -> 44100
    Buffer Size: 128/3 (42)
    Conversion:
      Pre Format Conversion:    NO
      Post Format Conversion:   NO
      Channel Routing:          NO
      SRC:                      NO
      Channel Routing at Start: NO
      Passthrough:              YES

Which confirms that it is using ALSA, not PulseAudio.

Green-Sky commented 3 years ago

except with buffer size of 860 which is odd

o.O

Which confirms that it is using ALSA, not PulseAudio.

the relationship of ALSA and PulseAudio on the same system is complicated iirc. PulseAudio uses ALSA to comunicate with the hw and acts as the ALSA server for clients(apps), or something.... (which means you might still be using PA, even if it tells you it uses ALSA, but idk tbh).

it would be interesting if you had any other application/game on the linux system that also produces broken sound. Also whether SDL audio is fine, since it is the most battle-tested one. Do you have easy access to sdl2 in your build? Alternatively play some games, use some apps that rely on SDL for audio.

Green-Sky commented 3 years ago

btw, I tried compiling your engine (https://gitlab.com/JackRedstonia/stacks/) but failed with

error: the option `Z` is only accepted on the nightly compiler

$ rustc --version : rustc 1.43.0

ghost commented 3 years ago

@Green-Sky I don't recall having any other program on my Linux system producing broken sound, unfortunately. SDL2 seems to work well with the engine it seems, no audio glitches with buffer size of 256 (soloud itself reports a backend buffer size of exactly half, which is 128), but that doesn't really mean the issue should be closed IMO because SDL2 itself is rather big, making it unfit for applications that just want to play sound and nothing else.

For the engine specifically though, SDL2 access is simply modifying Cargo.toml to use the soloud crate's sdl2 feature and running export CFLAGS="-I /usr/include/SDL2" && export CXXFLAGS="-I /usr/include/SDL2", as I suggested to the bindings maintainer just a few days ago. The sdl2-static feature doesn't want to work yet though, which is irrelevant & I should report to said maintainer.

BTW to compile the engine, you need the nightly toolchain for now. You can do that with rustup default nightly. I have written that in README.md, but it's all the way down in the middle of the already-long document and is not really obvious, so sorry again if I didn't make that more "PLEASE READ ME".

Green-Sky commented 3 years ago

SDL2 seems to work well with the engine it seems

nice, good to know

but that doesn't really mean the issue should be closed IMO

yes. this seems to be some SoLoud bug. one could look for similar looking issues even.

SDL2 itself is rather big

not by modern standards :P . but yea, on linux it pulls in not too few dependencies...

but it's all the way down in the middle of the already-long document and is not really obvious, so sorry again if I didn't make that more "PLEASE READ ME".

Oh well...

mackron commented 3 years ago

I'm the developer of miniaudio, and I'm pretty sure this is due to a bad device configuration. The buffer size is way too small. I suspect this is the offending line:

https://github.com/jarikomppa/soloud/blob/master/src/backend/miniaudio/soloud_miniaudio.cpp#L64

An experiment would be to change that to something like 2048 and see how that goes.

ghost commented 3 years ago

Even if the line isn't the one causing the bug in question, it is causing another bug where the aBuffer parameter isn't used, and as such the buffer size is always 128 despite what one feeds into Soloud::init.

Does MiniAudio support buffer sizes that aren't a power of 2?

mackron commented 3 years ago

Oh, I didn't even notice that aBuffer parameter!

So with the buffer size stuff, it's all up to the backend. It's technically just a hint - miniaudio will tell the backend what it wants, but the backend will be the one who ultimately decides what it actually gives you. Buffer sizes do not need to be powers of two from the perspective of miniaudio, but the backend itself may require it in which case it'll give you back a power of 2 buffer.

ghost commented 3 years ago

Alright, I'll go ahead and make a pull request to fix the parameter. Thanks for pointing that out.

ghost commented 3 years ago

I made a pull request #310 to address that. Hopefully that'll be sufficient for fixing this issue.

mackron commented 3 years ago

I think that should do the trick. Did that fix your specific issue?

Another thing that should be done at some point is to upgrade miniaudio because the version currently being used is over a year out of date and there's been a few changes regarding buffer management.

ghost commented 3 years ago

Did that fix your specific issue?

It did! For me the aBuffer parameter can go as low as 512 before having glitches.

upgrade miniaudio

I think you should open a PR for that, I'll checkout and see if it makes things a bit better.

ghost commented 3 years ago

Also, seems like I have proven my own claim of "this issue occurs on any backend" to be wrong once again, since I just got JACK to work again on my system (having REAPER break on me was half the motive for that, haha). I went with 48000Hz (buffer size doesn't seem to affect anything as seen in jack_init for some reason) and every problem mentioned in the original issue post didn't appear at all.

mackron commented 3 years ago

There's already a PR for that (not from me): https://github.com/jarikomppa/soloud/pull/294. Though that pull request itself is a bit out of date.

ghost commented 3 years ago

I think you can simply open a new PR superseding that one, not worth having one PR with 2 version upgrades IMO.

mackron commented 3 years ago

I don't use SoLoud myself (I occasionally scan it's issue tracker to catch potential miniaudio issues like this one) and there's no activity on this project at the moment so I'm not interested in spending time on it (would need to download, set up build systems, etc.)

JACK doesn't give you a choice on buffer sizes. You can't even give it a hint - it just gives you what it wants and leaves it to you to deal with (goes back to what I was saying earlier about how not all backends will use your requested buffer size).

ghost commented 3 years ago

Did some testing on Windows and while it all mostly works fine, something I have noticed on both Windows and Linux is that the audio distorts rather noticeably when it is loud enough. Probably clipping.

Lowering the volumes does not help, it simply makes the distortions a bit quieter, but even down to volume 0.1 it is still there, almost as if the clipping was done at the audio file decoder level.

For example when playing an .ogg of "Camellia - OOPARTS" you will easily notice it right at the start of the song. This doesn't occur with other applications on my systems playing back the same file, so I don't think this is an issue with either my system or my headphones.

I will report back with a video recording when possible.

Anuken commented 3 years ago

the audio distorts rather noticeably when it is loud enough

I've had strange problems with seemingly-random ogg files (and only ogg files) causing intense distortion and clicking, regardless of their volume.

For example when playing an .ogg

What happens when you play the same song as an MP3 instead?

ghost commented 3 years ago

@Anuken playing the song with MP3 or WAV still results in the same distortions. I tested different songs with OGG, MP3 and WAV using both Wav and WavStream, and the distortions are always there.

ghost commented 3 years ago

I have written a simple program in Rust that plays back an .ogg file, and it seems that with the same file, my program does not introduce any distortion or clicking. I strongly believe the distortion in SoLoud is either excessive clipping and/or incorrect decoding in some stage in the pipeline.

JoelOtter commented 2 years ago

I'm noticing this with the MiniAudio backend in the case where audio is being played through my monitor (DisplayPort) - with my USB headphones it is fine. The sound is garbled and then sort of repeats itself, backwards, a few seconds later. With Bluetooth headphones it sounds like there's a frequency mismatch or something; it's lower in pitch and longer than it ought to be.