On Wed, Sep 12, 2012 at 1:17 AM, D.V.N.Sarma డి.వి.ఎన్.శర్మ <dvnsa...@gmail.com> wrote: > How to produce a musical note of given frequency,volume and duration in > Python.
Do you just want a sinusoidal, pure tone, or do you need a more complex waveform? For a pure tone you can use math.sin(2 * math.pi * f * dt * n). The sin is a function of radians. 2*math.pi is the constant number of radians/cycle, f is the frequency in cycles/second (Hz), dt is your sampling step size in seconds/sample, and n is the index in samples. Multiply all those units together and you get an argument in radians. The sin function just samples the y value of the (x,y) coordinate as you step around a unit circle in the given radians/step. You can scale the amplitude and iterate for however many steps you want. The discrete frequency is f*dt in cycles/sample, and the discrete period is 1/(f*dt) in samples/cycle. You need this to be at least 2 samples/cycle to uniquely define a sinusoid. In other words, 1/dt >= 2*f. The term 1/dt is the sampling rate fs. Two times the highest frequency of interest (2*f) is called the Nyquist rate. Sampling a a sinusoid at a sub-Nyquist rate will alias to a different frequency (the spectrum of a sampled signal goes from 0 to fs/2; higher frequencies fold back around). Search the web for animations that show aliasing (typically with clock hands, fan blades, etc). If your sample rate is 48000 Hz, you can create tones up to 24000 Hz, which is beyond the spectrum of human hearing (20Hz - 20kHz). The example below creates a generator for 1 cycle of a tone at a sample rate of 48 ksps. Next it packs the floating point values as bytes using struct.pack(). The resulting byte string is written to a PyAudio stream. PyAudio is a C extension wrapper around the cross-platform PortAudio library: http://people.csail.mit.edu/hubert/pyaudio import math import struct import pyaudio def play_tone(frequency, amplitude, duration, fs, stream): N = int(fs / frequency) T = int(frequency * duration) # repeat for T cycles dt = 1.0 / fs # 1 cycle tone = (amplitude * math.sin(2 * math.pi * frequency * n * dt) for n in xrange(N)) # todo: get the format from the stream; this assumes Float32 data = ''.join(struct.pack('f', samp) for samp in tone) for n in xrange(T): stream.write(data) fs = 48000 p = pyaudio.PyAudio() stream = p.open( format=pyaudio.paFloat32, channels=1, rate=fs, output=True) # play the C major scale scale = [130.8, 146.8, 164.8, 174.6, 195.0, 220.0, 246.9, 261.6] for tone in scale: play_tone(tone, 0.5, 0.75, fs, stream) # up an octave for tone in scale[1:]: play_tone(2*tone, 0.5, 0.75, fs, stream) stream.close() p.terminate() _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor