WASY-LOG

たいした話はしません

PythonでWAVEファイルのヘッダ情報の読み取り

環境

Python 3.6.0

WAVEファイルの構造について

パラメータ サイズ[byte] 内容
riff_chunk_id 4 ‘RIFF’
riff_chunk_size 4 size + 36
riff_form_type 4 ‘WAVE’
fmt_chunk_id 4 ‘fmt ‘
fmt_chunk_size 4 16
fmt_wave_format_type 2 PCM: 1
fmt_channel 2 モノラル:1, ステレオ:2
fmt_samples_per_sec 4 サンプリングレート
fmt_bytes_per_sec 4
fmt_block_size 2
fmt_bits_per_sample 2 量子化精度
data_chunk_id 4 ‘data’
data_chunk_size 4 size + 36
data_data size 音データ

WAVファイルの基本的な構造はこのようになっており,これ全体でRIFFチャンクと呼ばれる.サブチャンクとしてfmtチャンクとdataチャンクが存在し,それぞれの持つパラメータには対応する名前をつけてある.
block_sizeはwavファイルとして記録した音の最小単位のバイト数を表し,8bitモノラルなら1,1bitステレオなら2,2bitモノラルなら2…となる.bytes_per_secは1秒間の音の記録に必要なデータ量で,block_sizeとsamples_per_secを乗じたもの.
なお,各チャンク及びサブチャンクのchunk_idとriff_form_typeがビッグエンディアンで,それ以外はリトルエンディアンである.

コード

import sys
from pprint import pprint

filename = sys.argv[1]

wavfile = open(filename, 'rb')

wav_header = {}

wav_header['riff_chunk_id'] = wavfile.read(4).decode('ascii')
wav_header['riff_chunk_size'] = int.from_bytes(wavfile.read(4), 'little')
wav_header['riff_form_type'] = wavfile.read(4).decode('ascii')
wav_header['fmt_chunk_id'] = wavfile.read(4).decode('ascii')
wav_header['fmt_chunk_size'] = int.from_bytes(wavfile.read(4), 'little')
wav_header['fmt_wave_format_type'] = int.from_bytes(wavfile.read(2), 'little')
wav_header['fmt_channel'] = int.from_bytes(wavfile.read(2), 'little')
wav_header['fmt_samples_per_sec'] = int.from_bytes(wavfile.read(4), 'little')
wav_header['fmt_bytes_per_sec'] = int.from_bytes(wavfile.read(4), 'little')
wav_header['fmt_block_size'] = int.from_bytes(wavfile.read(2), 'little')
wav_header['fmt_bits_per_sample'] = int.from_bytes(wavfile.read(2), 'little')
wav_header['data_chunk_id'] = wavfile.read(4).decode('ascii')
wav_header['data_chunk_size'] = int.from_bytes(wavfile.read(4), 'little')

pprint(wav_header)

出力

{'data_chunk_id': 'data',
 'data_chunk_size': 1755180,
 'fmt_bits_per_sample': 16,
 'fmt_block_size': 4,
 'fmt_bytes_per_sec': 176400,
 'fmt_channel': 2,
 'fmt_chunk_id': 'fmt ',
 'fmt_chunk_size': 16,
 'fmt_samples_per_sec': 44100,
 'fmt_wave_format_type': 1,
 'riff_chunk_id': 'RIFF',
 'riff_chunk_size': 1755216,
 'riff_form_type': 'WAVE'}

おしまい

参考