空音開発Kuon R&D
初めての方は DDPファイル完全ガイド をご覧ください。本ページは技術深堀り向けです。

DDPチェッカーの仕組み

CD マスタリング用バイナリフォーマット DDP を、ブラウザで完全に解析・再生する技術

DDP とは何か

DDP(Disc Description Protocol)は Doug Carson & Associates が開発した CD マスタリング用バイナリフォーマット。
レコード会社や CD 製造所が使用する業界標準。

CD の全情報を含む:
• トラック数・曲順・タイムコード
• 各トラック間の無音部分(gap)の長さ
• ISRC コード(国際標準録音コード)
• UPC / EAN バーコード
• 最大 99 トラックまでの完全な PQ シート情報
• 44.1kHz, 16-bit ステレオの PCM オーディオデータ(赤本仕様)

バイナリ構造の解析

DDP ファイルは複数の小さなファイルで構成されます。それぞれが異なる役割を持っています。

DDPID ファイル:識別情報
固定 128 バイト。CD マスターの識別子を格納。

DDPMS ファイル:マップストリーム
128 バイト単位のパケット。各データストリームの型・ポインタ・長さ・CD モード・トラック情報を含む。

PQ ディスクリプタ:トラック・インデックス情報
64 バイト単位の PQ パケット。各トラックのタイムコード、ISRC、UPC/EAN を含む。

オーディオデータ:PCM 音声
赤本仕様:44.1kHz, 16-bit, ステレオ。セクタサイズ 2,352 バイト(CD-DA 標準)。

DDPID 構造(128 バイト)

01020304050607080Version0-7UPC/EAN8-20Master ID38-85

DDPMS パケット(128 バイト)

010Type0-1Pointer2-7Length8-11CD Mode12-12Track13-13

トラック構築アルゴリズム

DDP の複数の PQ パケットを解析してひとつのトラックを構築するプロセス:

1. Index Points の識別
• Index 00:プリギャップ開始(音声なし)
• Index 01:音声開始(実際の演奏データ)
• Index 02~99:追加インデックスポイント(オプション)

2. ギャップ計算
前トラックの最後の Index 01 から、次トラックの Index 00 までの距離をセクタ数で計算。
標準では 2 秒(150 セクタ)ですが、特殊なマスタリングでは異なる場合があります。

3. バイトオフセット計算
セクタ数 × 2,352 バイト/セクタ = ファイル上のバイト位置

4. タイムコード変換
BCD エンコード(Binary-Coded Decimal)から MM:SS:FF(分:秒:フレーム)へ変換。
1 秒 = 75 フレーム(CD-DA 規格)
TypeScript
// Timecode conversion (BCD → MM:SS:FF)
function parseBCDTimecode(minutes: number, seconds: number, frames: number): string {
  const m = ((minutes >> 4) * 10) + (minutes & 0x0F);
  const s = ((seconds >> 4) * 10) + (seconds & 0x0F);
  const f = ((frames >> 4) * 10) + (frames & 0x0F);
  return `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}:${f.toString().padStart(2, '0')}`;
}

// Byte offset calculation
const sectorSize = 2352; // bytes per CD sector
const byteOffset = sectorNumber * sectorSize;

オーディオデータの抽出と再生

各トラックのオーディオデータは ArrayBuffer として メモリに読み込まれます。

赤本仕様の遵守
• サンプリング周波数:44.1 kHz(CD 標準)
• ビット深度:16-bit(符号付き)
• チャンネル:ステレオ(L/R)
• バイトオーダー:リトルエンディアン

トラック分離
DDP ファイルの全 PCM データから、各トラックのバイト範囲を `ArrayBuffer.slice()` で抽出。
先頭トラック:バイト 0 からトラック長まで
以降のトラック:前トラックの終了位置 + ギャップサイズ からスタート。

Web Audio API との連携
抽出した ArrayBuffer を `AudioContext.decodeAudioData()` で WAV/PCM に復号化。
AudioBuffer が生成され、ブラウザの `<audio>` タグで再生可能な状態に。

リアルタイムアナライザー
Web Audio API の AnalyserNode を使用し、再生中のリアルタイム波形・スペクトラム可視化が可能。
TypeScript
// Extract track audio from DDP file
function extractTrackAudio(
  buffer: ArrayBuffer,
  startSector: number,
  endSector: number
): ArrayBuffer {
  const sectorSize = 2352;
  const startByte = startSector * sectorSize;
  const endByte = endSector * sectorSize;
  return buffer.slice(startByte, endByte);
}

// Decode to playable format
async function decodeAudio(
  context: AudioContext,
  arrayBuffer: ArrayBuffer
): Promise<AudioBuffer> {
  return await context.decodeAudioData(arrayBuffer);
}

ギャップリッスン機能

KUON DDP チェッカーの最大の特徴:前のトラックの最後と次のトラックの最初を繋いで、曲間を自然に聞く機能。

実装方法
• 前トラック:最後の 15 秒を抽出
• 曲間:完全な無音ギャップ(マスタリング意図を保持)
• 次トラック:最初の 5 秒を抽出
• 連続再生:3 つのセグメントをシームレスに OfflineAudioContext で処理。

なぜ重要か
CD マスタリング時、エンジニアはギャップの長さを非常に慎重に設定します。
標準の 2 秒ではなく、楽曲の性質やコンセプトに応じて 1.5 秒だったり 3 秒だったりします。

従来のプレーヤーではギャップを聞く手段がありません。
KUON のギャップリッスンなら、マスタリングエンジニアが意図した「音と音の繋がり」を検証できます。
トラック1 最後15秒
■■■
ギャップ 自然な 無音
──
トラック2 最初5秒
■■■

プライバシーとセキュリティ

DDP Checker のすべての処理は、ユーザーのブラウザ内で完結します。

サーバーへの送信:0
DDP ファイルはサーバーにアップロードされません。
ファイル API と ArrayBuffer を使用して、ローカルメモリのみで処理。

通信履歴:なし
ネットワークトラフィックが生じるのは Web ページの読み込み時のみ。
DDP 解析・再生時は通信なし。

データ永続性:なし
ファイルの内容は localStorage や IndexedDB に保存されません。
ブラウザを閉じると全て削除。

メタデータのみ保存(オプション)
ユーザーが明示的に「メタデータを保存」を選択した場合のみ、
トラック名・タイムコードなどの基本情報が localStorage に保存されます。
オーディオデータやマスター ID は保存されません。

DDP Checker を試す → DDP チェッカーを開く
別の記事を読む → DSD コンバーターの仕組み