だから私はタイトルのすべてを尋ねました:
私はwavファイル(入力オーディオからPyAudioによって書かれたもの)を持っていて、それをサウンドレベル(振幅)に対応するfloatデータに変換して、フーリエ変換などを行いたい...
WAVデータをfloatに変換するアイデアはありますか?
これを行うための2つの適切な方法を特定しました。
方法 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: ウェーブ モジュールを使用する
モジュールのインストールの手間を減らしたい場合は、この方法を使用してください。
ファイルシステムから 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
功績のほとんどはWAV データの解釈にあります。唯一の秘訣は、unpack の正しいフォーマットを取得することです。正しいバイト数と正しいフォーマット (符号付きまたは符号なし) でなければなりません。
ほとんどのウェーブ ファイルは、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;
}
Wave ファイルのステレオ PCM データはインターリーブされているため、ステレオ ファイルには注意してください。つまり、データは (LLLLLLLLRRRRRRRR ではなく) LRLRLRLRLRLRLRLR のように見えます。データの処理内容に応じて、インターリーブを解除する必要がある場合とない場合があります。
Microsoft WAVE 形式は、かなり詳細に文書化されています。たとえば、https://ccrma.stanford.edu/courses/422/projects/WaveFormat/を参照してください。ファイル パーサーを作成してデータを開いて解釈し、必要な情報を取得するのにそれほど時間はかかりません。 )