1

I'm using Pygame's mixer to play sounds in the background because it's non-blocking. However, while the sound plays fine, if I do something like use sleep() from the time module to wait for a specific moment, the audio begins to stutter badly while the sleep function is executed. I do it like this:

#Initialize mixer and load a sound file
pygame.mixer.init()
pygame.mixer.music.load("sound.mp3")

#Elsewhere in the code, play the loaded file and wait 5 seconds
pygame.mixer.music.play(-1,0.0)
time.sleep(5)

The sound plays, but it begins to stutter. The ALSA lib also complains about being overrun, so I initially thought this was due to everything running in a single thread by some scheduling means that switches back and forth between main code and pygame player's loop.

ALSA lib pcm.c:8545:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8545:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8545:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8545:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8545:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8545:(snd_pcm_recover) underrun occurred

I'm running this on a Raspberry Pi Zero 2, so I looked at the task manager to confirm this, and I did see three python processes to run (three seperate threads?) along with some relative struggle terminal

I tested this on my main x86 computer and there was no such issue, so I appear to be correct to some degree. But then I decided to test this further by letting the Python code run without pygame and then via another terminal, play the sound file with a CLI player like mpg123. This worked without issue, which to me either means that:

a) Pygame's player is just not fast and efficient at decoding the mp3 file

b) It's not very efficient at managing threads in order to run in the background

c) both possibilities apply.

I tried to use the os module to run mpg123 in the background by executing a shell command, which worked fine, but I found this to be a dirty solution, especially because the stdout stream was being printed in the terminal.

Additionally, I also attempted to start the mixer in its own thread like this:

def pygame_mixer():
    pygame.mixer.init()
    pygame.mixer.music.load("sound.mp3")
    pygame.mixer.music.play(-1,0.0)
thread.start_new_thread(pygame_mixer, ())

This did improve performance quite a bit, but if the timer is longer than one second, then it starts to stutter a little still. I don't get spammed by as many ALSA messages.

Why exactly is this happening? And what can I do to get around this?

Myronaz
  • 183
  • 1
  • 1
  • 10

0 Answers0