What is the easiest way to read wav-files using Python [summary]?

落爺英雄遲暮 提交于 2019-11-28 08:44:00

Have you tried the wave module? It has fewer dependencies:

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

I wrote a simple wrapper over the wave module in the std lib. it's called pydub and it has a method for reading samples from the audio data as ints.

>>> 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

Hopefully this helps

Nathan

This is good enough for me

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

It ignores the first 24 values, because that's not audio, it the header.

Also, if the file was stereo, your channels will have alternating indexes, So I usually just reduce it to mono with Audacity first.

You can also use the wave module along with the numpy.fromstring() function to convert it to an array

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))
Dominik

After trying so many things that does not work I used the decode library from Use (Python) Gstreamer to decode audio (to PCM data) and build a function to parse the raw pcm data into a scipy array.

It's nice and can open any audio file that gstreamer can open: http://gist.github.com/592776 (see Test and the end of the file for usage info)

endolith

audiolab is the best way, but it doesn't work in every environment and the developer's not working on it. I'm still using Python 2.5 so I can use it.

Did you install libsndfile?

audiolab seems to be not maintained anymore, you should try PySoundFile.

Installation is simple:

pip install PySoundFile --user

And reading a sound file as well:

import soundfile as sf
x, fs = sf.read('/usr/share/sounds/purple/receive.wav')

Have a look at this overview about different Python libraries for handling sound files.

pydub provides an even easier solution without any dependencies needing to be installed (for wav files). I'm currently using this method in production without any issues.

from pydub import AudioSegment
awesome_song = AudioSegment.from_wav('awesome_song.wav')
print('Duration in seconds is {}'.format(awesome_song.duration_seconds))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!