如何将wav文件转换为浮动幅度

时间:2011-10-14 15:32:52

标签: python audio wave pyaudio

所以我问了标题中的所有内容:

我有一个波形文件(由输入音频中的PyAudio编写),我想将其转换为与声级(振幅)相对应的浮点数据,以进行一些傅里叶变换等...

任何人都有想法将WAVE数据转换为浮动数据吗?

5 个答案:

答案 0 :(得分:10)

我已经确定了两种不错的方法。

方法1:使用wavefile模块

如果您不介意安装一些额外的库,这些库在我的Mac上有点乱,但在我的Ubuntu服务器上很容易,请使用此方法。

https://github.com/vokimon/python-wavefile

import wavefile

# returns the contents of the wav file as a double precision float array
def wav_to_floats(filename = 'file1.wav'):
    w = wavefile.load(filename)
    return w[1][0]

signal = wav_to_floats(sys.argv[1])
print "read "+str(len(signal))+" frames"
print  "in the range "+str(min(signal))+" to "+str(min(signal))

方法2:使用wave模块

如果您希望减少模块安装麻烦,请使用此方法。

从文件系统读取一个wav文件并将其转换为-1到1范围内的浮点数。它适用于16位文件,如果它们是> 1个通道,将以与文件中相同的方式交错样本。对于其他位深度,请根据本页底部的表格将参数中的“h”更改为struct.unpack:

https://docs.python.org/2/library/struct.html

它不适用于24位文件,因为没有24位的数据类型,所以没有办法告诉struct.unpack要做什么。

import wave
import struct
import sys

def wav_to_floats(wave_file):
    w = wave.open(wave_file)
    astr = w.readframes(w.getnframes())
    # convert binary chunks to short 
    a = struct.unpack("%ih" % (w.getnframes()* w.getnchannels()), astr)
    a = [float(val) / pow(2, 15) for val in a]
    return a

# read the wav file specified as first command line arg
signal = wav_to_floats(sys.argv[1])
print "read "+str(len(signal))+" frames"
print  "in the range "+str(min(signal))+" to "+str(min(signal))

答案 1 :(得分:5)

大多数波形文件采用PCM 16位整数格式。

您想要的:

  • 将标头解析为已知的格式(检查来自Xophmeister的链接)
  • 读取数据,取整数值并将它们转换为float

整数值范围从-32768到32767,您需要在浮点中转换为-1.0到1.0的值。

我没有python中的代码,但是在C ++中,如果PCM数据是16位整数,这里是代码摘录,并将其转换为float(32位):

short* pBuffer = (short*)pReadBuffer;

const float ONEOVERSHORTMAX = 3.0517578125e-5f; // 1/32768 
unsigned int uFrameRead = dwRead / m_fmt.Format.nBlockAlign;

for ( unsigned int i = 0; i < uFrameCount * m_fmt.Format.nChannels; ++i )
{
    short i16In = pBuffer[i];
    out_pBuffer[i] = (float)i16In * ONEOVERSHORTMAX;
}

小心立体声文件,因为波形文件中的立体声PCM数据是交错的,这意味着数据看起来像LRLRLRLRLRLRLRLR(而不是LLLLLLLLRRRRRRRR)。根据您对数据的处理方式,您可能需要也可能不需要解交错。

答案 2 :(得分:5)

我花了好几个小时试图找到答案。解决方案结果非常简单:struct.unpack是您正在寻找的。最终的代码看起来像这样:

rawdata=stream.read()                  # The raw PCM data in need of conversion
from struct import unpack              # Import unpack -- this is what does the conversion
npts=len(rawdata)                      # Number of data points to be converted
formatstr='%ih' % npts                 # The format to convert the data; use '%iB' for unsigned PCM
int_data=unpack(formatstr,rawdata)     # Convert from raw PCM to integer tuple

大部分功劳归于Interpreting WAV Data。唯一的技巧是使格式正确解压缩:它必须是正确的字节数和正确的格式(有符号或无符号)。

答案 3 :(得分:1)

此版本从文件系统读取 wav 文件并将其转换为 -1 到 1 范围内的浮点数。它适用于所有样本宽度的文件,并以在文件中找到的相同方式交错样本。

import wave

def read_wav_file(filename):
    def get_int(bytes_obj):
        an_int = int.from_bytes(bytes_obj, 'little',  signed=sampwidth!=1)
        return an_int - 128 * (sampwidth == 1)
    with wave.open(filename, 'rb') as file:
        sampwidth = file.getsampwidth()
        frames = file.readframes(-1)
    bytes_samples = (frames[i : i+sampwidth] for i in range(0, len(frames), sampwidth))
    return [get_int(b) / pow(2, sampwidth * 8 - 1) for b in bytes_samples]

这里还有一个链接,该函数将浮点数转换回整数并将它们写入所需的 wav 文件:

https://gto76.github.io/python-cheatsheet/#writefloatsamplestowavfile

答案 4 :(得分:0)

Microsoft WAVE格式已有详细记录。例如,请参阅https://ccrma.stanford.edu/courses/422/projects/WaveFormat/。编写一个文件解析器来打开和解释数据以获取你需要的信息并不需要太多...这就是说,它几乎肯定已经完成了,所以我相信有人会给出一个“更容易”的答案; )