【问题标题】:WAVE File with non-standard fmt Header带有非标准 fmt 标头的 WAVE 文件
【发布时间】:2018-07-07 00:37:42
【问题描述】:

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

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

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 网站来源,标题似乎是非标准的,至少据我所知。 Subchunk1Size 为 32 个字节(十六进制为 20 00 00 00),而更常见的是 16 个字节。随后,构成标头的数据处于异常顺序,并且似乎包含附加数据或垃圾数据(在这种情况下,如果我继续16 字节标头的标准结构,我最终会以 00 00 作为每个样本的位)。随后,我留下了静态声音或 Windows Media Player 无法播放该文件。

我对此进行了进一步研究,得出的结论是,这只能表示两件事之一(当然,我可能是错的):

1) 此波形文件使用某种与“标准 PCM”波形文件不同的“自定义”标头或格式,至少在两个来源的示例中都引用了这些文件。

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

在进一步深入研究十六进制以找到任何进一步的线索后,每个波形文件的末尾似乎都有一个以“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

在这个“寻找”代码或指令之后,另一个 RIFF 文件头开始。

基本上,我完全没有想法/选项/资源来进一步破译 fmt 标头发生了什么以及为什么它似乎不适合所示的子块一种格式并且长度为 32 个字节,而不是 16 个因此使标头中的其余数据无效和混乱。有人有任何建议或潜在的阅读资源,以获取有关如何正确阅读标题以创建有效 WAV 文件的更多信息吗?

【问题讨论】:

  • 您发布的代码不是 C++。看起来可能是 C#?
  • 如果是标准 PCM,65 01 将是 00 01。我找不到wFormatTag这个值的任何定义@
  • @1201ProgramAlarm 是的,它是 C#。我的错,我已经编辑了标签。
  • @jaket 这会暗示某种“自定义”格式、可能的加密或某种形式的损坏吗?我真的不确定自己 - 这些只是对可能发生的事情的想法。

标签: c# audio header hex wave


【解决方案1】:

在进一步调查中,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

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

【讨论】:

    猜你喜欢
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 2018-10-18
    • 1970-01-01
    相关资源
    最近更新 更多