Pygame音频延迟和重复循环

时间:2014-07-21 09:38:40

标签: audio pygame continuous sine

我有一些python代码用于在pygame中生成一些正弦波音频:

 import pygame
from pygame.locals import *

import math
import numpy


def generate_sound(freq):

    #setup our numpy array to handle 16 bit ints, which is what we set our mixer to expect with "bits" up above
    buf = numpy.zeros((n_samples, 2), dtype = numpy.int16)
    max_sample = 2**(bits - 1) - 1

    for s in range(n_samples):
        t = float(s)/sample_rate    # time in seconds
        buf[s][0] = int(round(max_sample*math.sin(2*math.pi*freq*t)))    # left
        buf[s][1] = int(round(max_sample*math.sin(2*math.pi*freq*t)))    # right

    return pygame.sndarray.make_sound(buf)

bits = 16

pygame.mixer.pre_init(44100, -bits, 2)
pygame.init()
pygame.mixer.fadeout(4000) #fade out time in milliseconds

size = (1200, 720)
screen = pygame.display.set_mode(size, pygame.HWSURFACE | pygame.DOUBLEBUF)


duration = 1.0          # in seconds

sample_rate = 44100

n_samples = int(round(duration*sample_rate))


#lower
sound_130_81 = generate_sound(130.81)   #C
sound_146_83 = generate_sound(146.83)   #D
sound_164_81 = generate_sound(164.81)   #E
sound_174_61 = generate_sound(174.61)   #F
sound_196_00 = generate_sound(196.00)   #G
sound_220_00 = generate_sound(220.00)   #A
sound_246_94 = generate_sound(246.94)   #B
#middle
sound_261_63 = generate_sound(261.63)   #C
sound_293_66 = generate_sound(293.66)   #D
sound_329_63 = generate_sound(329.63)   #E
sound_349_23 = generate_sound(349.23)   #F
sound_392_00 = generate_sound(392.00)   #G
sound_440_00 = generate_sound(440.00)   #A
sound_493_88 = generate_sound(493.88)   #B
#higher
sound_523_25 = generate_sound(523.25)   #C
sound_587_33 = generate_sound(587.33)   #D
sound_659_25 = generate_sound(659.25)   #E
sound_698_46 = generate_sound(698.46)   #F
sound_783_99 = generate_sound(783.99)   #G
sound_880_00 = generate_sound(880.00)   #A
sound_987_77 = generate_sound(987.77)   #B
sound_1046_50 = generate_sound(1046.50) #C

#This will keep the sound playing forever, the quit event handling allows the pygame window to close without crashing
_running = True
while _running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            _running = False


        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                _running = False

            #lower notes DOWN

            elif event.key == K_z:
                sound_130_81.play(loops = -1)

            elif event.key == K_x:
                sound_146_83.play(loops = -1)

            elif event.key == K_c:
                sound_164_81.play(loops = -1)

            elif event.key == K_v:
                sound_174_61.play(loops = -1)

            elif event.key == K_b:
                sound_196_00.play(loops = -1)

            elif event.key == K_n:
                sound_220_00.play(loops = -1)

            elif event.key == K_m:
                sound_246_94.play(loops = -1)

            elif event.key == K_COMMA:
                sound_261_63.play(loops = -1) 


            #middle notes DOWN

            elif event.key == K_a:
                sound_261_63.play(loops = -1)

            elif event.key == K_s:
                sound_293_66.play(loops = -1)

            elif event.key == K_d:
                sound_329_63.play(loops = -1)

            elif event.key == K_f:
                sound_349_23.play(loops = -1)

            elif event.key == K_g:
                sound_392_00.play(loops = -1)

            elif event.key == K_h:
                sound_440_00.play(loops = -1)

            elif event.key == K_j:
                sound_493_88.play(loops = -1)

            elif event.key == K_k:
                sound_523_25.play(loops = -1)


            #higher notes DOWN

            elif event.key == K_q:
                sound_523_25.play(loops = -1)

            elif event.key == K_w:
                sound_587_33.play(loops = -1)

            elif event.key == K_e:
                sound_659_25.play(loops = -1)

            elif event.key == K_r:
                sound_698_46.play(loops = -1)

            elif event.key == K_t:
                sound_783_99.play(loops = -1)

            elif event.key == K_y:
                sound_880_00.play(loops = -1)

            elif event.key == K_u:
                sound_987_77.play(loops = -1)

            elif event.key == K_i:
                sound_1046_50.play(loops = -1)

        if event.type == KEYUP:

            #lower notes UP

            if event.key == K_z:
                sound_130_81.stop()

            elif event.key == K_x:
                sound_146_83.stop()

            elif event.key == K_c:
                sound_164_81.stop()

            elif event.key == K_v:
                sound_174_61.stop()

            elif event.key == K_b:
                sound_196_00.stop()

            elif event.key == K_n:
                sound_220_00.stop()

            elif event.key == K_m:
                sound_246_94.stop()

            elif event.key == K_COMMA:
                sound_261_63.stop()

            #middle notes UP

            elif event.key == K_a:
                sound_261_63.stop()

            elif event.key == K_s:
                sound_293_66.stop()

            elif event.key == K_d:
                sound_329_63.stop()

            elif event.key == K_f:
                sound_349_23.stop()

            elif event.key == K_g:
                sound_392_00.stop()

            elif event.key == K_h:
                sound_440_00.stop()

            elif event.key == K_j:
                sound_493_88.stop()

            elif event.key == K_k:
                sound_523_25.stop()

            #higher notes UP

            elif event.key == K_q:
                sound_523_25.stop()

            elif event.key == K_w:
                sound_587_33.stop()

            elif event.key == K_e:
                sound_659_25.stop()

            elif event.key == K_r:
                sound_698_46.stop()

            elif event.key == K_t:
                sound_783_99.stop()

            elif event.key == K_y:
                sound_880_00.stop()

            elif event.key == K_u:
                sound_987_77.stop()

            elif event.key == K_i:
                sound_1046_50.stop()


pygame.quit()

当pygame窗口最初打开时,我得到了延迟。任何人都可以帮助优化此代码以消除此延迟?另外,如何让声音作为连续音符播放,而不是重复播放?

1 个答案:

答案 0 :(得分:1)

我修改了你的代码以显示启动序列中的时间延迟(在我移动到开头的pygame.init()之后) 通过pygame.time.get_ticks()获取开始时间并在每个值得注意的点比较这是输出(数字是以毫秒为单位的时间)

right at the start 0
post mixer preinit 6
post mixer fadeout 21
screen made 373
before generating sounds 377
after generating sounds 3686
after full init 3689

基本上这个延迟都在“generate_sound()”调用的块中,你永远不会摆脱这个延迟,你正在生成大量的数组。您应该做的是在程序中使用单独的加载屏幕优雅地处理加载(查看线程以保持实时窗口并同时加载)