We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 1857

Summary: SDL_PauseAudio(1) does not result in silence using the DirectSound backend
Product: SDL Reporter: ny00
Component: audioAssignee: 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.

Description ny00 2013-05-20 04:25:16 UTC
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.
Comment 1 Sam Lantinga 2013-05-21 03:52:09 UTC
Ryan, can you look at this for the SDL 2.0 release?
Comment 2 ny00 2013-05-25 10:02:33 UTC
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.)
Comment 3 Sam Lantinga 2013-05-26 17:40:08 UTC
Can you try that workaround?
Comment 4 Ryan C. Gordon 2013-05-26 23:34:36 UTC
(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.
Comment 5 ny00 2013-05-27 05:10:20 UTC
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.
Comment 6 ny00 2013-05-27 07:03:37 UTC
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.
Comment 7 ny00 2013-05-27 07:16:47 UTC
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.
Comment 8 ny00 2013-06-30 16:33:05 UTC
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!
Comment 9 ny00 2013-06-30 17:04:04 UTC
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...
Comment 10 Ryan C. Gordon 2013-07-12 00:04:07 UTC
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.
Comment 11 ny00 2013-07-12 04:24:51 UTC
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.
Comment 12 ny00 2013-07-12 08:15:51 UTC
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!
Comment 13 Ryan C. Gordon 2013-07-12 18:57:04 UTC
(In reply to comment #12)
> Thanks for fixing the bug!

You're welcome!  :)

--ryan.