Re: [pygame] noob questions about creating and playing sounds
On Wed, Jul 22, 2009 at 12:46 PM, Jake bninmonk...@gmail.com wrote: For the crackle, are you using the latest version of pygame? I know a certain version had problems on win32. I am using: * Pygame 1.8.1 * Python 2.6.2 * Xubuntu 9.04 Jaunty Jackalope * Linux 2.6.28-13.45 * ALSA 1.0.18 It would be interesting to know, if the posted code examples produce that noise on your machine :)
[pygame] Re: noob questions about creating and playing sounds
I finally used the ossaudiodev module from the Python standard library, because I was unable to play a noise-free sound using pygame.mixer.Sound. OSS is not portable, but at least, it should make it easy to process in real-time. The full working code is attached as a reference for other people with similar needs. This code example was adapted from the following source: http://www.google.com/codesearch/p#dOPNNT5w2nY/svn/collective/funittest/trunk/doc/src/soundout.py On Mon, Jul 20, 2009 at 9:44 AM, Jerzy Jalocha Njjalo...@gmail.com wrote: 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, 2, 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) #! /usr/bin/env python import math import struct from cStringIO import StringIO import ossaudiodev as oss # Initialize OSS sound system. device = oss.open('/dev/dsp', 'w') bitrate, channels, samplerate = device.setparameters(oss.AFMT_S16_LE, 1, 22050) assert channels == 1 assert bitrate == 16 # Only 16 bit implemented below # Create sound. pitch = 440 # Hz duration = 1 # s sound_buffer = StringIO() nsamples = int(samplerate * duration) omega = 2.0 * math.pi * pitch / samplerate for n in xrange(nsamples): sample = math.sin(omega * n) value = int(sample * 32767) # 2**16 / 2 - 1 data = struct.pack('h', value) # short (signed) sound_buffer.write(data) # Play back. device.write(sound_buffer.getvalue()) device.close()
[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, 2, 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)
Re: [pygame] noob questions about creating and playing sounds
On Mon, Jul 20, 2009 at 9:55 AM, Yanom Mobisya...@rocketmail.com wrote: code gets all gibberishy in the message itself attatch the .py file(s) to the message Oops, sorry, I didn't know that! I forgot to mention, that I am running Python 2.6.6 under Linux. I can provide further information if necessary. #! /usr/bin/env python 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, 2, 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)
Re: [pygame] noob questions about creating and playing sounds
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. Because without that the program finishes and quits. You would not need the time.delay if you were using this in a game, since you would be playing your sounds inside the game's loop. OK, thanks, James! This shouldn't be a problem, then, if I succeed in somehow creating reproducing the sound in real-time, inside some kind main() loop. That was actually the third question in my original post: * 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.
Re: [pygame] noob questions about creating and playing sounds
On Mon, Jul 20, 2009 at 11:52 AM, Paulo Silvanitrofur...@gmail.com wrote: just a question: afaik, since Pygame uses SDL, Pygame only can play sounds were loaded, and the only way to 'create' (one of the questions of this mailinglist post) sounds is writing binary data into a .raw file, and calling SoX for converting it as .ogg, .wav, etc.? Paulo, I am not sure if I understand you correctly. The posted code actually 'creates' the sound, (a numpy array with a sine curve), converts it into a mixer.Sound object, and plays that back. This path without .ogg or .wav files is exactly what I am looking for. It just fails partially, because it creates a horrible rattle noise. And I am unable to discover where the noise comes from. (The data curve is smooth, and no clipping occurs. I also tried using longer arrays with many cycles of my curve.) What I am not sure if it can be done (or how), is to create the sound in real-time, and play that back. As an example, make the sound's frequency and amplitude depend on the mouse pointer's position. But maybe this is a limitation of the SDL? Thanks! #! /usr/bin/env python 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, 2, 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)
Re: [pygame] noob questions about creating and playing sounds
I fixed the problem, I think. The issue is in the way the sound is created. There's sometimes a bit of static-ey stuff in there on my system which I don't have time to track down right now. Hope it helps, Thank you, Ian, for the correction. You are right, that my math was not correct. I was producing 22000 samples for one second instead of 22050. I also appreciate the normalized amplitude. But from what I understand, this shouldn't matter to the core issue here (besides of slightly off-pitch), because play() (with loops=-1, of course) simply loops over the provided sample. Thus, your solution still produces the same rattle as my try. I charted both arrays, and they are basically equivalent. Any other ideas, where the rattle comes from? I have a cheap build-in soundcard, but this has been perfectly been able to provide decent music with other software, so far. - Jerzy