[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] noob questions about creating and playing sounds



Hi, I am starting to experiment with Pygame and how to generate sounds
and play them back. Here is a code snippet, the full (working) code is
below.

def play_maxtime(sound, duration):
    sound.play(loops=-1, maxtime=duration)
    pygame.time.delay(duration)

I have a few questions about this:

 * Why is it that play_maxtime doesn't work without the time.delay?
When I remove the delay line, no sound is played, despite the use of
the maxtime argument.

 * Why does this sound so ugly? This method (and play_loops below)
produces a terrible rattle, regardless the sample-rate. (Note, that I
am using 16 bit, which should produce at least decent quality. And it
is not clipping.)

 * Anyone knows how to create the sound in real-time, and feed it to
the sound card? For example, make the frequency depend on the mouse
position.

Since it is quite difficult to find information and examples about how
to create and play back sounds in Python and Pygame, I am posting the
complete working example below, for reference. Maybe other noobs might
find it useful. This code was adapted from a post on other mailing
list: http://mail.python.org/pipermail/tutor/2009-March/067724.html


import numpy
import pygame

# Create the sound wave in the required bit-rate.
def sine_array(freq, amplitude, sample_rate):
    wavelength = sample_rate / freq
    omega = 2 * numpy.pi / wavelength
    xvalues = numpy.arange(wavelength) * omega
    return numpy.int16(amplitude * numpy.sin(xvalues))

# Two different methods for playing the sound.
def play_maxtime(sound, duration):
    sound.play(loops=-1, maxtime=duration)
    pygame.time.delay(duration)

def play_loops(sound, duration):
    sound.play(loops=-1)
    pygame.time.delay(duration)
    sound.stop()

# Initialize PyGame & PyGame sound system.
sample_rate, bit_rate, channels = 22050, -16, 1
pygame.mixer.pre_init(sample_rate, bit_rate, channels)
pygame.init()
sample_rate, bit_rate, channels = pygame.mixer.get_init()
assert bit_rate == -16   # sine_array only implements 16 bit signed
pygame.sndarray.use_arraytype('numpy')

# Create a sound array, and convert it to a Sound object.
sound_array = sine_array(440, 20000, sample_rate)
sound = pygame.sndarray.make_sound(sound_array)

# Play the sound using two different methods.
duration = 2000
play_maxtime(sound, duration)
pygame.time.delay(duration)
play_loops(sound, duration)