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関数じゃダメっぽい.