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

Rom*_*man 7 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号线,在进口scikits.audiolab文件"/usr/lib/python2.5/site-packages/scikits/audiolab/ 初始化 py"为25行,从pysndfile进口formatinfo,sndfile文件"/usr/lib/python2.5/site-packages/scikits/audiolab/pysndfile/ 初始化的.py",1号线,从_sndfile进口sndfile,格式,available_file_formats,available_encodings文件"numpy的.pxd",第30行,在scikits.audiolab.pysndfile._sndfile中(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')

我得到以下内容:

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

小智 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
Run Code Online (Sandbox Code Playgroud)

  • 而不是everyOther,使用[0 :: 2]和out [1 :: 2]. (8认同)

Jia*_*aro 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
Run Code Online (Sandbox Code Playgroud)

希望这会有所帮助


Nat*_*han 5

这对我来说已经足够了

import numpy as np
x = np.fromfile(open('song.wav'),np.int16)[24:]
Run Code Online (Sandbox Code Playgroud)

它会忽略前24个值,因为它不是音频,而是标题.

此外,如果文件是立体声,您的频道将具有交替索引,所以我通常只使用Audacity将其缩小为单声道.


小智 5

您还可以使用 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))
Run Code Online (Sandbox Code Playgroud)


end*_*ith 1

audiolab是最好的方法,但它并不适用于所有环境,而且开发人员也没有致力于它。我仍在使用Python 2.5,所以我可以使用它。

你安装了libsndfile吗?