Pygame.mixer.Sound.play is irregular, although it leaves regularly

I am currently trying to repeat the sound every x ms - where x depends on the UDP packet I receive through the socket - and I decided to use pygame for this. I used this SO answer to repeat something every x ms: stack overflow

But now I have a problem that the sound plays very irregularly and makes 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 recorded from the script through Audacity:

enter image description here

You see, for some reason, some samples reproduced longer than others. Not very good for some metronome that I want to build.

UPDATE: pygame.time.set_timer, 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()

. Ubuntu 16.04, Python 3.5 64bit (Anaconda) pygame.

+4
3

. , , () , Sound.play(loops=-1).

, .

pygame.sndarray a numpy , :

import pygame
import numpy


# Helper function
def getResizedSound(sound, seconds):

    frequency, bits, channels = pygame.mixer.get_init()

    # Determine silence value
    silence = 0 if bits < 0 else (2**bits / 2) - 1

    # Get raw sample array of original sound
    oldArray = pygame.sndarray.array(sound)

    # Create silent sample array with desired length
    newSampleCount = int(seconds * frequency)
    newShape = (newSampleCount,) + oldArray.shape[1:]
    newArray = numpy.full(newShape, silence, dtype=oldArray.dtype)

    # Copy original sound to the beginning of the
    # silent array, clipping the sound if it is longer
    newArray[:oldArray.shape[0]] = oldArray[:newArray.shape[0]]

    return pygame.mixer.Sound(newArray)


pygame.mixer.init()
pygame.init()

sound = pygame.mixer.Sound('sound.wav')

resizedSound = getResizedSound(sound, 0.2)
resizedSound.play(loops=-1)

while True:
    pass

pygame ( numpy), .

0

, :

pygame.mixer.pre_init(44100, -16, 2, 256)

pygame init.

0

Well, you should try using a different way to download sound:

pygame.mixer.music.load(file=file_directory str)

To play sound, use:

pygame.mixer.music.play(loops=*optional* int, start=*optional* float)

Your code might look like this:

import pygame

pygame.init()
pygame.mixer.init()

sound = pygame.mixer.music.load('sound.wav')
def playSound():
    sound.pause()
    sound.play()

while True:
    pass

It worked better for me, but I'm on python 3.7.2. I don't know about python 3.5, but there is not much difference between 3.5 and 3.7.2. That should work!

0
source

Source: https://habr.com/ru/post/1664834/


All Articles