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)

-- 
Wine randomly cannot initialize sound [mmap() failed: ]
https://bugs.launchpad.net/bugs/502375
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.

-- 
ubuntu-bugs mailing list
ubuntu-bugs@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to