bin + cueをwav + cueに変換する
約1ヶ月半にMacBook Airを買って、現時点での究極のGUIを堪能している今日この頃ですが、一つだけ不満が・・・。
MacってCD-DAのイメージファイルをマウント出来る仕組みが無いのよね。
Windows時代に物理的耐用年数(20年)を過ぎたCD達をイメージ化してたんだけど、これが死んでしまうのは非常に痛い。
LINDBERGのEXTRA FLIGHTとかFlight Recorderとかが聞けなくなったらと思うと、もうウルウルっす・・・。
ウルウルしながら調べたところ、XLDってフリーソフトを使えばwav + cueファイルを分割してiTunesに登録してくれることを発見。やった。
ああ、でも愛用のAlcohol52%はcueシート付きのイメージファイルが作れるけど、イメージ本体はbinファイルなのでアウト。
号泣しながらさらに調べたところ、binとwavの差はRIFFコンテナへの格納有無だけらしいので簡単に変換出来そう。
よし、bin + cueファイルをwav + cueファイルに変換してみよう!
やることの説明
CD-DAのイメージファイルであるところのbinファイルは、CD-DAの内容を44.1kHz、16bit、2チャンネル(ステレオ)のPCM形式で保存したものです。サウンドレコーダでいう「CDの音質」と言う奴です。
(CDなんだから当たり前ですが。てか最近の子ってサウンドレコーダ知ってんの?)
一方のwavファイルは、RIFFコンテナに格納されたサウンドデータです。
RIFFはチャンク構造を持っており、名前付きの可変長データを複数格納出来るようになっています。
[RIFFヘッダ][チャンクヘッダ1(チャンク名)(データサイズ)][データ1][チャックヘッダ2(チャンク名)(データサイズ)][データ2]・・・
最近の概念だと、キーバリューストアだと思ってもらったら良いです。
さて、RIFFについて何となく理解したところで、wavファイルを形成するためのチャンクを見ていきます。
最低限必要なチャンクは"fmt"と"data"の2つ。
先に書いたサンプリングレートその他の情報はイメージファイルからは推測が不能なため、"fmt"チャンクにフォーマットの情報を格納する必要があります。
そして、肝心のデータは"data"チャンクに格納します。
受け売り文献:wav ファイルフォーマット
と、言う訳でbinファイルをwavファイルに変換するには、以下の情報を納めたファイルを作れば良いことになります。
- RIFFヘッダ(ファイルサイズ以外は固定データ)
- fmtチャンクヘッダ(固定データ)
- フォーマット情報(固定データ)
- dataチャンクヘッダ(データサイズ以外は固定データ)
- binファイルの内容(可変データ)
割と簡単。
実装してみた
複雑なことはしなくても良いので、シェルスクリプトで変換することにしました。
ついでにcueシート内のイメージファイル名の変換機能も付けました。
#! /bin/sh encode_int32() { X01000000=`printf %d 0x01000000` X00010000=`printf %d 0x00010000` X00000100=`printf %d 0x00000100` printf '\\x%x' `expr $1 % $X00000100` printf '\\x%x' `expr $1 / $X00000100 % $X00000100` printf '\\x%x' `expr $1 / $X00010000 % $X00000100` printf '\\x%x' `expr $1 / $X01000000 % $X00000100` } bin2wav() { WAVE_SIZE=`wc -c "$1" | cut -f2 -d " "` SIZE=`expr 48 + $WAVE_SIZE - 8` HEAD_1=RIFF HEAD_2=`encode_int32 $SIZE` HEAD_3='WAVEfmt \x10\x00\x00\x00\x01\x00\x02\x00\x44\xAC\x00\x00\x10\xB1\x02\x00\x04\x00\x10\x00data' HEAD_4=`encode_int32 $WAVE_SIZE` printf "$HEAD_1$HEAD_2$HEAD_3$HEAD_4" > "$2" cat "$1" >> "$2" } rewrite_cue() { mv "$1" "$1"_bin2wav echo FILE \"$2\" WAVE > tmp tail +2 "$1"_bin2wav >> tmp mv tmp "$1" } cd `dirname "$1"` CUE_EXT=`echo "$1" | sed -E 's/^.+(\.[^\.]+)$/\1/g'` BASENAME=`basename "$1" $CUE_EXT` if [ "$CUE_EXT" == ".cue" ];then BIN_EXT=".bin" WAV_EXT=".wav" elif [ "$CUE_EXT" == ".CUE" ];then BIN_EXT=".BIN" WAV_EXT=".WAV" else echo Invalid cue file > /dev/stderr exit 1 fi bin2wav "$BASENAME$BIN_EXT" "$BASENAME$WAV_EXT" rewrite_cue "$BASENAME$CUE_EXT" "$BASENAME$WAV_EXT"
第一引数にcueファイルのファイル名を指定してやれば、めでたくXLDで読めるwav + cueが完成します。