我想使用Python访问wav文件,并以允许我分析它的形式编写其内容(比如数组)。
我在numpy(1.4.0)上安装了更新的版本。但后来我遇到了一系列新的错误:
追踪(最近一次通话): 文件“test.py”,第7行,in 导入scikits.audiolab 文件“/usr/lib/python2.5/site-packages/scikits/audiolab/init.py”,第25行,in 来自pysndfile import formatinfo,sndfile 文件“/usr/lib/python2.5/site-packages/scikits/audiolab/pysndfile/init.py”,第1行,in 来自_sndfile导入Sndfile,Format,available_file_formats,available_encodings 在scikits.audiolab.pysndfile._sndfile中文件“numpy.pxd”,第30行(scikits / audiolab / pysndfile / _sndfile.c:9632) ValueError:numpy.dtype似乎不是正确的类型对象
我放弃使用audiolab并认为我可以使用“wave”包来读取wav文件。我问了一个关于这个的问题,但人们建议改用scipy。好吧,我决定专注于scipy(我有0.6.0。版本)。
但是当我尝试执行以下操作时:
来自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
答案 0 :(得分:11)
你试过波浪模块吗?它具有较少的依赖性:
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
答案 1 :(得分:6)
我在std lib中的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
希望这会有所帮助
答案 2 :(得分:5)
这对我来说已经足够了
import numpy as np
x = np.fromfile(open('song.wav'),np.int16)[24:]
它会忽略前24个值,因为它不是音频,而是标题。
另外,如果文件是立体声,你的频道将有交替的索引,所以我通常只用Audacity将其缩小为单声道。
答案 3 :(得分:4)
您还可以使用wave模块和numpy.fromstring()函数将其转换为数组
import wave
import numpy
fp = wave.open('test.wav')
nchan = fp.getnchannels()
N = fp.getnframes()
dstr = fp.readframes(N*nchan)
data = numpy.fromstring(dstr, numpy.int16)
data = numpy.reshape(data, (-1,nchan))
答案 4 :(得分:2)
在尝试了许多不起作用的东西之后,我使用了Use (Python) Gstreamer to decode audio (to PCM data)中的解码库并构建了一个函数来将原始pcm数据解析为scipy数组。
很好,可以打开gstreamer可以打开的任何音频文件: http://gist.github.com/592776(请参阅测试和文件末尾的使用信息)
答案 5 :(得分:1)
audiolab是最好的方法,但它并不适用于所有环境,开发人员也没有这样做。我还在使用Python 2.5,所以我可以使用它。
您安装了libsndfile吗?
答案 6 :(得分:1)
audiolab似乎不再维护,您应该尝试PySoundFile。
安装很简单:
pip install PySoundFile --user
同时阅读声音文件:
import soundfile as sf
x, fs = sf.read('/usr/share/sounds/purple/receive.wav')
看看这个overview about different Python libraries for handling sound files。
答案 7 :(得分:0)
pydub提供了一个更简单的解决方案,无需安装任何依赖项(对于wav文件)。我目前在生产中使用这种方法没有任何问题。
from pydub import AudioSegment
awesome_song = AudioSegment.from_wav('awesome_song.wav')
print('Duration in seconds is {}'.format(awesome_song.duration_seconds))