| Summary: | WASAPI: No sound on Windows 10, glitchy playback under Wine 1.6.2 (Windows 7), and a choppy playback when processing powerful music codecs. | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Vitaly Novichkov <admin> |
| Component: | audio | Assignee: | Ryan C. Gordon <icculus> |
| Status: | RESOLVED INVALID | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | CC: | admin, contact, olav.sorensen, sezeroz |
| Version: | HG 2.1 | Keywords: | target-2.0.10 |
| Hardware: | x86_64 | ||
| OS: | Windows 10 | ||
| Attachments: |
Why SDL_setenv workaround is BAD
A working test of latest SDL 2.0.9 for Windows |
||
|
Description
Vitaly Novichkov
2018-01-26 14:59:50 UTC
Yes, SDL2 started to get audio problems when they started using WASAPI on Windows. My programs also get choppy/cracking/popping audio on some machines, and making the audio buffer size higher doesn't fix it. Very frustrating... It was all good before the transition, but then you didn't get the "hot swap" audio device support. The worst part is that there's no way to turn WASAPI off unless you build SDL2 yourself. Very annoying though, because I don't want to rebuild SDL2.dll, I want to use the original one where they used the optimal compiler settings etc. Having a hint for disabling it would be fantastic, as WASAPI on SDL2 is known to have problems for some people, including me. (In reply to Olav Sørensen from comment #2) > Having a hint for disabling it would be fantastic, as WASAPI on SDL2 is > known to have problems for some people, including me. SDL_setenv(“SDL_AUDIODRIVER”, “directsound”, 1); SDL_Init(SDL_INIT_AUDIO); --ryan. > (In reply to Olav Sørensen from comment #2) > > Having a hint for disabling it would be fantastic, as WASAPI on SDL2 is > > known to have problems for some people, including me. > > SDL_setenv(“SDL_AUDIODRIVER”, “directsound”, 1); > SDL_Init(SDL_INIT_AUDIO); > > --ryan. Yeah, but (to don't break compatibility with other platforms, or SDL will cry for an unknown audio driver) #ifdef _WIN32 SDL_setenv(“SDL_AUDIODRIVER”, “directsound”, 1); #endif SDL_Init(SDL_INIT_AUDIO); Also, It's my clunky but working workaround I use in my project to avoid WASAPI appearance in building libraries. https://github.com/WohlSoft/PGE-Project/blob/master/_Libs/_sources/___build_script.sh#L139-L142(In reply to Ryan C. Gordon from comment #3) Created attachment 3170 [details]
Why SDL_setenv workaround is BAD
Okay, the using of SDL_setenv workaround is BAD.
Why?
On some computers DirectSound is not available, therefore WinMM will be is the use. DirectSound is a better choice than WinMM, but in some cases usage of DirectSound is impossible.
So, the best solution is an ability to natively disable WASAPI which is still glitchy on many systems.
Do you have a test case to reproduce this problem? We haven't seen any problems with WASAPI in our applications and DOTA 2 is starting to use it as the default audio driver. The WASAPI has a number of benefits on modern systems (hot plugging, better resampling support, etc.) and is the native Windows API, which makes it preferred over the other options. Yes! Try to compile this project: https://github.com/Wohlstand/libADLMIDI Use next setup (no matter MinGW or MSVC. Myself I always using MinGW and having the issue with WASAPI case): ``` md build cd build cmake -DWITH_MIDIPLAY=ON .. make -j 5 ``` Then, force SDL2 to use WASAPI and try to play any MIDI file via "adlmidiplay.exe" utility, for example: ``` set SDL_AUDIODRIVER="wasapi" adlmidiplay.exe "C:\Windows\Media\onestop.mid" -fp --emu-nuked 68 ``` P.S. The source code of simple player itself where is a usage of SDL Audio was done: https://github.com/Wohlstand/libADLMIDI/blob/master/utils/midiplay/adlmidiplay.cpp Absolutely similar issue is on my fork of SDL Mixer where the plugin for libADLMIDI is here: https://github.com/WohlSoft/SDL-Mixer-X/blob/master/src/codecs/music_midi_adl.c One note: Most of the issues are happens when you are using Nuked OPL3 emulator chosen on the libADLMIDI side. When the DOSBox OPL3 emulator was chosen, it has fewer issues on real Windows 7. The test with DOSBox emulator: ``` set SDL_AUDIODRIVER="wasapi" adlmidiplay.exe "C:\Windows\Media\onestop.mid" -fp --emu-dosbox 68 ``` By the mean irony, absolutely SAME thing outputs audio stream fine through WinMM and DirectSound overlays. Quick question: does it's a matter which compiler was used? This bug is reproducible when using vanilla MinGW toolchains (http://mingw.org/), but I have didn't tested MinGW-w64 case (I making 64-bit builds through it, but I have didn't tested it yet myself). I never using MSVC except for super-rare cases. So just call a function like this when you initialise the audio then?
void sdl_init_audio_not_wasapi()
{
int i;
SDL_AudioQuit(); // quit the current audio driver, probably wasapi
// Init the first driver that isn't wasapi
for (i = 0; i < SDL_GetNumAudioDrivers(); ++i)
if (strcmp("wasapi", SDL_GetAudioDriver(i))) // if the driver isn't called "wasapi"
{
SDL_AudioInit(SDL_GetAudioDriver(i)); // initialise it
return ;
}
}
No real need for #ifdef _WIN32 since all it does is go through the list of drivers and pick the first one not called "wasapi".
For reference here for me the list of drivers is:
0: wasapi
1: directsound
2: winmm
3: disk
4: dummy
So this function picks directsound and would fall back to winmm were that to be missing.
Created attachment 3494 [details]
A working test of latest SDL 2.0.9 for Windows
Okay, just now I have tried to test on all my systems, and I see that WASAPI is now much better than in previous times!
I have built the ready-to-use test that was failed with the previous SDL2 versions, but works fine on latest!
Okay, I can see next: ``` - Audio wanted (format=S16,samples=3528,rate=44100,channels=2); - Audio obtained (format=F32,samples=661,rate=44100,channels=2) ``` Looks like WASAPI accepts Float32-only and can't PCMS16. In past, I have passed S16 stream as-is with no any conversions. For now, I doing the generating of the stream into the requested format to avoid any post-conversions of output. I have done tests on the next platforms: - Wine 3.20 (set into Windows 7) - Windows 10 - Windows 7 And now everything works fine! I also remember that some time ago you had troubles with sample conversions, and one of them I have fixed by myself. I was using the 2.0.8 SDL2.dll until today and it worked fine, but since I just switched to the 2.0.9 SDL2.dll I get the WASAPI bug and I now have to call the function I posted above to skip WASAPI. It made the sound play back about two times too fast and all cracked and skippy, so there seems to be a regression in the 2.0.9 DLL (compiling against the 2.0.9 .lib but still using the 2.0.8 DLL worked fine). And yet I tried Vitaly's MIDI test and all 3 outputs worked fine, so maybe it's down to my code. I requested a sample rate of 44100, AUDIO_F32 format, 2 channels, a buffer of 2048 samples and only called the legacy SDL_OpenAudio() function. Okay I should have looked at my own logs, it says I asked for 2048 samples but it gave me 981, and the rest of my code didn't take that new size into account. Before WASAPI I never failed to obtain the 2048 samples I asked for so that was never a problem, but it's just down to bad coding from me. So problem solved. Tagging a bunch of bugs with "target-2.0.10" so we have a clear list of things to address before a 2.0.10 release. Please note that "addressing" one of these bugs might mean deciding to defer on it until after 2.0.10, or resolving it as WONTFIX, etc. This is just here to tell us we should look at it carefully, and soon. If you have new information or feedback on this issue, this is a good time to add it to the conversation, as we're likely to be paying attention to this specific report in the next few days/weeks. Thanks! --ryan. It looks like this is taken care of now. Thanks everyone! |