Reputation: 3908
I am trying to write an audio file with tones from 440hz to 600hz. The file should start at 440hz and then play each frequency (in increasing order) for 1 second, ending at 600hz. I've come up with python's wave module, but am doing something wrong here, as I end up with a file with no sound. (If someone has a better suggestion, I really don't care if it's in python or not. I am using Linux and anything that will work on that platform will do fine. I just need to create an audio file with the above specs. thx!)
frequencies = range(440,600)
data_size = len(frequencies)
fname = "WaveTest.wav"
frate = 11025.0 # framerate as a float
amp = 64000.0 # multiplier for amplitude
sine_list_x = []
for f in frequencies:
for x in range(data_size):
sine_list_x.append(math.sin(2*math.pi*f*(x/frate)))
wav_file = wave.open(fname, "w")
nchannels = 1
sampwidth = 2
framerate = int(frate)
nframes = data_size
comptype = "NONE"
compname = "not compressed"
wav_file.setparams((nchannels, sampwidth, framerate, nframes,
comptype, compname))
for s in sine_list_x:
# write the audio frames to file
wav_file.writeframes(struct.pack('h', int(s*amp/2)))
wav_file.close()
Upvotes: 2
Views: 1210
Reputation: 11002
It seems to works fine for me on a Windows plateform :
The sampling is respected and the frequencies are just right (from 440 to 600 Hz). However, in your code the frequencies does not stay for one second, but for len(frequencies)/frate-th of second. If you want to have a full second for every frequency, data_size should be equal to frate.
import math
import wave
import struct
frequencies = range(440,600)
duration = 1 #in second
fname = "WaveTest.wav"
frate = 11025.0 # framerate as a float
amp = 64000.0 # multiplier for amplitude
sine_list_x = []
for f in frequencies:
for x in range(duration*frate) :
sine_list_x.append(math.sin(2*math.pi*f*(x/frate)))
wav_file = wave.open(fname, "w")
nchannels = 1
sampwidth = 2
framerate = int(frate)
nframes = data_size
comptype = "NONE"
compname = "not compressed"
wav_file.setparams((nchannels, sampwidth, framerate, nframes,
comptype, compname))
for s in sine_list_x:
# write the audio frames to file
wav_file.writeframes(struct.pack('h', int(s*amp/2)))
wav_file.close()
Upvotes: 1
Reputation: 1500
Something like this should work: hopefully its at least a good starting point for you to continue.
import numpy as N
import wave
towrite = ''
for freq in xrange(440,600):
duration = 1
samplerate = 44100
samples = duration*samplerate
period = samplerate / float(freq) # in sample points
omega = N.pi * 2 / period
xaxis = N.arange(samples,dtype = N.float)
ydata = 16384 * N.sin(xaxis*omega)
signal = N.resize(ydata, (samples,))
towrite += ''.join([wave.struct.pack('h',s) for s in signal])
f = wave.open('freqs.wav', 'wb')
f.setparams((1,2,44100, 44100*4, 'NONE', 'noncompressed'))
f.writeframes(towrite)
f.close()
Upvotes: 1