解析WAV文件头

发布于 2024-10-02 23:58:21 字数 2311 浏览 3 评论 0原文

我正在编写一个程序来解析 WAV 文件头并将信息打印到屏幕上。在编写程序之前,我正在做一些研究

hexdump -n 48 sound_file_8000hz.wav

00000000  52 49 46 46 bc af 01 00  57 41 56 45 66 6d 74 20    |RIFF....WAVEfmt |
00000010  10 00 00 00 01 00 01 00  >40 1f 00 00< 40 1f 00 00  |........@...@...|
00000020  01 00 08 00 64 61 74 61  98 af 01 00 81 80 81 80    |....data........|

hexdump -n 48 sound_file_44100hz.wav

00000000  52 49 46 46 c4 ea 1a 00  57 41 56 45 66 6d 74 20    |RIFF....WAVEfmt |
00000010  10 00 00 00 01 00 02 00  >44 ac 00 00< 10 b1 02 00  |........D.......|
00000020  04 00 10 00 64 61 74 61  a0 ea 1a 00 00 00 00 00    |....data........|

> 之间的部分且<两个文件中都是采样率。

“40 1f 00 00”如何转换为 8000Hz,“44 ac 00 00”如何转换为 44100Hz?可以直接从转储中读取通道数和音频格式等信息。我发现了一个Python 名为 WavHeader 的脚本可以正确解析两个文件中的采样率。这是脚本的核心:

 bufHeader = fileIn.read(38)
    # Verify that the correct identifiers are present
    if (bufHeader[0:4] != "RIFF") or \
       (bufHeader[12:16] != "fmt "): 
         logging.debug("Input file not a standard WAV file")
         return
    # endif
    stHeaderFields = {'ChunkSize' : 0, 'Format' : '',
        'Subchunk1Size' : 0, 'AudioFormat' : 0,
        'NumChannels' : 0, 'SampleRate' : 0,
        'ByteRate' : 0, 'BlockAlign' : 0,
        'BitsPerSample' : 0, 'Filename': ''}
    # Parse fields
    stHeaderFields['ChunkSize'] = struct.unpack('<L', bufHeader[4:8])[0]
    stHeaderFields['Format'] = bufHeader[8:12]
    stHeaderFields['Subchunk1Size'] = struct.unpack('<L', bufHeader[16:20])[0]
    stHeaderFields['AudioFormat'] = struct.unpack('<H', bufHeader[20:22])[0]
    stHeaderFields['NumChannels'] = struct.unpack('<H', bufHeader[22:24])[0]
    stHeaderFields['SampleRate'] = struct.unpack('<L', bufHeader[24:28])[0]
    stHeaderFields['ByteRate'] = struct.unpack('<L', bufHeader[28:32])[0]
    stHeaderFields['BlockAlign'] = struct.unpack('<H', bufHeader[32:34])[0]
    stHeaderFields['BitsPerSample'] = struct.unpack('<H', bufHeader[34:36])[0]

当我无法使用 hexdump 时,我不明白如何提取正确的采样率?

我正在使用此页面中有关 WAV 文件格式的信息:

https://ccrma.stanford .edu/courses/422/projects/WaveFormat/

I am writing a program to parse a WAV file header and print the information to the screen. Before writing the program i am doing some research

hexdump -n 48 sound_file_8000hz.wav

00000000  52 49 46 46 bc af 01 00  57 41 56 45 66 6d 74 20    |RIFF....WAVEfmt |
00000010  10 00 00 00 01 00 01 00  >40 1f 00 00< 40 1f 00 00  |........@...@...|
00000020  01 00 08 00 64 61 74 61  98 af 01 00 81 80 81 80    |....data........|

hexdump -n 48 sound_file_44100hz.wav

00000000  52 49 46 46 c4 ea 1a 00  57 41 56 45 66 6d 74 20    |RIFF....WAVEfmt |
00000010  10 00 00 00 01 00 02 00  >44 ac 00 00< 10 b1 02 00  |........D.......|
00000020  04 00 10 00 64 61 74 61  a0 ea 1a 00 00 00 00 00    |....data........|

The part between > and < in both files are the sample rate.

How does "40 1f 00 00" translate to 8000Hz and "44 ac 00 00" to 44100Hz? Information like number of channels and audio format can be read directly from the dump. I found a Python
script called WavHeader that parses the sample rate correctly in both files. This is the core of the script:

 bufHeader = fileIn.read(38)
    # Verify that the correct identifiers are present
    if (bufHeader[0:4] != "RIFF") or \
       (bufHeader[12:16] != "fmt "): 
         logging.debug("Input file not a standard WAV file")
         return
    # endif
    stHeaderFields = {'ChunkSize' : 0, 'Format' : '',
        'Subchunk1Size' : 0, 'AudioFormat' : 0,
        'NumChannels' : 0, 'SampleRate' : 0,
        'ByteRate' : 0, 'BlockAlign' : 0,
        'BitsPerSample' : 0, 'Filename': ''}
    # Parse fields
    stHeaderFields['ChunkSize'] = struct.unpack('<L', bufHeader[4:8])[0]
    stHeaderFields['Format'] = bufHeader[8:12]
    stHeaderFields['Subchunk1Size'] = struct.unpack('<L', bufHeader[16:20])[0]
    stHeaderFields['AudioFormat'] = struct.unpack('<H', bufHeader[20:22])[0]
    stHeaderFields['NumChannels'] = struct.unpack('<H', bufHeader[22:24])[0]
    stHeaderFields['SampleRate'] = struct.unpack('<L', bufHeader[24:28])[0]
    stHeaderFields['ByteRate'] = struct.unpack('<L', bufHeader[28:32])[0]
    stHeaderFields['BlockAlign'] = struct.unpack('<H', bufHeader[32:34])[0]
    stHeaderFields['BitsPerSample'] = struct.unpack('<H', bufHeader[34:36])[0]

I do not understand how this can extract the corret sample rates, when i cannot using hexdump?

I am using information about the WAV file format from this page:

https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花海 2024-10-09 23:58:22

它们是little-endian

>>> 0x00001f40
8000
>>> 0x0000ac44
44100

They're little-endian.

>>> 0x00001f40
8000
>>> 0x0000ac44
44100
裸钻 2024-10-09 23:58:21

“40 1F 00 00”字节相当于一个十六进制值为 00001F40 的整数(请记住,该整数以小端格式存储在 WAVE 文件中)。十六进制值 00001F40 相当于十进制值 8000。

同样,“44 AC 00 00”字节相当于十六进制值为 0000AC44 的整数。十六进制值 0000AC44 相当于十进制值 44100。

The "40 1F 00 00" bytes equate to an integer whose hexadecimal value is 00001F40 (remember that the integers are stored in a WAVE file in the little endian format). A value of 00001F40 in hexadecimal equates to a decimal value of 8000.

Similarly, the "44 AC 00 00" bytes equate to an integer whose hexadecimal value is 0000AC44. A value of 0000AC44 in hexadecimal equates to a decimal value of 44100.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文