I currently try to repeat a sound every x ms - where x is dependent on an UDP packet I receive via socket - and I decided to use pygame for that. I used this SO answer to repeat something every x ms: https://stackoverflow.com/a/18954902/3475778
But now I have the problem, that the sound is played very irregular and made a minimal-working example where the problem persists:
import pygame
from pygame.locals import *
pygame.mixer.init()
sound = pygame.mixer.Sound('sound.wav')
def play_sound():
sound.stop()
sound.play()
pygame.init()
clock = pygame.time.Clock()
pygame.time.set_timer(USEREVENT+1, 200)
while True:
# clock.tick(30)
for event in pygame.event.get():
if event.type == USEREVENT+1:
play_sound()
Here is the waveform of what I have recorded from the script via Audacity:
You see that for some reason some samples were played longer than the others. Not very nice for some kind of metronome I want to build.
edit UPDATE: It is not a problem of pygame.time.set_timer, because this code doesn't solve the problem and doesn't rely on pygame.time.set_timer:
import pygame
from datetime import datetime
d = datetime.now()
pygame.mixer.init()
sound = pygame.mixer.Sound('horn_short.wav')
pygame.init()
while True:
if (datetime.now() - d).total_seconds() > 0.2:
sound.play()
d = datetime.now()
has the same problem. The Problem is also under Ubuntu 16.04, Python 3.5 64bit (Anaconda) and a fresh installed pygame.
For me the thing worked much better, if i did:
before any of the pygame
init
functions.Here is an idea for an alternative approach. If the goal is to play a sound in regular intervals, you might get better results if you (dynamically) pad the sound to the desired interval length, and then simply loop it with
Sound.play(loops=-1)
.If there are just a handful of valid intervals, it might be easiest to store dedicated sound files and load the appropriate one.
Otherwise, the
pygame.sndarray
module provides access to anumpy
array of the raw sound data, which makes it possible to dynamically generate sound objects of the desired length:Using just pygame (and numpy), this approach should have a good chance for an accurate playback.