今すぐ修復
- ファイルをドロップ
- 修復はローカルで実行
- 結果をダウンロード
WAV は現存する中でも最も単純な音声コンテナーのひとつであり、だからこそヘッダー内のわずか 2 バイトや 4 バイトの誤りだけで、録音全体が死んでいるように見えてしまうことがあります。ファイルは RIFF というラッパーです。ASCII タグ RIFF、4 バイトのリトルエンディアンのサイズ、タグ WAVE、そして一連のチャンク(chunk)が続きます — それぞれが 4 バイトの名前、4 バイトのサイズ、そして本体からなります。重要なのは 2 つで、ひとつは fmt (末尾のスペースに注意)で、サンプルレート、チャンネル数、ビット深度を宣言します。もうひとつは data で、生の PCM サンプルを収めています。オフセット 4 の RIFF サイズ、または data チャンクのサイズが間違っていると — それらを書き直す前に落ちた録音機器、末尾を切り落とした転送、32 ビットのサイズ上限を超えたファイルなどによって — プレーヤーはその壊れた数値を信用し、すべてのサンプルがそこに残っているのにファイルを破損として報告します。上のエリアに .wav をドロップすると、ツールはブラウザー内で本物の fmt と data のマーカーを探し、実際に存在するものからサイズを計算し直し、手つかずの PCM の周りにきれいな正規のヘッダーを書き戻します — 何ひとつあなたの端末から出ていくことはありません。
PCM が無傷なのに WAV が破損と表示される理由
正規の WAV は 12 バイトのプロローグから始まります — ASCII タグ RIFF、ファイル全体のサイズから 8 を引いた値と等しいはずの 32 ビットのリトルエンディアン数値、そして ASCII タグ WAVE — そのあとにチャンクが続きます。各チャンクは 4 バイトの名前、4 バイトのリトルエンディアンのサイズ、そしてそのサイズぶんの本体からなります。fmt チャンクは 16 バイトの本体を持ちます。オフセット 0 のフォーマットタグ(1 = PCM、3 = IEEE 浮動小数点、0xFFFE = WAVE_FORMAT_EXTENSIBLE、0x11 = IMA ADPCM)、続いてチャンネル数(オフセット 2)、サンプルレート(オフセット 4)、バイトレート(オフセット 8)、ブロックアライン(オフセット 12)、ビット深度(オフセット 14)です。data チャンクは 8 バイトのヘッダーに、インターリーブされたサンプルが続くだけのものです。何時間もの音声へ至る「地図」全体が、このわずか数十バイトなのです。
この脆さこそが問題のすべてです。ディスクへ書き込み続ける録音機器は、あなたが停止を押すまで最終的な長さを知りません。そのため RIFF サイズ(オフセット 4)と data サイズにプレースホルダーを書き込み — 多くの場合 0 か 0xFFFFFFFF です — ファイルを閉じる最後の段階で本物の値に書き直します。その最後の書き直しの前にアプリを強制終了したり、電源を抜いたり、カードを引き抜いたり、OS をクラッシュさせたりすると、PCM は完全に書き込まれているのに、サイズはファイルが空だと言い続けます。プレーヤーはヘッダーを信じます。Windows Media Player は 0xC00D36C4 を返し、Audacity の libsndfile は File contains data in an unknown format(「不明な形式のデータが含まれています」)と報告するか、「WAV でも AIFF でもないファイル」として拒否します。ffmpeg は Invalid data found when processing input(「入力の処理中に無効なデータが見つかりました」)と表示し、ときには RIFF size ... bigger than resulting file size(「RIFF サイズが実ファイルサイズより大きい」)と警告したあとに出します。
ほかの日常的な原因も、行き着く先は同じです。途中で止まったコピーや同期は data の本体を切り詰め、宣言されたサイズが実際に存在するバイト数を上回ってしまいます。およそ 4 GiB を超えた録音は 32 ビットの RIFF/data サイズフィールドをあふれさせるため、カウンターが一巡し、末尾が読めなくなったように見えます。fmt より前に書き込まれた迷子のメタデータチャンクや、バイト順序のずれは、素朴なパーサーを本物のチャンクから外れさせてしまうことがあります。これらのどの場合でも、サンプルは無傷です — 嘘をついているのは帳簿のほうなのです。
ブラウザーがサンプルに触れずに RIFF/fmt/data を再構築する仕組み
この修復はヘッダーの構造的な再構築であり、あなたのタブの中で純粋な TypeScript として動きます。ファイル全体を読み込み(有効な WAV には少なくとも 44 バイトの最小ヘッダーが必要です)、オフセット 4 の RIFF サイズを信用する代わりに、ファイルのどこかにあるリテラルな ASCII バイト列 fmt を走査します。これが肝心な一手です。ゼロになった、プレースホルダーの、あるいはあふれたマスターサイズも、これを止められません。道を見つけるためにそのフィールドを読むことが決してないからです。fmt の本体からは、本当に必要な 4 つの値だけを取り出します — フォーマットタグ、チャンネル数(オフセット 2)、サンプルレート(オフセット 4)、ビット深度(オフセット 14)です。チャンネル数、サンプルレート、ビット深度のいずれかがゼロなら、ノイズを吐き出すのではなく bad-fmt-params という結果で正直に停止します。
次に、2 つの派生フィールドを自分で計算し直します — ブロックアラインはチャンネル数 ×(ビット深度 ÷ 8)、バイトレートはサンプルレート × ブロックアラインです — したがって元のヘッダーにあった間違ったバイトレートやブロックアラインは、そのまま捨てられ、正しい計算に置き換えられます。続いて data タグを前方へ走査します。宣言された data サイズが実際に存在するバイト数より大きい場合(切り詰めのケース)、残っているものをすべて保持し、結果を truncated-data と記録します。data ヘッダーがまったくない場合は、16 バイトの fmt 本体の直後のバイトを PCM として扱い、no-data-header と記録します。そのあと PCM は整数個のサンプルフレームに収まるよう切り詰められ、最後まで書き込まれなかったフレームがプチッというノイズを出さないようにします。
最後に、新しく正規の 44 バイトのヘッダーを書き込みます。RIFF には 36 + PCM の長さという修正済みサイズを、続いて WAVE、回復したフォーマット/チャンネル数/サンプルレート/ビット深度と、計算し直したバイトレートおよびブロックアラインを収めたきれいな 16 バイトの fmt チャンク、そして本当の PCM の長さを収めた data、その後の 44 バイト目以降にあなたのサンプルをそのままコピーします。リサンプリングも再エンコードもありません — 音声のバイトはあなたが録音したものとまったく同じなので、この修復は無劣化(ロスレス)です。ツールは回復したサンプルレート、チャンネル数、ビット深度、PCM のバイト数と、損傷の分類として header(きれいな成功)または truncated-data/no-data-header(部分的な結果)を報告します。この一連の処理はネットワークにいっさい触れません — ネットワークタブを開けば、ファイルが 1 バイトも送信されていないことを確認できます。
再構築できないとき — そして何が失われるか
この修復は生き残ったものに手を届かせるだけで、もはや読めなくなったフォーマットをでっち上げることはできません。fmt チャンクが存在することが前提です。fmt が欠けていたり上書きされていたりすると、ツールは推測する代わりに no-fmt という結果で停止します。サンプルレート、チャンネル数、ビット深度は生の PCM から推定できないからです — 間違った推測は音声を誤った速度で再生したり、インターリーブされたゴミとして鳴らしたりしてしまいます。moov アトムのない動画とは違い、ここでは正常な参照ファイルを使いません。したがってフォーマットヘッダーが消えていれば、フォーマットは消えたのです。44 バイト未満のファイルは too-small を返し、整数フレームに切り詰めた結果として何も残らなければ no-pcm を返します。
正規の 44 バイトヘッダーを出力するため、付随的なチャンクは破棄されます。放送用メタデータ(bext/BWF のタイムコードと制作情報)、キューポイント(cue )、プレイリストとラベルのチャンク、LIST/INFO タグ(アーティスト、コメント)、fact チャンク、そして WAVE_FORMAT_EXTENSIBLE 拡張(cbSize、有効ビット数、チャンネルマスク、サブフォーマット GUID)です。音声は戻ってきますが、これらのメタデータは戻りません。この再構築はまた、サンプルフレームのサイズが一定であることを前提とします。そのため、ブロックアラインが単純なチャンネル数 × サンプルあたりバイト数ではない圧縮 WAV — IMA/MS ADPCM、GSM 6.10 — は、計算し直したブロックアラインによって誤って記述され、デコードできないことがあります。ツールが対象とするのは、その計算が厳密に成り立つ PCM と IEEE 浮動小数点です。
正直に述べておくべき限界がもう 2 つあります。出力は標準的な 32 ビットの RIFF なので、およそ 4 GiB を超える PCM はサイズフィールドで表現できません — その規模には RF64/BW64 か、ソニーの Wave64(.w64) という別のコンテナーが必要です。そして、故障しかけたドライブやカードが物理的にゼロや無音で上書きしてしまったサンプルは、そもそもディスク上に残っておらず回復できません。まずストレージのレベルで生のバイトを取り戻し、それからヘッダーを再構築してください。確実に取り戻せるのは、正しく記述された無傷の PCM が、プレーヤーが実際に開けるファイルに収まった状態です。
修復できるものとできないもの
修復できる
- 録音機器が最終的な RIFF/data サイズを書き直す前にクラッシュし(プレースホルダーの 0 または 0xFFFFFFFF)、長さ 0 または破損と表示される WAV
- 宣言されたサイズが実在するバイト数を上回る data チャンク(切り詰められたコピー/同期)— ディスクにたどり着いたサンプルをすべて保持します
- fmt チャンク内の間違った、あるいは意味をなさないバイトレート/ブロックアライン — どちらもチャンネル数、サンプルレート、ビット深度から計算し直します
- 'data' チャンクヘッダーの欠落 — fmt 本体の後ろのバイトを PCM として扱い、包み直します
- オフセット 4 のゴミのような RIFF マスターサイズ — ツールは代わりに 'fmt ' と 'data' のマーカーを走査するため、完全に無視されます
- 標準的な整数 PCM および IEEE 浮動小数点の WAV(モノラルまたはマルチチャンネル)— サンプルをバイト単位でコピーし、無劣化で再構築します
修復できない
- 'fmt ' チャンクがないファイル — サンプルレート、チャンネル数、ビット深度は生の PCM から推測できないため、停止します('no-fmt' として報告)
- ブロックアラインがチャンネル数 × サンプルあたりバイト数ではない圧縮 WAV(IMA/MS ADPCM、GSM)— 計算し直したヘッダーが誤って記述してしまいます
- 放送用/BWF(bext)、キューポイント(cue)、LIST/INFO タグ、EXTENSIBLE の fmt 拡張 — 正規の 44 バイトヘッダーを書き込む際に破棄されます
- 約 4 GiB を超える PCM — 32 ビットの RIFF サイズには収まりません。RF64/BW64 または Wave64(.w64)が必要です
- 故障しかけたドライブやカードがゼロ/無音で上書きしたサンプル — まずストレージのレベルで生のバイトを回復し、それから再構築してください
- 44 バイト未満のファイル、または整数個のサンプルフレームが 1 つも残っていないファイル('too-small' または 'no-pcm' として報告)
修復が失敗した場合、その理由(データの欠落か構造の破損か)をお伝えします。失敗した修復に料金が請求されることはありません。