2014-07-22 18 views
0

Этот код, похоже, работает нормально, но на самом деле не do ничего, кроме открытия окна pygame. Я ищу звук, который будет воспроизводиться при нажатии клавиши «z».Звуковой код Pygame не работает

У кого-нибудь есть проблемы с этим кодом?

import pygame 
from pygame.locals import * 
import math 
import numpy 

size = (1200, 720) 
screen = pygame.display.set_mode(size, pygame.HWSURFACE | pygame.DOUBLEBUF) 
pygame.display.set_caption('Nibbles!') 

SAMPLE_RATE = 22050 ## This many array entries == 1 second of sound. 

def SineWave(freq=1000,volume=16000,length=1): 
    num_steps = length*SAMPLE_RATE 
    s = [] 
    for n in range(num_steps): 
     value = int(math.sin(n * freq * (6.28318/SAMPLE_RATE) * length)*volume) 
     s.append([value,value]) 
    x_arr = array(s) 
    return x_arr 

def SquareWave(freq=1000,volume=100000,length=1): 
    length_of_plateau = SAMPLE_RATE/(2*freq) 
    s = [] 
    counter = 0 
    state = 1 
    for n in range(length*SAMPLE_RATE): 
     if state == 1: 
      value = volume 
     else: 
      value = -volume 
     s.append([value,value]) 

     counter += 1 
     if counter == length_of_plateau: 
      counter = 0 
      if state == 1: 
       state = -1 
      else: 
       state = 1 

    x_arr = array(s) 
    return x_arr 

def MakeSound(arr): 
    return pygame.sndarray.make_sound(arr) 

def PlaySquareWave(freq=1000): 
    MakeSound(SquareWave(freq)).play() 

def PlaySineWave(freq=1000): 
    MakeSound(SineWave(freq)).play() 

def StopSineWave(freq=1000): 
    MakeSound(SineWave(freq)).fadeout(350) 

def StopSquareWave(freq=1000): 
    MakeSound(SquareWave(freq)).fadeout(350) 

_running = True 
while _running: 

    SineWaveType = 'Sine' 
    SquareWaveType = 'Square' 
    d = {SineWaveType:SquareWaveType, SquareWaveType:SineWaveType} 
    Type = SineWaveType 

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

      if Type == 'Sine': 

       if event.type == KEYDOWN: 

        #lower notes DOWN 
        if event.key == K_ESCAPE: 
         _running = False 

        if event.key == K_ENTER: 
         Type = d[Type] #Toggle 

        elif event.key == K_z: 
         PlaySineWave(130.81) 

       if event.type == KEYUP: 

        #lower notes UP 

        if event.key == K_z: 
         StopSineWave(130.81).fadeout(350)  #fade sound by .35 seconds 

      elif Type == 'Square': 

       if event.type == KEYDOWN: 

        #lower notes DOWN 
        if event.key == K_z: 
         PlaySquareWave(130.81) 

       if event.type == KEYUP: 

        #lower notes UP 

        if event.key == K_z: 
         StopSquareWave(130.81).fadeout(350)  #fade sound by .35 seconds 

pygame.quit() 
+0

Вы понимаете, что ваш цикл '_running' абсолютно ничего не значит, но ждать' QUIT', правильно? В какой момент вы ожидаете, что этот код действительно сделает что-нибудь? – jonrsharpe

+0

Теперь я чувствую себя глупо, этого не замечал. Я отредактировал оригинальный пост, теперь он даже не откроет окно pygame, я все еще что-то пропущу? – ZenLogic

+0

Вам действительно нужно разобраться с областью определения на основе Python - все от 'if Type == 'Sine':' on down is ** вне ** цикла while. – jonrsharpe

ответ

0

Некоторые модификации:

  • вы должны FADEOUT существующий звук не создать новый для FADEOUT (потому что Pygame будет играть и в то же время) - я использую curren_played сохранить существующий звук.
  • ключей ESCAPE и ENTER не нужно проверять тип звука.
  • Вы забыли pygame.init(), которые инициализируют экран, микшер и другие вещи.
  • потому что у меня была проблема с квадратной волной, поэтому я использую синус-волну в примере.
  • добавить sonund к c ключ - так что вы можете играть в двух звуков одновременно
  • Я использую прописные имена для постоянных значений как SINE_WAVE_TYPE.

Вы можете создавать волны, прежде чем mainloop и держать его в current_played и породили новые волны в current_played при нажатии RETURN .

import pygame 
from pygame.locals import * 
import math 
import numpy 

#---------------------------------------------------------------------- 
# functions 
#---------------------------------------------------------------------- 

def SineWave(freq=1000, volume=16000, length=1): 

    num_steps = length * SAMPLE_RATE 
    s = [] 

    for n in range(num_steps): 
     value = int(math.sin(n * freq * (6.28318/SAMPLE_RATE) * length) * volume) 
     s.append([value, value]) 

    return numpy.array(s) 

def SquareWave(freq=1000, volume=100000, length=1): 

    num_steps = length * SAMPLE_RATE 
    s = [] 

    length_of_plateau = SAMPLE_RATE/(2*freq) 

    counter = 0 
    state = 1 

    for n in range(num_steps): 

     value = state * volume 
     s.append([value, value]) 

     counter += 1 

     if counter == length_of_plateau: 
      counter = 0 
      state *= -1 

    return numpy.array(s) 

def MakeSound(arr): 
    return pygame.sndarray.make_sound(arr) 

def MakeSquareWave(freq=1000): 
    return MakeSound(SquareWave(freq)) 

def MakeSineWave(freq=1000): 
    return MakeSound(SineWave(freq)) 

#---------------------------------------------------------------------- 
# main program 
#---------------------------------------------------------------------- 

pygame.init() 

size = (1200, 720) 
screen = pygame.display.set_mode(size, pygame.HWSURFACE | pygame.DOUBLEBUF) 
pygame.display.set_caption('Nibbles!') 

SAMPLE_RATE = 22050 ## This many array entries == 1 second of sound. 

SINE_WAVE_TYPE = 'Sine' 
SQUARE_WAVE_TYPE = 'Square' 

sound_types = {SINE_WAVE_TYPE:SQUARE_WAVE_TYPE, SQUARE_WAVE_TYPE:SINE_WAVE_TYPE} 

current_type = SINE_WAVE_TYPE 

current_played = { 'z': None, 'c': None } 

_running = True 
while _running: 

    for event in pygame.event.get(): 

     if event.type == pygame.QUIT: 
      _running = False 

     # some keys don't depend on `current_type` 

     elif event.type == KEYDOWN: 

      if event.key == K_ESCAPE: 
       _running = False 

      if event.key == K_RETURN: 
       current_type = sound_types[current_type] #Toggle 
       print 'new type:', current_type 

     # some keys depend on `current_type` 

     if current_type == SINE_WAVE_TYPE: 

      if event.type == KEYDOWN: 

       #lower notes DOWN 

       if event.key == K_z: 
        print current_type, 130.81 
        current_played['z'] = MakeSineWave(130.81) 
        current_played['z'].play() 

       elif event.key == K_c: 
        print current_type, 180.81 
        current_played['c'] = MakeSineWave(180.81) 
        current_played['c'].play() 

      elif event.type == KEYUP: 

       #lower notes UP 

       if event.key == K_z: 
        current_played['z'].fadeout(350) 
       elif event.key == K_c: 
        current_played['c'].fadeout(350) 

     elif current_type == SQUARE_WAVE_TYPE: 

      if event.type == KEYDOWN: 

       #lower notes DOWN 

       if event.key == K_z: 
        print current_type, 80.81 
        current_played['z'] = MakeSineWave(80.81) 
        #current_played['z'] = MakeSquareWave(130.81) 
        current_played['z'].play() 

       elif event.key == K_c: 
        print current_type, 180.81 
        current_played['c'] = MakeSineWave(180.81) 
        #current_played['c'] = MakeSquareWave(130.81) 
        current_played['c'].play() 

      elif event.type == KEYUP: 

       #lower notes UP 

       if event.key == K_z: 
        current_played['z'].fadeout(350) 
       elif event.key == K_c: 
        current_played['c'].fadeout(350) 

pygame.quit() 

#---------------------------------------------------------------------- 
Смежные вопросы