简体   繁体   English

Python 和波形样本宽度

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM