Pygame.error: Mixer not initialized

I am developing an arcade game in pygame which requires sound. I currently store my source code here. It uses pygame.mixer to generate and play sound waves. If I install it using sudo pip3 install git+https://github.com/tuxbert/outbreak/, everything seems to work as I would hope.

However, I am currently trying to produce a snap of the same package, and both pygame.mixer.pre_init pygame.init are called without raising an error. However, if I then try to use audio (e.g. running pygame.sndarray.make_sound), I get the following: pygame.error: Mixer not initialized

I am not sure why this is a problem for a snap, but not for a package installation via pip. Is there a stage-package, perhaps? My snapcraft.yaml is written as follows:

name: outbreak
version: 1.0.0
summary: A viral outbreak emerges! How long will you last?
description: |
  An arcade game in which the player must avoid being infested. Although there
  is initally only one host to the disease, as time passes, more and more
  people are contaminated, resultantly engaging in your pursuit. Some will lay
  eggs, from which more hatch, yet pop these eggs, and you may cure some of the
  infested.

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots

apps:
  outbreak:
    command: bin/outbreak

parts:
  outbreak:
    plugin: python
    python-version: python3
    source: https://github.com/tuxbert/outbreak.git
    source-type: git
    build-packages: []
    stage-packages: []
    python-packages: [numpy, pygame]

You probably should check out the snapcraft-alsa remote part

I’d recommend trying to use pulseaudio rather than alsa if that’s supported by pygame.

You’ll need to add libpulse0 to stage-packages and the following environment to your apps. The LD_LIBRARY_PATH stuff is needed because the pulseaudio libs live in a directory that’s not initially found, but adding this will fix that.

apps:
  outbreak:
    command: bin/outbreak
    environment: 
      "LD_LIBRARY_PATH": "$LD_LIBRARY_PATH:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pulseaudio"
2 Likes

I have done as suggested, although the problem persists as before. I don’t know if pygame supports pulseaudio. What changes should I be observing?

The shared object for pulseaudio is now found at the following path:
/snap/outbreak/x1/usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-8.0.so

I don’t know pygame much but actually the error you’re seeing implies you’re not doing pygame.mixer.init. I note you’re doing pygame.mixer.pre_init at https://github.com/tuxbert/outbreak/blob/master/outbreak/sound.py#L6 - is that related?

1 Like

My understanding of pygame.mixer.pre_init is that it sets certain constants. When pygame.init is called, it automatically calls pygame.mixer.init with these constants. After all, it works when I’m not building a snap.

I’m glad you asked though, because once I’ve changed the code to use pygame.mixer.init explicitly, it raises a more informative error, which is helpful.

pygame.error: No available audio device

Ok, that’s good I guess :). I think some research would be needed to figure out if pygame does indeed support pulseaudio or whether as suggested it can only use ALSA on Linux?

If it can only use ALSA then it’s possible to get working, but requires a chunk of boilerplate in your yaml.

One thing you can do to help debug is install the snappy-debug snap:-

snap install snappy-debug

Now, in a terminal, run snappy-debug.security scanlog and leave it running. Switch to another terminal and run your snap. You should see some output in the scanlog window which may hint what pygame is trying to do which is being denied. Maybe paste that here?

2 Likes

It printed the following output:

= AppArmor =
Time: Jan  1 09:46:05
Log: apparmor="ALLOWED" operation="open" profile="snap.outbreak.outbreak" name="/proc/6662/mounts" pid=6662 comm="python3" requested_mask="r" denied_mask="r" fsuid=1000 ouid=1000
File: /proc/6662/mounts (read)
Suggestions:
* adjust program to not access '@{PROC}/@{pid}/mounts'
* add one of 'mount-observe, network-control' to 'plugs'

I have tried adding these as plugs (one at a time) like so:

apps:
  outbreak:
    command: bin/outbreak
    plugs: [network-control]

The problem persists as before. Admittedly, I’ve never used plugs before, so I’m only guessing what to do here.

I’m not sure you need plugs if you’re building in devmode, but if you are adding them, you should try the pulseaudio plug to see if it helps.

1 Like