yamamoto2002
yamamoto2002
オーディオ関連のフリーソフトウェアを作っています。 Amazon.co.jpのyamamoto2002さんは別人です。 楽天オークションのyamamoto2002さんも別人です。 Twitt…

マイルーム

yamamoto2002のページ
yamamoto2002のページ
yamamoto2002のページです。
所有製品

レビュー/コメント

カレンダー

        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28      

最新のレス

日記
製品レビュー/コメント

製品レビュー/コメントへのレスはありません

お気に入り製品

お気に入り製品はありません

日記

4GB超のWAVファイル

このエントリーをはてなブックマークに追加
2018年02月02日

以前44.1kHz PCMファイルを2.8MHz 1bitのファイルに変換するプログラムを作ろうとしたとき、中間生成物として2.8MHz 32bit PCMのWAVファイルを出力しWaveSpectraでノイズシェイピングのスペクトルを観察しようとした。WaveSpectraは2.8MHz 32bitのWAVファイルのスペクトルを問題なく表示した。しかし4GBには3分しか入らず1曲入らないことに気づいた。その時調べた(のだったか?昔のことなので失念)WAVで4GBを超える方法について以下に書こうと思う。

■普通に作ったWAVファイル出力プログラムからごく自然に出てくる4GB超のWAVファイル

WAVファイルの構造については以下の資料が分かりやすい:
http://soundfile.sapp.org/doc/WaveFormat/

WAVファイルの先頭部分にはRIFFチャンクディスクリプタがあり、そこ(ファイルの先頭から4バイト目から7バイト目まで)にWAVファイルのサイズが記録されている。これが4バイト(=32ビット)と規定されているために、4GBを超えるサイズをここに正確に書き込むことが出来ない。

記事の最後に貼ったシンプルなWAV書き込みプログラムの★の行のftell(fp)関数の戻り値は8バイト長だが、uint32_t型のfileSizeに代入されるとき4バイトにスライスされる:1ビット目から32ビット目がfileSizeに入って33ビット目以降の情報は失われる。DATAサブチャンクのサイズも同様にスライスされる。

意図したというよりも偶然できたという感じはするが、このようにして作られたと思われる4GBを超えるWAVファイルは実在する。

このWAVファイルを読み出すことを考える。本当のファイルサイズはファイルシステムから得ることが出来る。RIFF.sizeから算出したファイルサイズは本当のファイルサイズと異なるが、違いは33ビット目よりも大きいビット部分だけで、1ビット目から32ビット目まではすべて一致する。このようなことが起きるのは偶然とは思われない。本当のファイルサイズをヒントにして33ビット目以降を補完することで、記録されたすべてのPCMデータを無傷で救い出すことが出来る。

しかし曖昧さは残るので、この記録方法は綺麗な解決法ではないと思う。

PlayPcmWinは、この種の4GB超のWAVファイルの再生にある程度対応していたと思う。動作テストデータの中にこの形式のWAVファイルがある。

■DATAサブチャンクを2回繰り返す

私はこの方法を掲示板の書き込みで見た。PCMデータを4GB以下に分割してDATAサブチャンクを並べて書き込んだら確かに各々のDATAサブチャンクのサイズは正確になり、最初に挙げた方法よりは幾分ましな感じはするが、RIFFチャンクのサイズ情報の記録が不正確になるのは避けられないと思う。

PlayPcmWinは、この種のWAVファイルの再生に対応していない。(2018年2月8日追記:プログラムを見たところ、複数個のDATAサブチャンク対応をしようとして途中まで作られていた。完全には機能しておらず未完成の状態で打ち捨てられている。)

■2つのWAVファイルを連結して1個のファイルにする

たとえばlinuxで以下のようにして作る:

$ cat firstHalf.wav secondHalf.wav > full.wav

2つのファイルを単純に連結して1個のファイルを作るというのは映像業界から来た発想と思う。MPEGファイルはこのようにして連結すると全く継ぎ目無くギャップレス連続再生される。

PlayPcmWinは、この種のWAVファイルの再生に対応していない。対応について検討したとき、前半と後半でPCM形式が変わっていた時の対策が面倒そうと思ったのでペンディングになっている。映像は門外漢だが番組はモノラルでCMに入るとステレオになるとか想像すると、大変そうだなと思った。

以上述べ来った方式はどれも過渡的な方式であり廃れ、次に説明するRF64 WAVEがデファクトスタンダードとなり、WAVの4GBの壁問題は実務的には解決し過去のものとなった。

■RF64 WAV

RF64はEBUが10年ほど前に出した規格。WAVを自然に拡張し4GB超のサイズを扱えるようにした。

シンプルかつエレガントにこの4GB問題を解決していると思う。

具体的には、

図1 RIFF WAVEとRF64 WAVE (クリックすると拡大)

①riff.descを"RF64"に変更、RIFF.sizeとDATAサブチャンクのサイズには0xffffffffを入れる。riff.typeは"WAVE"のままである。
②他のWAVのサブチャンクはそのまま書き込む。
③fmt サブチャンクよりも前に、新設されたRF64のサブチャンク(ds64)を書き込む。ds64サブチャンクには本当のファイルサイズと本当のデータサブチャンクのサイズが8バイト長で入っている。

必要な実装はこれだけでありすごく簡単だ。Adobe Audition, Audacity, Pro Tools, Nuendo, Cubase, Samplitude, Saracon, Soxはこの形式のWAVを出力できる。ファイルの拡張子は".wav"。RecPcmWinもRF64 WAVを出力する。192kHz 32bit 8chのPCM録音は11分で4GBに達する。マルチチャンネル録音や長時間の録音のためには4GB超対応は必須と思う。

RF64仕様書の9~10ページに興味深い例が挙がっている。録音装置や録音アプリは録音停止ボタンが押されるまでファイルサイズが確定しないので4GBを超えるかどうかはあらかじめわからない。このときはファイルの先頭にRF64のヘッダーが書き込める領域(上図1の場合80バイト)を用意しておいて、録音終了時WAVファイルのサイズが4GB未満になったときは、普通のRIFF WAVEのチャンクを書き込み、4GBを超えたらRF64 WAVEのチャンクを書き込むようにすると、RF64 awareではないレガシーなWAV読み出しプログラムとの動作互換性が高まる。

PlayPcmWinは、RF64 WAVファイルの再生に対応している。

■他の方法

他にもいろいろな方法が考案されている。しかしどれもRF64 WAVEよりマイナーである。

■シンプルなWAV書き込みプログラムの断片

struct RIFF {
uint32_t desc;
uint32_t size;
uint32_t type;
};

FILE * fp = fopen("output.wav", "wb");

/* 4GB以上のWAVファイルを最後まで書き込む(略) */

// ファイルサイズが確定したので取得。
uint32_t fileSize = ftell(fp); //< ★

// 書き込み位置をファイルの先頭に持っていく。
fseek(fp, 0, SEEK_SET);

// RIFFチャンクをファイルの先頭に書き込む。
RIFF riff;
riff.desc = 0x46464952; //< "RIFF"
riff.size = fileSize - 8; 
riff.type = 0x45564157; //< "WAVE"
fwrite(&riff, 12, 1, fp);

// WAVファイル出力完了。
fclose(fp);

■おまけ: fmt サブチャンクの種類

この話は4GBの話とは関係ないが、WAVの話なのでついでに書こうと思う。fmtサブチャンクには少なくとも5種類ある。WAV形式の長い歴史を感じる。

①サイズ14バイトの場合:サンプリング周波数とチャンネル数が入っている。量子化ビット数は書かれておらず暗黙的に16ビットに固定される。古いプログラムが出力することがある。

②サイズ16バイトの場合:量子化ビット数の情報が、追加された2バイトに入っている。16,20,24,32。ここに20が入っているときは有効量子化ビット数20ビットでコンテナサイズが24ビットという意味。②はもっともポピュラーな形式だと思う。上図1はこのタイプ。

③サイズ18バイトの場合:基本的には②と同じ。追加された2バイトは拡張情報のサイズを表すものだが、0が入っている。理不尽な感じがする形式だ。Adobe Audition CS5.5がRF64 WAVEを出力するとき③を付けてくるようだ。

④サイズ40バイトの場合:追加された22バイトにマルチチャンネル音声のチャンネル番号とスピーカー位置の対応表と「有効量子化ビット数」が入っている。しばしば見られる。

⑤サイズ54バイトの場合:先月発見した新種(?)。詳細不明。最初から16バイト目までは②と同じのようだ。

量子化ビット数20ビットのWAVファイルはWaveLabが出力できる。

■関連記事

WAVファイルの形式を変更するアプリ
http://community.phileweb.com/mypage/entry/2721/20151123/49456/

次回の日記→

←前回の日記

レスを書く

レスを書くにはログインする必要があります
ログインする