仕事柄ファイルフォーマットについて関心をもつようになったので、今回はwavファイルのファイルフォーマットを自分の手でプログラムを書いて分析してみることにしました。
以下のような0秒未満の効果音に対してミリ秒単位での再生時間を算出することをしてみたいと思います。
ヘッダーの解析
ヘッダーには様々な情報が記載されています。
フォーマットとしては素直で固定長で、ここからここまではチャンネル数、ここからここまではブロックサイズとなっています。
file_path = "./input/youfit.wav" wav_data = open(file_path, "rb") contents = wav_data.read() wav_data.close() print(contents) # ヘッダー情報を出力します。 print('RIFF = ' + repr(contents[0:4])) print('チャンクサイズ = ' + str(int.from_bytes(contents[4:8], byteorder='little'))) print('フォーマット = ' + repr(contents[8:12])) print('fmt識別子 = ' + repr(contents[12:16])) print('fmtチャンクのバイト数 = ' + str(int.from_bytes(contents[16:20], byteorder='little'))) print('音声フォーマット = ' + str(int.from_bytes(contents[20:22], byteorder='little'))) print('チャンネル数 = ' + str(int.from_bytes(contents[22:24], byteorder='little'))) print('サンプリング周波数(Hz) = ' + str(int.from_bytes(contents[24:28], byteorder='little') / 1000)) print('1秒あたりのバイト数平均 = ' + str(int.from_bytes(contents[28:32], byteorder='little'))) print('ブロックサイズ = ' + str(int.from_bytes(contents[32:34], byteorder='little'))) print('ビット/サンプル = ' + str(int.from_bytes(contents[34:36], byteorder='little'))) print('サブチャンク識別子2 = ' + repr(contents[36:40])) print('サブチャンク識別子2サイズ = ' + str(int.from_bytes(contents[40:44], byteorder='little')))
再生時間
再生時間 = 波形データサイズ / 1秒あたりのバイト数平均
で割り出せそうですね。
音声を波形に
今回のデータは1サンプル16bit(2bytes)となります。2bytesずつ取得していくことになります。
ステレオだと左、右、左、右と順に取得するのややこしいのですがチャンネルが1つのモノラルです。
全て取得して表示すると、よくわからなくなるので一部を取得して折れ線にしてみます。
参考サイト
[小ネタ]バイナリを文字列として出力するrepr()[python] | KentaKomai Blog