[Tutor] Chord player

Mr Gerard Kelly s4027340 at student.uq.edu.au
Thu Jan 8 13:38:34 CET 2009


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 <s4027340 at 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.
> 
-------------- next part --------------
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20090108/cde8bf6c/attachment.htm>
-------------- next part --------------
_______________________________________________
Tutor maillist  -  Tutor at python.org
http://mail.python.org/mailman/listinfo/tutor


More information about the Tutor mailing list