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 scipy.io.wavfile 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 plot(linspace(0,2,2*44100),tone) axis([0,0.4,15000,-15000]) show()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.
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
ReplyDeleteHi thanks for your code it is just was I need!
ReplyDeleteI 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
It's because the wave is stopped suddenly.
ReplyDeleteThanks, hence to avoid the click I need to fade out the sound. How can I do that?
ReplyDeleteA 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
Deletesomething like this
amp_decay = np.linspace(amp, 0, len * rate)
data = np.sin(2*np.pi*freq*t)*(amp_decay)
Ok; in case i want to play the (data) Int. as a sound ...
ReplyDeletehow can i do that ??
Try with pyaudio.
DeleteHI there..
Deleteiam 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 ....so how can i do that ??
it's may be so easy but i really need help with that
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.
ReplyDeleteIt would be at 440 ONLY if you used the correct number of samples for the FFT, with the data you are using it may be that 440 Hz isnt a multiple of your frequency resolution.
Delete