my dsound/winealsa hacks

Tomas Carnecky tom at dbservice.com
Fri Sep 22 06:06:50 CDT 2006


My ultimate goal was to solve the dsound underruns which were so 
horrible that I had to disable sound in World of Warcraft. While I 
managed to get the sound working flawlessly (really... I never heard 
such clear sound under wine) in WoW, it required WoW-specific hacks so 
my patch will never make it (in its current form) into the official git 
tree, but maybe someone can use some of my ideas to improve dsound/winealsa.

The basic idea is to let alsa mix the sound instead of the infamous 
dsound mixer. The advantage is that if the hardware supports mixing, 
there is very little overhead, if not, there's still dmix which can do 
that, but dsound doesn't need to care how it's done, it's entirely up to 
alsa.

Now to the actual implementation, it's pretty straight-forward: I 
'forced' CreateSoundBuffer to create a hardware buffer (right now it 
creates a hw buffer only for the primary buffer) and changed the 
winealsa driver to support that. Because winealsa driver opens only one 
'connection' (snd_pcm_t) to the soundcar (allowing only one buffer per 
device), I simply opened a new 'connection' for each buffer and 
configured the hardware for 44100Hz/U16LE/stereo (that's what WoW 
expects). Up to this point it was easy.
One of the big problems was that WoW requests a 16kb buffer, but alsa is 
unable to allocate a buffer with this exact size, and it caused problems 
if I passed the alsa buffer to WoW (so WoW could write directly to it). 
I had to allocate a separate buffer, keep track of the play/write 
positions in both buffers and copy the data from one to the other.
I'm fairly sure this all could be done in a WoW-independent way, eg. 
configure the hardware as the application requests it (by passing 
LPCDSBUFFERDESC to the low-level driver etc) and keeping track of the 
read/write positions could also be done in a better way.

There are a free questions that should be answered before someone can go 
on and make a 'proper' implementation. I simply bypassed the primary 
buffer, it doesn't exist since the data from the secondary buffers are 
written directly to the soundcard. If it should be possible to read the 
data from the primary buffer then we should forget this all and look for 
another solution. I believe that it's not possible (it's not possible to 
write to the primary buffer and the API doesn't differentiate between 
reads and writes), but someone should test that under windows.
(this is only one question but I'm sure you'll come up with more ;) )

Here is the complete patch, I also changed the IDirectSound interface 
and a lot unrelated code, so the patch is a bit big :-/ There also are a 
few memory leaks, I didn't bother freeing the memory etc.
http://dbservice.com/ftpdir/tom/dsound-alsa.patch

tom




More information about the wine-devel mailing list