繁体   English   中英

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

[英]how to convert wav file to float amplitude

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

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

任何人都有将 WAV 数据转换为浮点数的想法?

我已经确定了两种体面的方法来做到这一点。

方法一:使用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))

方法二:使用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))

我花了几个小时试图找到这个问题的答案。 结果证明解决方案非常简单: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 唯一的技巧是获得正确的解包格式:它必须是正确的字节数和正确的格式(有符号或无符号)。

大多数波形文件都是 PCM 16 位整数格式。

你会想要什么:

  • 解析标题以知道它是哪种格式(检查来自 Xophmeister 的链接)
  • 读取数据,取整数值并将它们转换为浮点数

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

我没有python中的代码,但是在C++中,如果PCM数据是16位整数,这里是一段代码摘录,并将其转换为浮点数(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)。 您可能需要也可能不需要去交织,具体取决于您对数据的处理方式。

此版本从文件系统读取 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

Microsoft WAVE 格式有很好的文档记录。 例如,请参见https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ 编写一个文件解析器来打开和解释数据以获取您需要的信息并不会花太多时间......也就是说,几乎可以肯定以前已经完成了,所以我相信有人会给出一个“更简单”的答案; )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM