non-standard fmt Header 的 WAVE 文件

WAVE File with non-standard fmt Header

使用 http://soundfile.sapp.org/doc/WaveFormat/ and http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html 等资源,我正在尝试创建一个程序,您可以在其中提取嵌入在可执行文件中的 wave 文件,并将其字节内容复制到文件可以读取的文件中将其从原始字节数据转换为 WAV 文件类型。

在代码中,我使用以下结构:

public class WAVEFile
    {
        public Header header;
        public FMT fmt;
        public Data data;

        public WAVEFile()
        {
            header = new Header();
            fmt = new FMT();
            data = new Data();
        }

        public class Header
        {
            public byte[] chunkID;
            public int chunkSize;
            public byte[] format;
        }

        public class FMT
        {
            public byte[] chunkID;
            public byte[] chunkSize;
            public byte[] audioFormat;
            public byte[] noOfChannels;
            public byte[] sampleRate;
            public byte[] byteRate;
            public byte[] blockAlign;
            public byte[] bitsPerSample;
        }

        public class Data
        {
            public byte[] chunkID;
            public byte[] chunkSize;
            public byte[] audioData;
        }
    }

在十六进制中,主文件header和fmt header如下所示:

52 49 46 46 84 80 00 00  57 41 56 45 66 6D 74 20
20 00 00 00 65 01 10 00  D6 10 00 00 01 00 00 02
E1 55 00 00 44 AC 00 00  00 00 00 00 00 00 00 00
00 02 01 02

但是,根据 soundfile.sapp.org 网站来源,header 似乎是 non-standard,至少据我所知是这样。 Subchunk1Size 是 32 字节(十六进制为 20 00 00 00),而更常见的是 16 字节。随后,构成 header 的数据顺序异常,似乎包含额外数据或垃圾数据(在本例中,如果我继续使用 16 字节 header 的标准结构,我最终会得到 00 00 作为每个样本的位)。随后,我留下了静态声音或 Windows 媒体播放器无法播放文件。

我对此进行了进一步调查,得出的结论是这只能表示以下两种情况之一(当然,我可能是错的):

1) 此波形文件使用某种 "custom" header 或不同于 "standard PCM" 波形文件的格式,至少两个来源在其示例中引用的内容是这样。

2) 这可能使用 WAV 文件作为包装器,这意味着实际上这可能是完全不同的文件类型。

进一步深入研究十六进制以找到更多线索后,每个波形文件的末尾似乎都有一个以 "seek" 开头的部分。这可能是相关的,但我不确定。这是我引用的 "seek" 数据:

73 65 65 6B 48 00 00 00  01 00 00 00 10 00 00 00
00 00 00 00 00 12 00 00  00 20 00 00 00 30 00 00
00 42 00 00 00 52 00 00  00 60 00 00 00 70 00 00
00 7E 00 00 00 8E 00 00  00 9C 00 00 00 AC 00 00
00 BE 00 00 00 D2 00 00  00 E8 00 00 00 00 01 00

在此 "seek" 代码或指令之后,另一个 RIFF 文件 header 开始。

基本上,我 ideas/options/resources 无法进一步破译 fmt header 发生了什么,以及为什么它似乎不适合所示的 subchunk 一种格式并且是 32 字节long,而不是 16,这会导致 header 中的其余数据无效和混乱。关于我如何正确阅读 header 以创建有效的 WAV 文件,是否有人有任何建议或潜在的阅读资源以获取更多信息?

经进一步调查,65 01 格式标签(或 0x0165)对应于 XMA 音频编解码器,最常用于 Xbox 360,我想,它的游戏。它似乎基于或至少非常类似于 WMA Pro。这是通过以下来源发现的:http://forum.xentax.com/viewtopic.php?f=17&t=14897

经过测试,FFMPEG 的 libavcodec 能够将 .xma 类型的任何原始十六进制数据转换为 .wav。通过将类似于上面的原始十六进制数据放入一个文件(使用任何十六进制编辑器,例如 HxD)并将其扩展名重命名为 .xma,FFMPEG 可以使用以下命令将其转换为 WAV:

ffmpeg -i myaudio.xma myaudio.wav

如原问题中所述,搜索命令的目的仍然不明确,但从十六进制代码中删除该部分(因此搜索开始和下一个音频头开始之间的任何数据)WAV 文件可以正确播放在 Windows 媒体播放器中。