I found this code for playing sounds: from array import array from time import sleep

Code:

import pygame
from pygame.mixer import Sound, get_init, pre_init

class Note(Sound):

    def __init__(self, frequency, volume=.1):
        self.frequency = frequency
        Sound.__init__(self, self.build_samples())
        self.set_volume(volume)

    def build_samples(self):
        period = int(round(get_init()[0] / self.frequency))
        samples = array("h", [0] * period)
        amplitude = 2 ** (abs(get_init()[1]) - 1) - 1
        for time in range(period):
            if time < period / 2:
                samples[time] = amplitude
            else:
                samples[time] = -amplitude
       return samples

if __name__ == "__main__":
    pre_init(44100, -16, 1, 1024)
    pygame.init()
    Note(440).play(-1)
    sleep(5)

I use this method to for convenience:

Code:
def playSound(hz,ms):
    pre_init(44100, -16, 1, 1024)
    Note(hz).play(ms)

Putting -1 for ms plays the sound infinitely.

My problem is that I have no way of controlling when the sound stops. I have tried playing another inaudible frequency over it, but both can play at the same time. Any ideas on how to end the playing of the sound upon releasing the key?
According to the documentation, Sound has a stop() method that will immediately stop playback of that instance.

A quick toy that plays A440 when you press the down arrow key and A880 when you press the up arrow:
Code:
from array import array
import pygame
from pygame.mixer import Sound, get_init

class Note(pygame.mixer.Sound):

    def __init__(self, frequency, volume=.1):
        self.frequency = frequency
        Sound.__init__(self, self.build_samples())
        self.set_volume(volume)

    def build_samples(self):
        period = int(round(get_init()[0] / self.frequency))
        samples = array("h", [0] * period)
        amplitude = 2 ** (abs(get_init()[1]) - 1) - 1
        for time in range(period):
            if time < period / 2:
                samples[time] = amplitude
            else:
                samples[time] = -amplitude
        return samples

pygame.init()
screen = pygame.display.set_mode([640, 480], 0)

sounds = {}
keymap = {
    pygame.K_UP: 880,
    pygame.K_DOWN: 440
}

while True:
    evt = pygame.event.wait()
    if evt.type == pygame.QUIT:
        break
    elif evt.type == pygame.KEYDOWN:
        if evt.key in keymap:
            note = Note(keymap[evt.key])
            note.play(-1)
            sounds[evt.key] = note
    elif evt.type == pygame.KEYUP:
        if evt.key in sounds:
            sounds.pop(evt.key).stop()
       

pygame.quit()
That works. I found that by also importing pre_init along with Sound and get_init and adding the line

Code:
pre_init(44100, -16, 1, 1024)
after pygame.init(), the delay between the keypress and the sound is eliminated. Thanks!

EDIT: While it does work, I am confused on how it works, in particular the keymap. Could you explain it to me please?

EDIT AGAIN: The program is pending addition to the archives. I understand it a little better not, but not entirely. Razz
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement