2012-03-19 168 views
2

我需要以24位pcm格式从wav文件中读取数据,并将其转换为浮点数。我正在使用Python 2.7.2。将24位wav pcm格式转换为浮点型的更快方法?

波包作为一个字符串读取数据,所以我已经试过是:

import wave 
import numpy as np 
import array 
import struct 

f = wave.open('filename.wav') 
# read in entire wav file 
wdata = f.readframes(nFrames) 
f.close() 

# unpack into signed integers and convert to float  
data = array.array('f') 
for i in range(0,nFrames*3,3): 
    data.append(float(struct.unpack('<i', '\x00'+ wdata[i:i+3])[0])) 

# normalize sample values 
data = np.array(data) 
data = data/0x800000 

这是相当多的比我以前的方法更快,但仍相当缓慢。任何人都可以提出更有效的方法吗?

+1

显然你有NumPy的。为什么不全程使用它? – 2012-03-19 23:27:24

回答

1

这似乎是相当快的,它可以处理24位的值,它正常化:

from scikits.audiolab import Sndfile 
import numpy as np 

f = Sndfile(fname, 'r') 
data = np.array(f.read_frames(f.nframes), dtype=np.float64) 
f.close() 
return data 
+0

您不需要转换为'np.array',因为'read_frames()'已经返回一个'np.array '。你甚至可以指定一个'dtype'参数,但是要知道,如果你使用的是一个不是'np.float64'的类型,那么当前(版本0.11.0)有一个错误:https://github.com/cournape/audiolab/问题/ 3 – Matthias 2013-11-06 09:08:15

+0

'scikits.audiolab'似乎不再被维护。作为一个(很可能同样快)的选择,你可以尝试[PySoundFile](http://pysoundfile.readthedocs.org/)。 – Matthias 2015-09-17 12:27:24

0
import sndhdr, wave, struct 
if sndhdr.what(fname)[0] != 'wav' 
    raise StandardError("file doesn't have wav header") 
try: 
    wav = wave.open(fname) 
    params = (nchannels,sampwidth,rate,nframes,comp,compname) = wav.getparams() 
    frames = wav.readframes(nframes*nchannels) 
finally: 
    wav.close() 
out = struct.unpack_from ("%dh" % nframes*nchannels, frames) 
+1

将两个字节的数据转换为一个整数,但数据宽度为三个字节。 FWIW,对于采样宽度大于2的wav pcm格式,sndhdr在wave不识别时识别官方格式,因此可能存在另一个错误条件。 – LMO 2012-03-20 01:29:36

+0

这看起来很快: – LMO 2012-03-20 04:49:37

+0

如何将此'out'转换为二维numpy数组? ('np.array(out)'只给出1个数组,所以我们不能处理2个通道) – Basj 2013-11-13 20:17:40