使用Python [summary]读取wav文件最简单的方法是什么?

时间:2010-01-14 09:51:36

标签: python audio wav scipy wave

我想使用Python访问wav文件,并以允许我分析它的形式编写其内容(比如数组)。

  1. 我听说“audiolab”是一个合适的工具(它将numpy数组转换为wav,反之亦然)。
  2. 我已经安装了“audiolab”,但我遇到了numpy版本的问题(我无法“从numpy.testing import Tester”)。我有1.1.1。 numpy版本。
  3. 我在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似乎不是正确的类型对象

  4. 我放弃使用audiolab并认为我可以使用“wave”包来读取wav文件。我问了一个关于这个的问题,但人们建议改用scipy。好吧,我决定专注于scipy(我有0.6.0。版本)。

  5. 但是当我尝试执行以下操作时:

    来自scipy.io import wavfile
    x = wavfile.read('/ usr / share / sounds / purple / receive.wav')

  6. 我得到以下内容:

    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
    
    1. 所以,我放弃使用scipy。我可以使用波包吗?我不需要太多。我只需要以人类可读的格式包含wav文件的内容,而不是我将弄清楚如何处理它。

8 个答案:

答案 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))