SDL: SDL 3 Loopwave : Audio no output and code freeze on USB Headphone via PulseAudio driver

Reference in https://github.com/exult/exult/issues/379

Problem description

Test with loopwave, Linux Fedora 39, USB Headphones over PipeWire, the SDL default driver is PulseAudio => no audio output, and code freeze :

build/test/loopwave --log all
INFO: Available audio drivers:
INFO: 0: pulseaudio
INFO: 1: pipewire
INFO: 2: alsa
INFO: 3: jack
INFO: 4: dsp
INFO: 5: disk
INFO: 6: dummy
INFO: Using audio driver: pulseaudio
<- No audio output, code freeze, does not stop with Ctl-C, must use kill -9 from another session

The SDL drivers PipeWire or ALSA work OK :

SDL_AUDIO_DRIVER=pipewire build/test/loopwave --log all

The SDL driver Jack fails with :

DEBUG: Parameter 'dst_spec->channels' is invalid
ERROR: Couldn't create audio stream: Parameter 'dst_spec->channels' is invalid

The SDL driver DSP fails with :

DEBUG: dsp: No such audio device
ERROR: Couldn't initialize SDL: dsp: No such audio device

The PulseAudio ( pacat -p ) and Pipewire ( pw-cat -p ) play command lines work OK.

When the audio is routed to the PCIe Audio card to Loudspeakers - by switching off the Headphone -, then loopwave with PulseAudio works.

With loopwave via PulseAudio to the USB Headphone under GDB, at code freeze, break with Ctl-C, the GDB query threads returns :

(gdb) info threads
  Id   Target Id                                         Frame 
* 1    Thread 0x7ffff7f32480 (LWP 21213) "loopwave"      0x00007ffff7af71a3 in clock_nanosleep@GLIBC_2.2.5 () from /lib64/libc.so.6
  2    Thread 0x7ffff72ec6c0 (LWP 21216) "PulseMainloop" 0x00007ffff7b25bcd in poll () from /lib64/libc.so.6
  3    Thread 0x7ffff7fb96c0 (LWP 21217) "PulseHotplug"  0x00007ffff7aa9169 in __futex_abstimed_wait_common () from /lib64/libc.so.6
  4    Thread 0x7ffff2a756c0 (LWP 21218) "SDLAudioP27"   0x00007ffff7aa9169 in __futex_abstimed_wait_common () from /lib64/libc.so.6
(gdb) t 1
[Switching to thread 1 (Thread 0x7ffff7f32480 (LWP 21213))]
#0  0x00007ffff7af71a3 in clock_nanosleep@GLIBC_2.2.5 () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff7af71a3 in clock_nanosleep@GLIBC_2.2.5 () from /lib64/libc.so.6
#1  0x00007ffff7b09a37 in nanosleep () from /lib64/libc.so.6
#2  0x00007ffff7e61fa2 in SDL_DelayNS_REAL () from <edited>/SDL.git/build/libSDL3.so.0
#3  0x00007ffff7e628d4 in SDL_EnterAppMainCallbacks_REAL () from <edited>/SDL.git/build/libSDL3.so.0
#4  0x00007ffff7c59228 in SDL_EnterAppMainCallbacks () from <edited>/SDL.git/build/libSDL3.so.0
#5  0x0000000000404b59 in SDL_main ()
#6  0x00007ffff7c46e14 in SDL_RunApp_REAL () from <edited>/SDL.git/build/libSDL3.so.0
#7  0x00007ffff7c4c756 in SDL_RunApp_DEFAULT () from <edited>/SDL.git/build/libSDL3.so.0
#8  0x00007ffff7c55cb9 in SDL_RunApp () from <edited>/SDL.git/build/libSDL3.so.0
#9  0x0000000000404b82 in main ()
(gdb) t 2
[Switching to thread 2 (Thread 0x7ffff72ec6c0 (LWP 21216))]
#0  0x00007ffff7b25bcd in poll () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff7b25bcd in poll () from /lib64/libc.so.6
#1  0x00007ffff76c7536 in poll_func () from /lib64/libpulse.so.0
#2  0x00007ffff76b0694 in pa_mainloop_poll () from /lib64/libpulse.so.0
#3  0x00007ffff76bb163 in pa_mainloop_iterate () from /lib64/libpulse.so.0
#4  0x00007ffff76bb228 in pa_mainloop_run () from /lib64/libpulse.so.0
#5  0x00007ffff76cb741 in thread () from /lib64/libpulse.so.0
#6  0x00007ffff766dccb in internal_thread_func () from /usr/lib64/pulseaudio/libpulsecommon-16.1.so
#7  0x00007ffff7aac897 in start_thread () from /lib64/libc.so.6
#8  0x00007ffff7b336fc in clone3 () from /lib64/libc.so.6
(gdb) t 3
[Switching to thread 3 (Thread 0x7ffff7fb96c0 (LWP 21217))]
#0  0x00007ffff7aa9169 in __futex_abstimed_wait_common () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff7aa9169 in __futex_abstimed_wait_common () from /lib64/libc.so.6
#1  0x00007ffff7aabb09 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libc.so.6
#2  0x00007ffff76c85a4 in pa_threaded_mainloop_wait () from /lib64/libpulse.so.0
#3  0x00007ffff7df06b6 in HotplugThread () from <edited>/SDL.git/build/libSDL3.so.0
#4  0x00007ffff7ce2124 in SDL_RunThread () from <edited>/SDL.git/build/libSDL3.so.0
#5  0x00007ffff7e5e7a4 in RunThread () from <edited>/SDL.git/build/libSDL3.so.0
#6  0x00007ffff7aac897 in start_thread () from /lib64/libc.so.6
#7  0x00007ffff7b336fc in clone3 () from /lib64/libc.so.6
(gdb) t 4
[Switching to thread 4 (Thread 0x7ffff2a756c0 (LWP 21218))]
#0  0x00007ffff7aa9169 in __futex_abstimed_wait_common () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff7aa9169 in __futex_abstimed_wait_common () from /lib64/libc.so.6
#1  0x00007ffff7aabb09 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libc.so.6
#2  0x00007ffff76c85a4 in pa_threaded_mainloop_wait () from /lib64/libpulse.so.0
#3  0x00007ffff7def3cd in PULSEAUDIO_WaitDevice () from <edited>/SDL.git/build/libSDL3.so.0
#4  0x00007ffff7c33a19 in OutputAudioThread () from <edited>/SDL.git/build/libSDL3.so.0
#5  0x00007ffff7ce2124 in SDL_RunThread () from <edited>/SDL.git/build/libSDL3.so.0
#6  0x00007ffff7e5e7a4 in RunThread () from <edited>/SDL.git/build/libSDL3.so.0
#7  0x00007ffff7aac897 in start_thread () from /lib64/libc.so.6
#8  0x00007ffff7b336fc in clone3 () from /lib64/libc.so.6
(gdb) q

Complement information

  • PipeWire is installed as pipewire-(various-)1.0.0-2.fc39,

  • PipeWire provides a PulseAudio API in installed pipewire-pulseaudio-1.0.0-2.fc39,

  • The PulseAudio core pulseaudio-16.1-5.fc39 is not installed and cannot be installed because the installed pipewire-pulseaudio is in conflict,

  • The PulseAudio library pulseaudio-libs-16.1-5.fc39 is installed.

  • SDL 3 is at Git main of 2024-01-06, commit e100992c1, no mod.

About this issue

  • Original URL
  • State: closed
  • Created 6 months ago
  • Comments: 15 (2 by maintainers)

Most upvoted comments

I am glad to report that this PR #9473 fixes the hang in Exult choosing PulseAudio over PipeWire :

I have removed my SDL_AUDIO_DRIVER=pipewire, then tested my migration of Exult to SDL 3 in Linux, both in KDE over Wayland and in Gnome over Wayland. Both attempts chose PipeWire and worked.

Not only that, I also find quite nice the idea of having the PipeWire driver occurring twice in the Audio driver list, with the first occurrence having more stringent but possibly failing tests than the second and original occurrence, thus preserving compatibility.

In the name of the Exult team, I am proffering my thanks for this solution.