Thursday, September 8, 2011

Sound Synthesis

Physically, sound is an oscillation of a mechanical medium that makes the surrounding air also oscillate and transport the sound as a compression wave. Mathematically, the oscillations can be described as
where t is the time, and f the frequency of the oscillation. Sound on a computer is a sequence of numbers and in this post we will see how to generate a musical tone with numpy and how to write it to a file wav file. Each musical note vibrates at a particular frequency and the following script contains a function to generate a note (tone(...)), we'll use this function to generate the A tone creating an oscillation with f = 440 Hz.
from import write
from numpy import linspace,sin,pi,int16
from pylab import plot,show,axis

# tone synthesis
def note(freq, len, amp=1, rate=44100):
 t = linspace(0,len,len*rate)
 data = sin(2*pi*freq*t)*amp
 return data.astype(int16) # two byte integers

# A tone, 2 seconds, 44100 samples per second
tone = note(440,2,amp=10000)

write('440hzAtone.wav',44100,tone) # writing the sound to a file

Now we can play the file 440hzAtone.wav with an external player. This plot shows a part of the signal generated by the script:
And using the plotSpectrum function defined in a previous post we can verify that 440 Hz is the fundamental frequency of the tone.


  1. thanks ! i´ve been looking for a simple way of doing this, but what i find on google uses csound and fluidsynth, i hope your method becomes the one used to give blender3d audio synthesis abilities

  2. Hi thanks for your code it is just was I need!
    I have one question. I get a "click" sound at the end on the generated tone. It is a problem of my hardware or the code? How can I get rid of that click sound? I have try changing the paramenters but the click sound is still there.
    Thanks in advance

  3. It's because the wave is stopped suddenly.

  4. Thanks, hence to avoid the click I need to fade out the sound. How can I do that?

    1. A possible solution to avoid the click sound is to decrease the amplitude as a function of the lenght of the note instead of using a contact amplitude

      something like this

      amp_decay = np.linspace(amp, 0, len * rate)
      data = np.sin(2*np.pi*freq*t)*(amp_decay)

  5. Ok; in case i want to play the (data) Int. as a sound ...
    how can i do that ??

    1. HI there..
      iam still new with python and need your help if you can ...
      all i need now is that i have :
      X=0 to 180
      and data=0.5 cos(2*pi*X)
      and i need to play the data as sound when ever X is changed how can i do that ??
      it's may be so easy but i really need help with that

  6. If I load the wav into Audacity and view the spectrum, the peak is at 443 Hz. Something is a bit off here, it should be exactly 440Hz.