WAVEファイルを解析する
はじめに
なんとなく音声の波形を取ってみたいと思った! とりあえずWAVEファイルから! 言語はなんでもいいけど, バイナリ扱うのが得意なErlangでやってみようと思う.
WAVEファイルのフォーマット
バイト数 | 内容 |
---|---|
4 | RIFF |
4 | 以降のファイルサイズ(だから全体のバイト数 - 8バイト) |
4 | WAVE |
4 | fmt (最後にスペースがある) |
4 | fmtチャンクのバイト数 |
2 | フォーマットID |
2 | チャンネル数(モノラルとかステレオとか) |
4 | サンプリングレート |
4 | データ速度(bytes/sec) |
2 | ブロックサイズ(bytes/sample * チャンネル数 |
2 | サンプルあたりのビット数(bit/sample, 8か16) |
2 | 拡張部分のサイズ |
n | 拡張部分 |
4 | data |
4 | 波形データのバイト数 |
n | 波形データ(ステレオならL, R, L, ……らしい) |
とりあえずサイズ(4 - 8)とってみる
Erlangでファイルを扱うにはfileモジュールを使う.
-module(wave). -export(analyse/1). analyse(File) -> if file:open(File, [binary, read, raw]) of {ok, S} -> {ok, Bin} = file:pread(S, 0, 8), file:close(S), Bin; % このままでは8バイトまるごとを返すので, ココを変える Error -> {File, Error} end.
で変数Binをビット構文で切り出す. コメント"このままでは〜"の部分を以下のように変える.
<<_Riff:4, Size:4>> = Bin, Size; % まだバイナリ
でもコレがアンマッチ! なんでだろー. とりあえず以下のようにしてある.
{_Riff, Size} = split_binary(Bin, 4), Size;
うん, 一応取り出せる. でもたくさん取り出すときはめんどうだよなぁ.
あと変数Sizeはまだバイナリだから数値に直さなくちゃいけない. でもどうやるんだろ? 左シフトして足して〜を繰り返すのかなぁ? binary_to_term関数じゃダメっぽい.