Actually, I think I can minimize the clipping sound by setting the sample_rate to be one hundred times the value of the highest frequency in the chord. But it's still there for the notes underneath. Oh well, better than nothing!
----- Original Message ----- From: Mr Gerard Kelly <s4027...@student.uq.edu.au> Date: Thursday, January 8, 2009 10:12 pm Subject: [Tutor] Chord player > I want to thank Emmanuel from the tutor mailing list for showing me a > piece of code that let me do exactly what I wanted - making Python > playa chord from a input of frequencies. I only needed to make a few > adjustments. > > The code (below) uses Numeric. Emmanuel said that Numeric is out of > dateand should be replaced everywhere by numpy. When I do that > there is no > error message but the code doesn't play any sound. So I'm keeping > Numeric in there (although I read somewhere that Python automatically > converts Numeric to numpy anyway). > > I did have one problem, which is when you play a chord, you hear a > clipping sound every second. I assume that is because of this line: > > def sine_array(hz, peak, n_samples = sample_rate): > #Compute N samples of a sine wave with given frequency and peak > amplitude (defaults to one second). > return Numeric.resize(sine_array_onecycle(hz, peak), (n_samples,)) > > I thought I could get rid of the clipping noise by making it return > moresamples than just for one second. For instance if I put in > 2*(n_samples)instead of the default sample_rate value, it might > make the clipping > sound come every 2 seconds etc. However, I have found that if I put in > any other value other than the default value, it cannot calculate. The > dimensions are wrong or there is a memory problem or something. I'm > notsure how the resize method works and I was wondering if it is > actuallypossible to fix this problem this way. > > Here's the whole code: > > > *** > > import pygame, time, random, Numeric, pygame, pygame.sndarray > sample_rate = 44100 > > def sine_array_onecycle(hz, peak): > #Compute one cycle of an N-Hz sine wave with given peak amplitude > length = sample_rate / float(hz) > omega = Numeric.pi * 2 / length > xvalues = Numeric.arange(int(length)) * omega > return (peak * Numeric.sin(xvalues)).astype(Numeric.Int16) > > def sine_array(hz, peak, n_samples = sample_rate): > #Compute N samples of a sine wave with given frequency and peak > amplitude (defaults to one second). > > return Numeric.resize(sine_array_onecycle(hz, peak), (n_samples,)) > > def waves(*chord): > #Compute the harmonic series for a vector of frequencies > #Create square-like waves by adding odd-numbered overtones for each > fundamental tone in the chord > #the amplitudes of the overtones are inverse to their frequencies. > h=9 > ot=3 > harmonic=sine_array(chord[0],4096) > while (ot<h): > if (ot*chord[0])<(sample_rate/2): > harmonic=harmonic+(sine_array(chord[0]*ot, 4096/(2*ot))) > else: > harmonic=harmonic+0 > ot+=2 > for i in range(1,len(chord)): > harmonic+=(sine_array(chord[i], 4096)) > > > if (ot*chord[i])<(sample_rate/2): > harmonic=harmonic+(sine_array(chord[i]*ot, 4096/(2*ot))) > else: > harmonic=harmonic+0 > ot+=2 > return harmonic > > def play_for(sample_array, ms): > #Play the sample array as a sound for N ms. > pygame.mixer.pre_init(sample_rate, -16, 1) # 44.1kHz, 16-bit > signed, mono > pygame.init() > sound = pygame.sndarray.make_sound(sample_array) > sound.play(-1) > pygame.time.delay(ms) > sound.stop() > > def main(): > #Play a single sine wave, followed by a chord with overtones. > > pygame.mixer.pre_init(sample_rate, -16, 1) # 44.1kHz, 16-bit > signed, mono > pygame.init() > play_for(sine_array(440, 4096), 2500) > play_for(waves(440,550,660,770,880), 5000) > > > if __name__ == '__main__': main() > > > *** > > Thanks for having a look! > > Gerard. >
Gerard Kelly wrote: > Hi everyone, I'm a python noob but I have an ambitious (for me) goal: I > want to make a simple program that allows you to hear combinations of > notes according to a vector of frequencies. > > Does anybody know any module that allows you to input a frequency in Hz > and returns a sound with that frequency, and lets you do that with > multiple frequencies, so that you can build chords? The recipe linked below plays sounds composed of a fundamental and a few harmonics. It requires Pygame and NumPy. http://osdir.com/ml/culture.people.kragen.hacks/2007-11/msg00000.html It is out of date, though. I had to change 'Numeric' to 'numpy' and 'Int16' to 'int16' to get it to work. Moreover NumPy doesn't seem to work with Python 2.6. You can also use TkSnack (http://www.speech.kth.se/snack/). Check the example named 'notescale' that comes with the module: it defines a function that receives a frequency as an input and plays a sound; there is also a graphical interface. Regards, Emmanuel
_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor