| Summary: | SDL_CloseAudio takes 2 seconds to return when using the Pulseaudio driver. | ||
|---|---|---|---|
| Product: | SDL | Reporter: | rgrocottbugzilla |
| Component: | audio | Assignee: | Ryan C. Gordon <icculus> |
| Status: | RESOLVED ENDOFLIFE | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | CC: | stsp2 |
| Version: | 1.2.14 | ||
| Hardware: | x86 | ||
| OS: | Linux | ||
| Attachments: |
Testcase.
Patch to fix the delay when closing the ALSA and Pulse drivers. SDL 2.0 pulseaudio patch |
||
Did a little more testing. Setting the audio driver to alsa rather than pulse has no effect on the bug, presumably because ALSA is emulated as a client of the PulseAudio server. However, setting it to esd removes the bug. My system has a universal sound latency of around 500ms; I've always presumed it was some sort of driver issue. When terminating the loopwave test with Ctrl+C (using the esd driver), the program will stop running as soon as this latency is over (that is, as soon as sound stops coming out the speakers). Using the pulse and alsa drivers, loopwave will keep running for an additional 1 - 2 seconds beyond this point. Decided to attempt to fix this bug myself. The delay occurs in SDL_pulseaudio.c, within the call to pa_mainloop_iterate around line 427. This call blocks waiting for completion of an asynchronous pa_stream_drain operation, initiated earlier in the same function. This bug can be trivially solved by replacing the call to pa_stream_drain with a call to pa_stream_flush, which discards the data rather than waiting for a guarantee that it's finished. PS: The above fix wouldn't resolve the same problem in the ALSA driver, when ALSA is being emulated on a Pulse system. I haven't tested this, but I believe the issue could be fixed in a similar way by replacing the call to snd_pcm_flush (in ALSA_CloseAudio) with snd_pcm_drop. Created attachment 839 [details]
Patch to fix the delay when closing the ALSA and Pulse drivers.
Sorry for the comment spam, but I forgot to mention: The above patch was generated against the current SDL-1.2 branch of hg. Should also be relevant to SDL2, although I haven't checked that it will apply as-is.
Is dropping the last buffer of audio the correct approach, though? If you had a music player, should it cut off the last half second of a song so the process can quit quickly?
This bug is real, but I think the culprit is PulseAudio and not SDL:
http://pulseaudio.org/ticket/866
We mentioned this in Bug #1013, in regards to SDL_mixer, at one point.
The gist is that we need to tell PulseAudio "wait until you've definitely played what we asked you to and get back to us" and it waits way too long.
I suppose we could work around this in SDL by timing out how long it should take for Pulse to play all our data and just quitting at that point, but that's a goofy solution, too.
--ryan.
Am I right in thinking that patching library or application X to accommodate a difficult-to-fix or widely-deployed bug in library Y isn't usually done in FOSS circles, then? I mean, I'd personally go for the more pragmatic option of patching X, but I can see how that could turn X into a hackjob in the long run. Philosophical issues aside, though, I'd say that dropping ~500ms of trailing audio will be less harmful in the general case than halting on shutdown for 2s. It's worth noting that without explicitly working around this bug by calling SDL_QuitSubSystem(SDL_INIT_VIDEO) before SDL_CloseAudio, SDL will always close down the audio subsystem before video; therefore, practically all SDL applications that use both audio and video (ie, games) will suffer from an ugly 2-second pause on closing, with an unresponsive window still visible to the user. I haven't tested this broadly, but I can at least confirm that it applies to Frets on Fire. Me too on this bug. I'd like to note that the problem does NOT depend on how much audio was played and when. For me it pauses for 3 seconds even if SDL_PauseAudio(0) was never called at all, and the sound callback was never called. So I am not sure if the Comment 6 applies well. Or is the PA bug so bad that it hangs even when nothing was played? Created attachment 1415 [details]
SDL 2.0 pulseaudio patch
I don't think we actually need to wait for the drain operation to complete. Can you try out this patch and see if it:
a) solves your issue
b) you actually hear all the audio from the application as it quits?
Thanks!
For me the problem no longer happens. I think because of the new pulseaudio-5.0. Tested with SDL-1.2.15 and SDL2-2.0.3 without any patches - all good. Hello, and sorry if you're getting several copies of this message by email, since we are closing many bugs at once here. We have decided to mark all SDL 1.2-related bugs as RESOLVED ENDOFLIFE, as we don't intend to work on SDL 1.2 any further, but didn't want to mark a large quantity of bugs as RESOLVED WONTFIX, to clearly show what was left unattended to and make it easily searchable. Our current focus is on SDL 2.0. If you are still having problems with an ENDOFLIFE bug, your absolute best option is to move your program to SDL2, as it will likely fix the problem by default, and give you access to modern platforms and tons of super-cool new features. Failing that, we _will_ accept small patches to fix these issues, and put them in revision control, although we do not intend to do any further official 1.2 releases. Failing that, please feel free to contact me directly by email (icculus@icculus.org) and we'll try to find some way to help you out of your situation. Thank you, --ryan. |
Created attachment 838 [details] Testcase. When SDL_CloseAudio is called on the pulse backend, a delay of around 2 seconds will sometimes occur (about 50% of the time). The rest of the time, the function returns almost immediately. A testcase is attached. My OS is a fairly vanilla installation of Ubuntu 11.04.