当前位置: 动力学知识库 > 问答 > 编程问答 >

Pygame audio delay and repeat loop

问题描述:

I have some python code for generating some sine wave audio in 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()

I am getting a delay when the pygame window initially opens. Can anyone help to optimise this code to remove this delay? Also, how can I enable to sound to play as one continuous note, rather than repeated intervals?

网友答案:

I modified your code a bit to show the time delays in the initiation sequence (after pygame.init() which i moved to the start) by getting the start time with pygame.time.get_ticks() and comparing at each notable point this is the output (the number is time in milliseconds)

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

Basically this delay is all in the block of "generate_sound()" calls, and you are never going to get rid of this delay, you are generating loads of big arrays. What you should just do is handle the loading gracefully with a separate loading screen in your program (look in to threading to keep a live window and load at the same time)

分享给朋友:
您可能感兴趣的文章:
随机阅读: