Comment 10 for bug 502375

I have confirmed that this is a bug in Pulseaudio. If it is disabled, Wine runs without a problem.

Alternatively, I have made a hack that works 100% on my PC and that I will share with you, hoping you will correct bad stuff I might have made here.

=== Hack ===

The trick I'll be using is redirecting Pulseaudio to use dmix and the like. This has its disadvantages: worse latency, double-mixing, but I haven't noticed them. However, I won't just let all the other apps use ALSA directly: I am going to edit alsa-lib's sources to trigger a change so that every device other than wine-default gets redirected to pulse.

There was *probably* a better way to do this, but I couldn't find it.

DO NOT FORGET TO BACKUP ANY FILES THAT I TELL YOU TO EDIT.

====== Step 1:

 Open up your ~/.asoundrc file. Delete everything in it (I mean everything) and paste the following in there:

== PASTE THE FOLLOWING: ==
# ALSA library configuration file

# Include settings that are under the control of asoundconf(1).
# (To disable these settings, comment out this line.)
#</home/jorl17/.asoundrc.asoundconf>
# ALSA library configuration file managed by asoundconf(1).

# Old Conf
defaults.pcm.nonblock 0
defaults.namehint.showall on
defaults.namehint.basic on
defaults.namehint.extended on
pcm.pulse {
type pulse
}

ctl.pulse {
type pulse
}

#pcm.!default {
# type pulse
#}

pcm.!dmixer {
        type dmix # plugin type
        ipc_key 5678293 # unique ipc id
        ipc_perm 0666 # would like to use icp_group instead
        ipc_key_add_uid no # share the same mixer with all users
        slave {
                pcm "hw:0,0"
                period_time 0 # needed by oss (= 0)
                period_size 1024 # needed by oss (= 2^n)
                period_size 8192 # needed by oss (= 2^n)
                format S32_LE
                rate 48000
        }
}
pcm.!dsnoop:0 {
        type pulse
}

== END PASTE THE FOLLOWING ==

This makes ALSA set its default device to dmix:0 and dsnoop:0, I believe. Since dsnoop:0 is used for input, we set it to pulse (Wine doesn't seem to have a problem with that).

====== Step 2:

Then, we will make Pulseaudio load up without blocking ALSA.

Edit /etc/pulse/default.pa (or make a user-specific config). Look for the line that reads "load-module module-udev-detect" (around line 54 and comment it out, by putting a '#' before). Then, scroll down to the end of the file and paste the following:

load-module module-alsa-source device=dsnoop:0
load-module module-alsa-sink device=dmix:0

That now makes Pulseaudio go through dmix and dsnoop. Maybe the dsnoop:0 part could be changed to something better, but I can't think of it right now.

====== Step 3:

We should now have Pulseaudio going through ALSA, but other devices will not go through Pulseaudio, since alsa's '!default' PCM isn't set to do that (which is something that we do not want). So, how do we get everything EXCEPT for Wine to go through the 'pulse' PCM that we created before?

My trick was to edit alsa-lib right at the source:

   sudo apt-get build-dep alsa-lib
   apt-get source alsa-lib
   cd alsa-lib-*

Now, we'll edit the snd_pcm_open() function:

   gedit src/pcm/pcm.c

Look for the line "int snd_pcm_open(snd_pcm_t **pcmp, const char *name, ", around line 2235. Then, modify that function so that it looks like this:

=== START MODIFIED FUNCTION ===
int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
   snd_pcm_stream_t stream, int mode)
{
 int err;
 assert(pcmp && name);
 err = snd_config_update();
 if (err < 0)
  return err;

 /**
  Using Jorl's Pulseaudio hack, I'd like to have all alsa audio going to
  a pulse device. Yet, I'd like to have wine direct itself to another one.
  To do this, we check for the wine- prefix!
 **/
 if (strcmp(name,"wine-default")==0) {
    printf("[ALSA-JORL]: Renaming wine-default to default.\n"); fflush(stdout);
    return snd_pcm_open_noupdate(pcmp, snd_config, "default", stream, mode, 0);
 } else if (strcmp(name,"default")==0 || strcmp(name,"default:0")==0) {
    printf("[ALSA-JORL]: Renaming default to pulse.\n"); fflush(stdout);
    return snd_pcm_open_noupdate(pcmp, snd_config, "pulse", stream, mode, 0);
 }

 return snd_pcm_open_noupdate(pcmp, snd_config, name, stream, mode, 0);
}
=== END MODIFIED FUNCTION ===

You can freely remove the printf() lines and comments, since I used those for debugging and organization over here.

Do you see what we are doing? It's very simple indeed! We check if somebody tried to open a device called wine-default and, knowing that will be Wine (we'll force it to do it), we rename that to default, which turns to dmix:0 and dsnoop:0 (which goes to pulse!). If it is looking for default (or default:0, which is often used too), we redirect it to pulse.

Now we have to compile and install it. BEWARE that I didn't seem to be able to fully uninstall it from this point on, but I don't need to either:

   make && sudo make install

That should have done it. You can check it by restarting ALSA & Pulse and running aplay to see if it turns out in pavucontrol. If it does, then default is being converted to pulse.

====== Step 4:

We now need to do only one last thing: Force Wine to 'request' for the wine-default device. Simple:

Run wine regedit and then create the following key:

Software\\Wine\\Alsa Driver (that is: Create 'Alsa Driver' in Software\\Alsa).

Then, create the following text values (REG_SZ) in that key, giving them the respective values (without the quotes):

"AutoScanCards" set to "N"
"DeviceCount" set to "1" -- Note that this is the amount of cards you have, it might depend on your configuration.
"DevicePCM1" set to"wine-default"

An easy way to do this without editing is just opening up your ~/.wine/user.reg file and pasting this there:

[Software\\Wine\\Alsa Driver] 1271518902
"AutoScanCards"="N"
"DeviceCount"="1"
"DevicePCM1"="wine-default"

====== Step 5:

Enjoy! It may be ugly and hack-ish, but it's been working great for me! You can even add more devices to redirect, so if somebody tries to directly access dmix:0 you can direct that to pulse, so that only Wine uses it (beware that pulseaudio itself is opening up dmix:0, so we might have the need for a pulse-dmix device, hehe!). This way, there will only be double-remixing when Wine is running sound!

Any tips or proper fixes for the bug, do say. I have used the most recent pulseaudio to no avail, it still had issues...

Cheers,

João Ricardo Lourenço (jorl17)