开发者

Parse WAV file header

开发者 https://www.devze.com 2023-01-25 08:18 出处:网络
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

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', bufHea开发者_高级运维der[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/


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.


They're little-endian.

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号