2016-12-25 73 views
4

解僱我現在儘量重複每x毫秒的聲音 - 其中x是依賴於我通過套接字收到UDP包 - 我決定使用pygame的爲。我用這個SO回答重複的東西每隔x毫秒:https://stackoverflow.com/a/18954902/3475778pygame.mixer.Sound.play是不規則的,雖然經常

但現在我有問題,該播放聲音很不規範,並提出了最低工作的例子,其中的問題仍然存在:

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的記錄波形:

enter image description here

你看到,由於某種原因,一些樣品比別人玩更長的時間。對於我想要構建的某種節拍器不是很好。

編輯更新: 這不是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下。

+2

目前還沒有在我的電腦上,但我的猜測是,如果pygame的定時器是基於SDL的定時器構建的,它的分辨率並不是很好。嘗試使用python'time'模塊並在while循環中查詢'time.time()',比較前一個和當前時間,直到xms已經過去。 – CodeSurgeon

+0

謝謝你的repsonse,我也是這樣的。我將在pygame存儲庫上做一個問題。 – capitalg

+1

這並不能解決問題,請參閱上面的更新。 – capitalg

回答

0

這是一個替代方法的想法。 如果目標是發揮定期健全, 你可能會得到更好的結果,如果你(動態)墊的聲音所需的時間間隔長, ,然後簡單地循環它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的),這種方法應該有一個很好的機會來進行準確的回放。