这是我的贡献。。。包括任意字长和任意数量的频道。
我已经冒昧地更改了float32_wav_文件,以包含一个保存用于测试的文件。注意,文件结构的多通道数据部分是交错的。我敢肯定,这个循环可能会被大Python化。在# see http://stackoverflow.com/questions/15576798/create-32bit-float-wav-file-in-python
# see... http://blog.theroyweb.com/extracting-wav-file-header-information-using-a-python-script
import struct
def float32_wav_file(file_name, sample_array, sample_rate):
(M,N)=sample_array.shape
#print "len sample_array=(%d,%d)" % (M,N)
byte_count = M * N * 4 # (len(sample_array)) * 4 # 32-bit floats
wav_file = ""
# write the header
wav_file += struct.pack('
'R', 'I', 'F', 'F',
byte_count + 0x2c - 8, # header size
'W', 'A', 'V', 'E', 'f', 'm', 't', ' ',
0x10, # size of 'fmt ' header
3, # format 3 = floating-point PCM
M, # channels
sample_rate, # samples / second
sample_rate * 4, # bytes / second
4, # block alignment
32) # bits / sample
wav_file += struct.pack('
'd', 'a', 't', 'a', byte_count)
print "packing..."
for j in range(0,N):
for k in range(0,M):
wav_file += struct.pack("
print "saving..."
fi=open(file_name,'wb')
for value in wav_file:
fi.write(value)
fi.close()
return wav_file
import numpy as np
def wav_file_read(filename):
fi=open(filename,'rb')
data=fi.read()
fi.close()
A, B, C, D =struct.unpack('4c', data[0:4]) # 'RIFF'
ChunkSize =struct.unpack('
A, B, C, D =struct.unpack('4c', data[8:12]) # 'WAVE'
A, B, C, D =struct.unpack('4c', data[12:16]) # 'fmt '
Subchunk1Size =struct.unpack('
AudioFormat =struct.unpack('
NumChannels =struct.unpack('
SampleRate =struct.unpack('
ByteRate =struct.unpack('
BlockAlign =struct.unpack('
BitsPerSample =struct.unpack('
A, B, C, D =struct.unpack('4c', data[36:40]) # BIG ENDIAN, char*4
SubChunk2Size =struct.unpack('
waveData=data[44:]
(M,N)=(len(waveData),len(waveData[0]))
print("ChunkSize =%d\nSubchunk1Size =%d\nAudioFormat =%d\nNumChannels =%d\nSampleRate =%d\nByteRate =%d\nBlockAlign =%d\nBitsPerSample =%d\nA:%c, B:%c, C:%c, D:%c\nSubChunk2Size =%d" %
(ChunkSize ,
Subchunk1Size,
AudioFormat ,
NumChannels ,
SampleRate ,
ByteRate ,
BlockAlign ,
BitsPerSample ,
A, B, C, D ,
SubChunk2Size ))
if BitsPerSample==8:
print "Unpacking 8 bits on len(waveData)=%d" % len(waveData)
d=np.fromstring(waveData,np.uint8)
floatdata=d.astype(np.float64)/np.float(127)
elif BitsPerSample==16:
print "Unpacking 16 bits on len(waveData)=%d" % len(waveData)
d=np.zeros(SubChunk2Size/2, dtype=np.int16)
j=0
for k in range(0, SubChunk2Size, 2):
d[j]=struct.unpack('
j=j+1
floatdata=d.astype(np.float64)/np.float(32767)
elif BitsPerSample==24:
print "Unpacking 24 bits on len(waveData)=%d" % len(waveData)
d=np.zeros(SubChunk2Size/3, dtype=np.int32)
j=0
for k in range(0, SubChunk2Size, 3):
d[j]=struct.unpack('
j=j+1
floatdata=d.astype(np.float64)/np.float(2147483647)
else: # anything else will be considered 32 bits
print "Unpacking 32 bits on len(waveData)=%d" % len(waveData)
d=np.fromstring(waveData,np.int32)
floatdata=d.astype(np.float64)/np.float(2147483647)
v=floatdata[0::NumChannels]
for i in range(1,NumChannels):
v=np.vstack((v,floatdata[i::NumChannels]))
#return (np.vstack((floatdata[0::2],floatdata[1::2])), SampleRate, NumChannels, BitsPerSample)
return (v, SampleRate, NumChannels, BitsPerSample)
if __name__ == "__main__":
(array,SampleRate,NumChannels,BitsPerSample)=wav_file_read("my_input_file.wav")
wavefile=float32_wav_file("test_file.wav",array,SampleRate)