[英]Python and wave sample width
I'm playing around with the wave library and I'm having trouble saving a sine to a wave file whose resolution is more than 8 bits.我正在使用波形库,但无法将正弦保存到分辨率超过 8 位的波形文件中。 My program works fine for 8 bits resolution (WIDTH = 1 byte in my program and comment out one line).我的程序在 8 位分辨率下运行良好(程序中的宽度 = 1 个字节并注释掉一行)。 If I use WIDTH = 2, the program works, but the output wave file does not look like a sine.如果我使用 WIDTH = 2,程序可以工作,但输出波形文件看起来不像正弦。
I hope I can get some help!我希望我能得到一些帮助!
import math
import wave
import struct
BITRATE = 44100
FREQUENCY = 440
LENGTH = 1 # in seconds
WIDTH = 2 # in bytes. 1->8 bits, 2->16 bits
def GenerateSine(NumberOfFrames):
wave = ''
for i in xrange(NumberOfFrames):
value = math.sin(i * 2 * math.pi * FREQUENCY / BITRATE)
value += 1
value /= 2
value *= (256 ** WIDTH) - 1
value = int(round(value))
#wave += struct.pack("<B", value) # this is good for WIDTH = 1
wave += struct.pack("<H", value) # i would think this would work for WIDTH = 2
return wave
WaveData = GenerateSine(int(BITRATE * LENGTH))
wf = wave.open("output.wave", 'w')
wf.setnchannels(1)
wf.setsampwidth(WIDTH)
wf.setframerate(BITRATE)
wf.writeframes(WaveData)
wf.close()
Got it to work!得到它的工作! I think the problem was that for WIDTH > 1, I must use a signed integer instead of unsigned.我认为问题是对于 WIDTH > 1,我必须使用有符号整数而不是无符号整数。
Here's something that works for WIDTH = 2 or WIDTH = 4. It won't work with WIDTH = 1 or 3, but that's fine for what I want to do.这里有一些适用于 WIDTH = 2 或 WIDTH = 4 的东西。它不适用于 WIDTH = 1 或 3,但这对我想做的事情来说很好。
import math
import wave
import struct
BITRATE = 44100
FREQUENCY = 440
LENGTH = 1
WIDTH = 2
def GenerateSine(NumberOfFrames):
wave = ''
for i in xrange(NumberOfFrames):
value = math.sin(i * 2 * math.pi * FREQUENCY / BITRATE)
value *= 128
value *= (256 ** (WIDTH - 1)) - 1
value = int(round(value))
if WIDTH == 2:
wave += struct.pack("<h", value)
elif WIDTH == 4:
wave += struct.pack("<l", value)
return wave
WaveData = GenerateSine(int(BITRATE * LENGTH))
wf = wave.open("output.wave", 'w')
wf.setnchannels(1)
wf.setsampwidth(WIDTH)
wf.setframerate(BITRATE)
wf.writeframes(WaveData)
wf.close()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.