gpt4 book ai didi

audio - 如何检测 WAV 文件的 header 是 44 还是 46 字节?

转载 作者:行者123 更新时间:2023-12-02 01:38:39 25 4
gpt4 key购买 nike

我发现假设所有 PCM wav 音频文件在样本开始之前都具有 44 字节的 header 数据是危险的。尽管这很常见,但许多应用程序(例如 ffmpeg)将生成具有 46 字节 header 的 wav,在处理时忽略这一事实将导致文件损坏且无法读取。但是如何检测 header 的实际长度呢?

显然有一种方法可以做到这一点,但我搜索并发现对此的讨论很少。很多音频项目都假设 44(或相反,46),具体取决于作者自己的上下文。

最佳答案

您应该检查所有标题数据以了解实际大小。广播波形文件将包含更大的扩展子 block 。 Pro Tools 中的 WAV 和 AIFF 文件具有更多未记录的扩展 block 以及音频后的数据。如果您想确定示例数据的开始和结束位置,您需要实际查找数据 block (WAV 文件为“data”,AIFF 文件为“SSND”)。

作为回顾,所有 WAV 子 block 都符合以下格式:

Subchunk Descriptor (4 bytes)    Subchunk Size (4 byte integer, little endian)    Subchunk Data (size is Subchunk Size)

This is very easy to process. All you need to do is read the descriptor, if it's not the one you are looking for, read the data size and skip ahead to the next. A simple Java routine to do that would look like this:

//
// 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 文件:

Found 'RIFF' descriptor.Found 'bext' descriptor.Found 'fmt ' descriptor.Found 'minf' descriptor.Found 'elm1' descriptor.Found 'data' descriptor.Found 'regn' descriptor.Found 'ovwf' descriptor.Found 'umid' descriptor.End of file.

值得注意的是,这里“fmt”和“data”都合法地出现在其他 block 之间,因为 Microsoft's RIFF specification说子 block 可以以任何顺序出现。即使是我所知道的一些主要音频系统也会出现这个错误,并且没有考虑到这一点。

因此,如果您想查找某个 block ,请循环遍历文件检查每个描述符,直到找到您要查找的描述符。

关于audio - 如何检测 WAV 文件的 header 是 44 还是 46 字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19991405/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com