| Summary: | SDL_PauseAudio(1) does not result in silence using the DirectSound backend | ||
|---|---|---|---|
| Product: | SDL | Reporter: | ny00 |
| Component: | audio | Assignee: | Ryan C. Gordon <icculus> |
| Status: | RESOLVED FIXED | QA Contact: | Sam Lantinga <slouken> |
| Severity: | blocker | ||
| Priority: | P1 | ||
| Version: | HG 2.0 | ||
| Hardware: | x86 | ||
| OS: | Windows (XP) | ||
| Attachments: |
A sample code mockup
A patch restoring SDL 1.2 behaviors of filling a buffer with silence, but only during a pause. |
||
Ryan, can you look at this for the SDL 2.0 release? Thanks for handling that. It probably worths to mention a possible workaround/solution for the bug: Set the buffer's contents to silence, as done in SDL 1.2, but only when a pause begins. However, it may really be just a workaround, and I haven't even checked it does its job... (The way the SDL 1.2.14 code is structured hints it should work, though.) Can you try that workaround? (In reply to comment #3) > Can you try that workaround? Having not actually looked at this yet, I suspect this is definitely our bug and it's easy to fix. I'll get to this soon. --ryan. Created attachment 1151 [details]
A patch restoring SDL 1.2 behaviors of filling a buffer with silence, but only during a pause.
I have just attached a simple patch that basically sets the buffer's contents to silence during a pause (not just when the pause begins), based on SDL 1.2 code.
Unfortunately I couldn't test it. Chances are it's just me doing something wrong, while cross-compiling from Ubuntu 12.04 (for x86-64) using MinGW-w64 (to construct a 32-bit Windows DLL file).
If you wonder, I called "autogen.sh" first and later called "configure" with a line like this:
../configure --host=i686-w64-mingw32 --prefix=/path/to/SDL2_inst
After using "make", it fails at the linking stage with an error like this:
build/.libs/SDL_dxjoystick.o: In function `IsXInputDevice':
/path/to/SDL_mercurial/mingw-w64/../src/joystick/windows/SDL_dxjoystick.c:417: undefined reference to `_IID_IWbemLocator'
I didn't have a problem building the DLL before. Nevertheless, maybe I just did something different (and wrong) this time.
Alright, about my recent failed attempt to build the SDL2.dll, I have found the following: - For now I should never touch autogen.sh and simply used the existing "configure" script from the repository. - Apparently changeset 76fa20889de8 is the cause of the linking failure. In contrary to what's described there, though, I could build SDL2.dll with no clear compilation error from 2435b221d77d. Guess it's time for a new bug report. Considering this report, I should apply the patch to 2435b221d77d (which is what I can build) and check this. Well, looks like the current workaround does its job! It may increase the CPU usage (for the audio thread) by a significant factor during a pause, though. Hey, I have noticed that the bug can also be reproduced on Windows 8.1 this week. Apparently, while the file SDL2.dll found in a current revision of SDL2-2.0.0.zip (Release Candidate) has the XAudio2 backend (as reported by "grep"), SDL_AUDIODRIVER=xaudio2 does not do the job and an app cannot load as expected. The DirectSound and WinMM backends can still be used. Maybe it's related to the fact I have used some form of MinGW and/or run Win8.1 in a VM. Back to the bug itself (i.e. the DirectSound case), thanks again for handling this! Should've added this: Of course, the given Windows 8.1 release is a preview. It's true that I don't remember checking for the bug on Windows 7 or 8 so far, though... This is fixed in hg changeset db8a19d767d7, which restores the SDL 1.2 behavior. I want to rewrite this code after 2.0 ships, though, and one of the improvements will be letting the lower-level drivers handle pauses instead of the higher level writing silence. For now, though, this will do. --ryan. Hey Ryan, Thanks for committing the patch. I am afraid it does not fix the bug, though. As before, while the audio device is paused, all that the involved loop really does in a single iteration is sleep for a bit. So practically the patch does not change the behaviors (except for a possible race condition coming from the usage of a secondary thread). Note that I have not yet tested this (just because it'd take a little while to build the DLL or wait for an automatic build...) but I think it's better to report this now, nevertheless. It also worths to mention there is the alternative streamer-specific code (currently untouched by the patch), but it seems to be unused at the moment. Guess what? I should have really checked a bit more of this... because the bug *is* fixed, after all. Basically, I was checking a few of the file's contents after a commit was applied: http://hg.libsdl.org/SDL/file/fb02213c11d3/src/audio/SDL_audio.c To compare, after updating a local copy of the tree, I could see that the short sleep is gone. I have just realized that you've spotted this on your own and applied a second commit, though. Thanks for fixing the bug! (In reply to comment #12) > Thanks for fixing the bug! You're welcome! :) --ryan. |
Created attachment 1144 [details] A sample code mockup When the DirectSound backend is used and a call of the form SDL_PauseAudio(1) is done in the middle of sound playback, you can still hear a portion of the sound being replayed in loop before a call of the form SDL_PauseAudio(0) is executed. For a simple example you can check the given code, which has been built into a GNU/Linux executable with GCC and a Windows exe with MinGW-w64 GCC. Some more details: - The bug is not reproduced with a build of SDL 1.2.15, using the DirectSound and WaveOut backends. Based on a quick comparison of copies of SDL_audio.c, it is apparently the case since the buffer passed to the audio callback is always initialized to zeros on 1.2 (during a pause or playback), while this is not the case with 2.0 (since it usually gets filled with contents in the program later anyway). - It should also be noted this is not reproduced with SDL 2.0 while using any of the WinMM, ALSA and PulseAudio backends.