[英]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 位整數格式。
你會想要什么:
整數值范圍從 -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.