I am trying to play an audio file in a loop (this example repeats it 3 times). The audio file is very short. It is just someone saying "Hello, world".
import pygame
def wait_for_player():
while pygame.mixer.music.get_busy():
continue
def play_file(filename):
pygame.init()
pygame.mixer.music.load(filename)
for i in range(3):
pygame.mixer.music.play()
wait_for_player()
if __name__ == '__main__':
play_file('hello_world.mp3')
What I hear sounds like this:
"Hello, world"
"o, world"
"o, world"
That is, the audio is clipped briefly at the beginning on subsequent replays. On a different device the same code and the same audio file sounds like this:
"o, world"
"Hello, world"
"Hello, world"
Each of these devices used bluetooth - one on a Raspberry Pi, the other on a Windows laptop. I tried again on a couple other devices without bluetooth and each time the audio played correctly. So maybe it's a bluetooth problem.
I tried padding a second or two of silence before the "hello", but it made no difference (except for spacing out the timing between each play - the audio was still clipped as it was without the padded silence).
My next step is to pad with a (hopefully) imperceptible bit of audio to "prime the pump", but I would rather have code that works than a workaround. Is there anything I can do programatically to ensure the entire sound plays each and every time?
ETA: Here is my workaround. I copied this gist into tone.py. It wraps around mixer.Sound to make it easy to play a note. The modified code below plays a low frequency note at low volume. This is enough to "prime the pump" and it now works on all devices. It's still a workaround, so hopefully someone will have a better answer - but I can go live with this if I have to.
from time import sleep
import pygame
from tone import Note
def wait_for_player():
while pygame.mixer.music.get_busy():
continue
def play_file(filename):
pygame.init()
Note(0.08, volume=0.01).play(-1)
sleep(1)
pygame.mixer.music.load(filename)
pygame.mixer.music.play(loops=3)
wait_for_player()
if __name__ == '__main__':
play_file('hello_world.mp3')
Here is my workaround. I copied this gist into tone.py. It wraps around mixer.Sound to make it easy to play a note. The modified code below plays a low frequency note at low volume. This is enough to "prime the pump" and it now works on all devices. It's still a workaround, so hopefully someone will have a better answer - but I can go live with this if I have to.
from time import sleep
import pygame
from tone import Note
def wait_for_player():
while pygame.mixer.music.get_busy():
continue
def play_file(filename):
pygame.init()
Note(0.08, volume=0.01).play(-1)
sleep(1)
pygame.mixer.music.load(filename)
pygame.mixer.music.play(loops=3)
wait_for_player()
if __name__ == '__main__':
play_file('hello_world.mp3')