Re: [pygame] Creating a stereo sound from an array doubles frequency
On Fri, Dec 2, 2011 at 12:59 AM, Marcel Stimberg stimb...@users.sourceforge.net wrote: Hi list, I'm having trouble playing sounds (generated from arrays) as stereo sounds. Creating a sound and copying it to two channels seems to double the frequency. The following script (see also here: http://pastebin.com/qqZbJavf ) should make it more clear. It constructs a simple 400Hz sine wave and plays it as a mono sound (nchannels = 1) or duplicates the array and plays it as a stereo sound (nchannels = 2). In the second case, however, the tone that is played is an 800Hz tone instead of a 400Hz one... This seems not to happen on Windows, I encountered the problem on ArchLinux and Ubuntu 11.10 (both having pygame 1.9.1). import numpy as np import pygame as pg import time frequency, samplerate, duration = 400, 44100, 2 nchannels = 1 # change to 2 for stereo pg.mixer.pre_init(channels=nchannels, frequency=samplerate) pg.init() sinusoid = (2**15 - 1) * np.sin(2.0 * np.pi * frequency * \ np.arange(0, duration) / float(samplerate)) samples = np.array(sinusoid, dtype=np.int16) if nchannels 1: #copy mono signal to two channels samples = np.tile(samples, (nchannels, 1)).T sound = pg.sndarray.make_sound(samples) sound.play() time.sleep(duration/float(samplerate)) Hi, I can reproduce the sound doubling effect on Windows 7 Professional, 32 bit. Thanks, Ian
Re: [pygame] Creating a stereo sound from an array doubles frequency
Hello. On my system (Win 7 Pro, 64 bits, Python 2.7, pygame 1.9.2pre), your program doesn't produce any sound at all. For it work, I have to replace pg.mixer.pre_init(...); pg.init() by pg.mixer.init(...). (I discovered this a while back, and put a comment about it in the documentation. If you open a window, then pg.mixer.pre_init(...); pg.init() works.) If I put nchannels = 2, then make_sound() gives the following error: ValueError: ndarray is not C-contiguous Here's a simple script to synthesize stereo sound, that does work on my system (and that doesn't double frequency, AFAICT): import pygame, numpy, math duration = 1.0 # in seconds sample_rate = 44100 bits = 16 try: pygame.mixer.init(frequency = sample_rate, size = -bits, channels = 2) n_samples = int(round(duration*sample_rate)) 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*440*t))) # left buf[s][1] = int(round(max_sample*0.5*math.sin(2*math.pi*440*t)))# right sound = pygame.sndarray.make_sound(buf) sound.play() pygame.time.wait(int(round(1000*duration))) finally: pygame.mixer.quit() Mark On Fri, Dec 2, 2011 at 9:24 AM, Ian Mallett geometr...@gmail.com wrote: On Fri, Dec 2, 2011 at 12:59 AM, Marcel Stimberg stimb...@users.sourceforge.net wrote: Hi list, I'm having trouble playing sounds (generated from arrays) as stereo sounds. Creating a sound and copying it to two channels seems to double the frequency. The following script (see also here: http://pastebin.com/qqZbJavf ) should make it more clear. It constructs a simple 400Hz sine wave and plays it as a mono sound (nchannels = 1) or duplicates the array and plays it as a stereo sound (nchannels = 2). In the second case, however, the tone that is played is an 800Hz tone instead of a 400Hz one... This seems not to happen on Windows, I encountered the problem on ArchLinux and Ubuntu 11.10 (both having pygame 1.9.1). import numpy as np import pygame as pg import time frequency, samplerate, duration = 400, 44100, 2 nchannels = 1 # change to 2 for stereo pg.mixer.pre_init(channels=nchannels, frequency=samplerate) pg.init() sinusoid = (2**15 - 1) * np.sin(2.0 * np.pi * frequency * \ np.arange(0, duration) / float(samplerate)) samples = np.array(sinusoid, dtype=np.int16) if nchannels 1: #copy mono signal to two channels samples = np.tile(samples, (nchannels, 1)).T sound = pg.sndarray.make_sound(samples) sound.play() time.sleep(duration/float(samplerate)) Hi, I can reproduce the sound doubling effect on Windows 7 Professional, 32 bit. Thanks, Ian -- Mark Wexler Laboratoire Psychologie de la Perception CNRS - Université Paris Descartes 45, rue des Saints-Pères 75006 Paris, France http://wexler.free.fr
Re: [pygame] Creating a stereo sound from an array doubles frequency
Hi Ian, hi Mark, thanks for the feedback. pre_init and init works for me, as does your variant. But your error message (that was apparently added after 1.9.1 was released) provided the necessary clue: pygame makes the assumption that the argument of make_sound is in C-Order. I can reproduce my double frequency problem with your code if I replace: sound = pygame.sndarray.make_sound(buf) with sound = pygame.sndarray.make_sound(buf.copy(order='F')) (Conversely, the problem dissappears in my script if I do samples.copy(order='C')) The above code will apparently trigger an error on pygame 1.9.2pre but with 1.9.1release will result in the odd behaviour I described. The details of whether the array ends up in Fortran order may also depend on numpy version, architecture, etc. as a colleague could not reproduce my problem with pygame1.9.1 under Windows. Thanks again, best Marcel
[pygame] Creating a stereo sound from an array doubles frequency
Hi list, I'm having trouble playing sounds (generated from arrays) as stereo sounds. Creating a sound and copying it to two channels seems to double the frequency. The following script (see also here: http://pastebin.com/qqZbJavf ) should make it more clear. It constructs a simple 400Hz sine wave and plays it as a mono sound (nchannels = 1) or duplicates the array and plays it as a stereo sound (nchannels = 2). In the second case, however, the tone that is played is an 800Hz tone instead of a 400Hz one... This seems not to happen on Windows, I encountered the problem on ArchLinux and Ubuntu 11.10 (both having pygame 1.9.1). import numpy as np import pygame as pg import time frequency, samplerate, duration = 400, 44100, 2 nchannels = 1 # change to 2 for stereo pg.mixer.pre_init(channels=nchannels, frequency=samplerate) pg.init() sinusoid = (2**15 - 1) * np.sin(2.0 * np.pi * frequency * \ np.arange(0, duration) / float(samplerate)) samples = np.array(sinusoid, dtype=np.int16) if nchannels 1: #copy mono signal to two channels samples = np.tile(samples, (nchannels, 1)).T sound = pg.sndarray.make_sound(samples) sound.play() time.sleep(duration/float(samplerate))