使用Python读取wav文件的最简单方法是什么[总结]?
我想用Python来读取一个wav文件,并把它的内容写成可以分析的形式(比如说数组)。
- 我听说“audiolab”是一个合适的工具(它可以把numpy数组转换成wav文件,反之亦然)。
- 我安装了“audiolab”,但遇到了numpy版本的问题(我无法使用“from numpy.testing import Tester”)。我当时的numpy版本是1.1.1。
我安装了一个更新的numpy版本(1.4.0)。但是我又遇到了新的错误:
错误追踪(最近的调用在最前面): 文件 "test.py",第7行,
import scikits.audiolab
文件 "/usr/lib/python2.5/site-packages/scikits/audiolab/init.py",第25行,
from pysndfile import formatinfo, sndfile
文件 "/usr/lib/python2.5/site-packages/scikits/audiolab/pysndfile/init.py",第1行,
from _sndfile import Sndfile, Format, available_file_formats, available_encodings
文件 "numpy.pxd",第30行,在 scikits.audiolab.pysndfile._sndfile (scikits/audiolab/pysndfile/_sndfile.c:9632)
ValueError: numpy.dtype似乎不是正确的类型对象我放弃了使用audiolab,想用“wave”包来读取wav文件。我问了这个问题,但大家推荐我用scipy。好吧,我决定专注于scipy(我有0.6.0版本)。
但是当我尝试以下操作时:
from scipy.io import wavfile
x = wavfile.read('/usr/share/sounds/purple/receive.wav')
我得到了以下内容:
Traceback (most recent call last):
File "test3.py", line 4, in <module>
from scipy.io import wavfile
File "/usr/lib/python2.5/site-packages/scipy/io/__init__.py", line 23, in <module>
from numpy.testing import NumpyTest
ImportError: cannot import name NumpyTest
- 所以,我放弃了使用scipy。我可以只用wave包吗?我不需要太多。我只需要把wav文件的内容转换成人类可读的格式,然后我再想办法处理。
8 个回答
这对我来说已经足够好了
import numpy as np
x = np.fromfile(open('song.wav'),np.int16)[24:]
它会忽略前面24个值,因为那些不是音频数据,而是文件的头部信息。
另外,如果这个文件是立体声的,你的声道会交替出现索引。所以我通常会先用Audacity把它转换成单声道。
我写了一个简单的工具,封装了标准库中的wave模块。这个工具叫做 pydub,它有一个方法可以把音频数据中的样本读取为整数。
>>> from pydub import AudioSegment
>>> song = AudioSegment.from_wav("your_song.wav")
<pydub.audio_segment.AudioSegment at 0x1068868d0>
>>> # This song is stereo
>>> song.channels
2
>>> # get the 5000th "frame" in the song
>>> frame = song.get_frame(5000)
>>> sample_left, sample_right = frame[:2], frame[2:]
>>> def sample_to_int(sample):
return int(sample.encode("hex"), 16)
>>> sample_to_int(sample_left)
8448
>>> sample_to_int(sample_right)
9984
希望这对你有帮助。
你试过使用wave模块吗?这个模块的依赖性比较少:
http://docs.python.org/library/wave.html
def everyOther (v, offset=0):
return [v[i] for i in range(offset, len(v), 2)]
def wavLoad (fname):
wav = wave.open (fname, "r")
(nchannels, sampwidth, framerate, nframes, comptype, compname) = wav.getparams ()
frames = wav.readframes (nframes * nchannels)
out = struct.unpack_from ("%dh" % nframes * nchannels, frames)
# Convert 2 channles to numpy arrays
if nchannels == 2:
left = array (list (everyOther (out, 0)))
right = array (list (everyOther (out, 1)))
else:
left = array (out)
right = left