rox

Cue シートと、アルバムらしく振る舞うリップ

分割が当たり前になる前に CD をリップしていたなら、ライブラリの一部はディスクごとに FLAC 1 つとテキストファイル 1 つの組になっているはずです。多くのプレイヤーはシートを無視するか、そこに書かれたものを二級市民として扱います。rox がそれをどう扱うかを書きます。

CUE リップとは実際に何か

ディスク 1 枚分を収めた音声ファイル 1 つと、各トラックの開始位置を並べた .cue シート。曲間の隙間もディスクの一部であり、分割するとそれが失われるので、CD を正確に保存する方法はこちらです。同時に、音楽ライブラリが土台にしている前提、つまり 1 ファイル = 1 トラックという前提を壊す形式でもあります。

プレイヤーの答えは 3 通りです。シートを無視して 70 分の 1 曲を出す。シートのトラックは出すが本体のライブラリとは別扱いにして、検索、並べ替え、プレイリストの挙動を変える。あるいは、その断絶を本物として受け止め、一度で吸収する。

断片ではなく、本物の行

rox はシートの各区間を、ファイルとトラック番号で識別されるライブラリの普通の行として取り込みます。下流のすべてがそれをトラックとして読むのは、下流にとって実際にトラックだからです。プレイリストは記録し、再生履歴が結び付き、検索が見つけ、並べ替えの列が並べ、そのどれも 11 行が同じ FLAC を指していることを知りません。

多くの実装が選ぶ代替案は album.flac#3 のような合成パスで、データベースはきれいに保てますが、あとでそのパスを開くすべてのコードに問題を押し付けます。そこで切り落とし忘れると、何もないところからタグのバイト列を読む静かなバグになります。cue シートを持たないライブラリはこの一切に何も払いません。区間は別テーブルに置かれ、ホットパスでは誰も読まないので。

区間をファイルのように鳴らす

エンジンは区間を、そのトラックにとっての世界のすべてとして扱います。開始位置への正確なシーク、両端のサンプル単位の切り詰め、そして本物のファイル終端と同じ経路を通る終端。ギャップレス、クロスフェード、この曲で停止、リピートは、区間の存在を知らないまま全部動きます。

頭の切り詰めが効いてくる細部です。正確なシークは正確なサンプルではなくパケット境界に着地するので、着地点と区間の開始のあいだのフレームを捨てなければ、どのトラックも 1 つ前の尻尾から始まります。それが、誰も仕上げなかった cue 実装の音です。

1 つのリップの連続したトラックは同じアルバムグループを共有します。それが、ディスク自身のギャップレスなつなぎ目をクロスフェードが跨がないようにしています。リップは、切り出された元の盤のように鳴ります。

スキャンと、気が変わったとき

シートは自分のイメージを主張します。cue がファイルを挙げているあいだ、そのファイルは自分の行を持たないので、11 曲に加えて 70 分の重複が並ぶことはありません。新しさは 2 つのうち後に更新されたほうを見るので、シートでも音声でも編集すれば次のスキャンでリップが切り直されます。シートを消せば、イメージはただの 1 行に戻ります。

メタデータはシートを優先し、無ければイメージ自身のタグに戻ります。UTF-8 の規律が当たり前になる前に書かれたシートには cp1252 のフォールバックが効きます。古いリップこそ、この機能が想定している対象なので。

ディスク全体に判を押さないレーティング

rox は普段レーティングをファイル自体に書きます。ファイルがトラックであるうちは、それが正しい判断です。CUE リップではそうではありません。イメージは 11 曲で共有しているので、トラックごとの書き込みは全曲に同じ星を押してしまいます。

書き込み側はこれらの行についてファイル側を拒み、データベースが値を持ちます。タグの編集も同じです。リップでもトラックごとのレーティングが手に入り、イメージはバイト単位で同じまま出てきます。

あとになって初めて気づく部分

  • m3u のエクスポートは区間を path#N として書き、インポートは完全一致のパスを優先するので、他のソフトを往復してもイメージに潰れません。
  • スクロブルと再生中表示はこの組で重複を排除するので、ディスクの 11 曲は 1 曲のとても長いものではなく 11 曲としてスクロブルされます。
  • 再生履歴は再スキャンのあとも区間ごとに結び直されるので、すべての区間が同じタグを持っていても、ディスクはトラックごとの再生履歴を保ちます。
  • 引き継がれるのは ReplayGain のアルバム側の値だけです。ディスク丸ごとのイメージに対して書かれたトラック値はディスクを表しているので、信用せず無視します。

ここでの物差しは、リップが鳴るかどうかではありません。1 か月後に、イメージから来たという理由でライブラリの何かがまだ違う振る舞いをするかどうかです。

分けずに置いてきた棚に向ける

スキャナーは最初のパスで、他のすべてと一緒にシートを拾います。ライブラリの規模で何が壊れるか も参考に。