【问题标题】:Pygame audio delay and repeat loopPygame 音频延迟和重复循环
【发布时间】:2014-07-21 09:38:40
【问题描述】:

我有一些 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 窗口最初打开时出现延迟。任何人都可以帮助优化此代码以消除此延迟吗?另外,我怎样才能让声音播放为一个连续的音符,而不是重复的间隔?

【问题讨论】:

    标签: audio pygame continuous trigonometry


    【解决方案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()”调用块中,您永远无法摆脱这种延迟,您正在生成大量的大数组。您应该做的是在程序中使用单独的加载屏幕优雅地处理加载(查看线程以保持实时窗口并同时加载)

    【讨论】:

    • 按键按下时的声音循环(持续音符)怎么样?目前,在声音的持续时间结束与其循环之间有一个相当突然的时刻,这非常清晰可听。将持续时间增加到 1 秒以上也会显着增加启动序列中的时间延迟,所以我不确定如何在长按键的情况下创建一个更微妙的无限音符循环。再次感谢您的合作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多