実際のサイズを確認するには、すべてのヘッダー データを確認する必要があります。Broadcast Wave Format ファイルには、さらに大きな拡張サブチャンクが含まれます。Pro Tools の WAV および AIFF ファイルには、ドキュメント化されていないさらに多くの拡張チャンクと、オーディオの後のデータがあります。サンプル データの開始位置と終了位置を確認したい場合は、データ チャンク (WAV ファイルの場合は「data」、AIFF の場合は「SSND」) を実際に探す必要があります。
復習として、すべての WAV サブチャンクは次の形式に準拠しています。
サブチャンク記述子 (4 バイト)
サブチャンク サイズ (4 バイト整数、リトル エンディアン)
Subchunk Data (サイズは Subchunk Size)
これは非常に簡単に処理できます。必要なのは記述子を読み取ることだけです。それが探しているものでない場合は、データ サイズを読み取って次へスキップします。これを行う単純な Java ルーチンは次のようになります。
//
// Quick note for people who don't know Java well:
// 'in.read(...)' returns -1 when the stream reaches
// the end of the file, so 'if (in.read(...) < 0)'
// is checking for the end of file.
//
public static void printWaveDescriptors(File file)
throws IOException {
try (FileInputStream in = new FileInputStream(file)) {
byte[] bytes = new byte[4];
// Read first 4 bytes.
// (Should be RIFF descriptor.)
if (in.read(bytes) < 0) {
return;
}
printDescriptor(bytes);
// First subchunk will always be at byte 12.
// (There is no other dependable constant.)
in.skip(8);
for (;;) {
// Read each chunk descriptor.
if (in.read(bytes) < 0) {
break;
}
printDescriptor(bytes);
// Read chunk length.
if (in.read(bytes) < 0) {
break;
}
// Skip the length of this chunk.
// Next bytes should be another descriptor or EOF.
int length = (
Byte.toUnsignedInt(bytes[0])
| Byte.toUnsignedInt(bytes[1]) << 8
| Byte.toUnsignedInt(bytes[2]) << 16
| Byte.toUnsignedInt(bytes[3]) << 24
);
in.skip(Integer.toUnsignedLong(length));
}
System.out.println("End of file.");
}
}
private static void printDescriptor(byte[] bytes)
throws IOException {
String desc = new String(bytes, "US-ASCII");
System.out.println("Found '" + desc + "' descriptor.");
}
たとえば、これは私が持っていたランダムな WAV ファイルです。
「RIFF」記述子が見つかりました。
「bext」記述子が見つかりました。
「fmt」記述子が見つかりました。
「minf」記述子が見つかりました。
「elm1」記述子が見つかりました。
「データ」記述子が見つかりました。
「regn」記述子が見つかりました。
「ovwf」記述子が見つかりました。
「umid」記述子が見つかりました。
ファイルの終わり。
特に、 Microsoft の RIFF 仕様では、サブチャンクは任意の順序で表示できると規定されているため、ここで「fmt」と「data」の両方が正当に他のチャンクの間に表示されます。私が知っているいくつかの主要なオーディオ システムでさえ、これを誤解しており、それを説明していません。
したがって、特定のチャンクを見つけたい場合は、探しているものが見つかるまで、各記述子をチェックするファイルをループします。