繁体   English   中英

虽然经常被解雇,但pygame.mixer.Sound.play是不规则的

[英]pygame.mixer.Sound.play is irregular although fired regularly

我目前尝试每隔x ms重复一次声音 - 其中x依赖于我通过套接字接收的UDP数据包 - 我决定使用pygame。 我用这个SO答案每隔x ms重复一次: https//stackoverflow.com/a/18954902/3475778

但现在我遇到了问题,声音播放非常不规律,并且问题仍然存在的最小工作示例:

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()

以下是我通过Audacity从脚本中记录的波形:

在此输入图像描述

你看,由于某些原因,一些样本的播放时间比其他样本长。 对于我想要构建的某种节拍器来说不是很好。

编辑更新:这不是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下。

这是另一种方法的想法。 如果目标是定期播放声音,如果您(动态)将声音填充到所需的间隔长度,则可能会获得更好的效果,然后使用Sound.play(loops=-1)Sound.play(loops=-1)

如果只有少数有效间隔,则最简单的方法是存储专用声音文件并加载适当的声音文件。

否则, pygame.sndarray模块提供对原始声音数据的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),这种方法应该有一个很好的机会进行准确的播放。

对我来说,如果我做的话,事情会好得多:

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

在任何pygame init函数之前。

好的,您应该尝试使用其他方式加载声音:

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

要播放声音使用:

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

您的代码可能如下所示:

import pygame

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

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

while True:
    pass

对我来说,这更好,但我在python 3.7.2。 我不知道python 3.5,但3.5和3.7.2之间没有太大的区别。 这应该工作!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM