所以基本上我试图读取波形文件的信息,以便我可以获取字节信息并创建一个时间 - >幅度点数组。
import wave
class WaveFile:
# `filename` is the name of the wav file to open
def __init__(self, fileName):
self.wf = wave.open(fileName, 'r')
self.soundBytes = self.wf.readframes(-1)
self.timeAmplitudeArray = self.__calcTimeAmplitudeArray()
def __calcTimeAmplitudeArray(self):
self.internalTimeAmpList = [] # zero out the internal representation
byteList = self.soundBytes
if((byteList[i+1] & 0x080) == 0):
amp = (byteList[i] & 0x0FF) + byteList[i+1] << 8
#more code continues.....
错误:
if((int(byteList[i+1]) & 0x080) == 0):
TypeError: unsupported operand type(s) for &: 'str' and 'int'
我尝试使用int()
转换为整数类型,但无济于事。我来自Java背景,这可以使用byte
类型完成,但这似乎不是Python的语言特性。任何方向都会受到赞赏。
答案 0 :(得分:2)
你的问题来自于wave库只是给你原始的二进制数据(以字符串的形式)。
您可能需要使用self.wf.getparams()
检查数据的格式。这将返回(nchannels, sampwidth, framerate, nframes, comptype, compname)
。如果你有1个通道,样本宽度为2,没有压缩(相当常见的wave类型),你可以使用以下(import numpy as np)来获取数据:
byteList = np.fromstring(self.soundBytes,'<h')
这将返回带有数据的numpy数组。你不需要循环。如果你有不同的样本宽度,你需要在第二个参数中有不同的东西。我已经使用简单的.wav
文件和plot(byteList); show()
(iPython中的pylab模式)进行了测试。
有关其他方法,请参阅Reading *.wav files in Python。
如果你需要避免numpy,你可以这样做:
import array
bytelist = array.array('h')
byteList.fromstring(self.soundBytes)
这与以前一样(使用plot(byteList); show()
测试)。 'h'表示签名短。 len
等有效。这确实一次导入了wav文件,但是再次.wav通常很小。并非总是如此。
答案 1 :(得分:1)
我通常使用array-module和fromstring方法。
我操作数据块的标准模式是:
def bytesfromfile(f):
while True:
raw = array.array('B')
raw.fromstring(f.read(8192))
if not raw:
break
yield raw
with open(f_in, 'rb') as fd_in:
for byte in bytesfromfile(fd_in):
# do stuff
高于'B'
表示无符号字符,即1字节。
如果文件不是很大,那么你可以嘟嘟它:
In [8]: f = open('foreman_cif_frame_0.yuv', 'rb')
In [9]: raw = array.array('B')
In [10]: raw.fromstring(f.read())
In [11]: raw[0:10]
Out[11]: array('B', [10, 40, 201, 255, 247, 254, 254, 254, 254, 254])
In [12]: len(raw)
Out[12]: 152064
如果您更喜欢numpy,我倾向于使用:
fd_i = open(file.bin, 'rb')
fd_o = open(out.bin, 'wb')
while True:
# Read as uint8
chunk = np.fromfile(fd_i, dtype=np.uint8, count=8192)
# use int for calculations since uint wraps
chunk = chunk.astype(np.int)
if not chunk.any():
break
# do some calculations
data = ...
# convert back to uint8 prior to writing.
data = data.astype(np.uint8)
data.tofile(fd_o)
fd_i.close()
fd_o.close()
或阅读整个文件:
In [18]: import numpy as np
In [19]: f = open('foreman_cif_frame_0.yuv', 'rb')
In [20]: data = np.fromfile(f, dtype=np.uint8)
In [21]: data[0:10]
Out[21]: array([ 10, 40, 201, 255, 247, 254, 254, 254, 254, 254], dtype=uint8)