加快python中wav的读取速度

2024-06-23 18:28:12 发布

您现在位置:Python中文网/ 问答频道 /正文

晚上好

我正在做一个项目,要求我在32位浮点的多通道wav文件中读取。 当我把一个特定的文件(1分钟长,6个通道,48k fs)读入Matlab并用tic/toc进行测量时,它在2.456482秒内解析了该文件。在

文件读取速度测量的Matlab代码 抽搐 wavread('C:/data/testData/6)ch.wav公司'); 总有机碳

当我用python(请注意,我对python很不熟悉)时,需要18.1655315617秒! 在我看来,我这样做是低效的(我确实把它从28降到了18,但还是太多了…)

我将代码剥离到与此主题相关的部分:

Python文件读取速度测量代码

import wave32
import struct
import time
import numpy as np

def getWavData(inFile)
    wavFile = wave32.open(inFile, 'r')
    wavParams = wavFile.getparams()
    nChannels = wavParams[0]
    byteDepth = wavParams[1]
    nFrames = wavParams[3]
    wavData = np.empty([nFrames, nChannels], np.float32)
    frames = wavFile.readframes(nFrames) 
    for i in range(nFrames):
        for j in range(nChannels):
            start = ( i * nChannels + j ) * byteDepth
            stop = start + byteDepth
            wavData[i][j] = struct.unpack('<f', frames[start:stop])[0]
    return wavData

inFile = 'C:/data/testData/6ch.wav'
start = time.clock() 
data2 = getWavData(inFile)
elapsed = time.clock()
elapsedNew = elapsed - start
print str(elapsedNew)

请不要说wav32是我必须执行的一个小黑客波浪.py启用32位浮点读取。在

^{pr2}$

抱歉,代码太长了BTW:)


所以我的问题是波浪.py模块固有的慢(有没有其他方法可以解决这个问题?)还是我在做低效的事?在

我想我可以用一个自定义函数读入wav头文件,然后用另一种方式读入文件,但这似乎需要大量的工作,尤其是因为我对1)python和2)文件处理知之甚少

谨致问候

K


编辑:我尝试了unutbu的建议,但这不起作用,因为scipy不接受>;16位。在

当我试图通过scipy wavreader解析wav文件时,我收到了以下消息:

C:\Users\King Broos\AppData\Local\Enthought\Canopy32\System\lib\site-packages\scipy\io\wavfile.py:31: WavFileWarning: Unfamiliar format bytes
  warnings.warn("Unfamiliar format bytes", WavFileWarning)

C:\Users\King Broos\AppData\Local\Enthought\Canopy32\System\lib\site-packages\scipy\io\wavfile.py:121: WavFileWarning: chunk not understood
  warnings.warn("chunk not understood", WavFileWarning)

调查wavfile.py文件这是它抛出异常的行:

    if (comp != 1 or size > 16):
    warnings.warn("Unfamiliar format bytes", WavFileWarning)

我真的需要24位或32位所以我想scipy不是一个选择?在


Tags: 文件代码pyimporttimenpscipystart
1条回答
网友
1楼 · 发布于 2024-06-23 18:28:12

如果您可以安装或拥有scipy,则使用wavfile.read

import scipy.io.wavfile as wavfile
sample_rate, x = wavfile.read(filename)

您可能还需要研究source code, here。在


注意,scipy.io.wavfile不使用Python的wave模块。我不确定它是否读取您的IEEE浮点数格式,但它不会执行与wave.py相同的检查:

^{pr2}$

所以也许它会开箱即用。在


顺便说一句,您可以使用monkey patching来代替您自己的模块wave32.py,它与标准库中的wave.py几乎完全相同:

import wave
import struct

WAVE_FORMAT_IEEE_FLOAT = 0x0003
def _read_fmt_chunk(self, chunk):
    wFormatTag, self._nchannels, self._framerate, dwAvgBytesPerSec, wBlockAlign = struct.unpack('<hhllh', chunk.read(14))
    if wFormatTag == WAVE_FORMAT_PCM or wFormatTag == WAVE_FORMAT_IEEE_FLOAT:
        sampwidth = struct.unpack('<h', chunk.read(2))[0]
        self._sampwidth = (sampwidth + 7) // 8
    else:
        raise Error, 'unknown format: %r' % (wFormatTag,)
    self._framesize = self._nchannels * self._sampwidth
    self._comptype = 'NONE'
    self._compname = 'not compressed'

wave.Wave_read._read_fmt_chunk = _read_fmt_chunk

相关问题 更多 >

    热门问题