File format for 24 bit 96 kHz stereo WAV file


WAV file as recorded by Creative MediaSource 3.30.21 and Creative Soundblaster Audigy 2ZS notebook card (Device SB Audigy 2[EECO])
WAV file size: 518480 bytes

----- Hex dump (partial) -------

0000   52 49 46 46 48 E9 07 00 57 41 56 45 66 6D 74 20   RIFFH...WAVEfmt 
0010   28 00 00 00 FE FF 02 00 00 77 01 00 00 CA 08 00   (........w......
0020   06 00 18 00 16 00 18 00 03 00 00 00 01 00 00 00   ................
0030   00 00 10 00 80 00 00 AA 00 38 9B 71 66 61 63 74   .........8.qfact
0040   04 00 00 00 00 00 00 00 64 61 74 61 00 E9 07 00   ........data....
0050   69 01 00 EE FF FF C0 FF FF FD FE FF 54 00 00 DB   i...........T...
0060   FF FF FC 00 00 5A 00 00 66 00 00 15 00 00 EA FE   .....Z..f.......
0070   FF 75 FF FF 8B 00 00 EA FF FF D2 FD FF 26 01 00   .u...........&..
.....

----- Byte breakdown -------

{52 49 46 46}   "RIFF"
{48 E9 07 00}    size of RIFF chunk
{57 41 56 45}   "WAVE"
{66 6D 74 20}   "fmt "
{28 00 00 00}    size of fmt chunk (40 bytes; a WAVEFORMATEXTENSIBLE struct)
{FE FF}     wFormatTag:  WAVE_FORMAT_EXTENSIBLE
{02 00}      nChannels:  2
{00 77 01 00}    nSamplesPerSec:  96000
{00 CA 08 00}    nAvgBytesPerSec:  576000
{06 00}    nBlockAlign:  6
{18 00}    nBitsPerSample:  24
{16 00}    cbSize:  22    (extra bytes of format information)
{18 00}    wValidBitsPerSample:  24
{03 00 00 00}    dwChannelMask: 3 (for SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT)
{01 00 00 00 00 00 10 00 80 00 00 AA 00 38 9B 71}    SubFormat:  KSDATAFORMAT_SUBTYPE_PCM
{66 61 63 74}  "fact"
{04 00 00 00}  size of fact chunk
{00 00 00 00}
{64 61 74 61}   "data"
{00 E9 07 00}   size of data chunk  (518400 bytes)
{ .......................}   actual audio data, ordered as 3 bytes left channel, 3 bytes right channel etc..

Java Utility to read RIFF file header information


RiffRead32.java source code     RiffRead32.class (compiled with java 1.6.0_01)
---------- Java utility class RiffRead32.class -----------
C:\..>java RiffRead32
C:\...My Recordings\24bit96short.wav    LENGTH:  518480 bytes
RIFF ----- data size: 518472 bytes
Form-type: WAVE
fmt  ----- data size: 40 bytes
wFormatTag:  WAVE_FORMAT_EXTENSIBLE
nChannels:  2
nSamplesPerSec:  96000
nAvgBytesPerSec:  576000
nBlockAlign:  6
nBitsPerSample:  24
fact ----- data size: 4 bytes
data ----- data size: 518400 bytes
wav duration:  0.9 sec
Final RIFF data bytecount: 518472
File chunk structure consistent with valid RIFF

.NET C# Utility to convert 32 bit (integer) WAV file to 24 bit

Conv32to24.cs C# source code
This utility parses any valid RIFF/WAV file with either WAVEFORMATEX or WAVEFORMATEXTENSIBLE header structure, performs basic validation on the WAV file and if a valid 32 bit (4-byte packed int) 2 channel (stereo) WAV file (with any sampling rate), converts to 24 bit (3 byte packed int) WAV. Writes a 24 bit WAV file with only the minimal essential WAVEFORMATEX 44 byte header and discards any extra subchunks ("fact", "list" etc..) and drops the WAVEFORMATEXTENSIBLE extra data if present. The 4 byte (32 bit) to 3 byte (24 bit) conversion drops the lowest order (least significant) byte of the 32 bit integer wav data for each channel. Note that the wFormatTag must be either WAVE_FORMAT_PCM or WAVE_FORMAT_EXTENSIBLE. 32 bit floating point format wav files (wFormatTag = WAVE_FORMAT_IEEE_FLOAT) are not supported.

Sample output:

C:\...>conv32to24
*****  32 bit to 24 bit RIFF/WAV file converter *****
Enter 32 bit WAV filename:
test.wav
WAV header preview  [80 bytes]
52  49  46  46  E8  F8  12  01  57  41  56  45  66  6D  74  20
10  00  00  00  01  00  02  00  00  77  01  00  00  B8  0B  00
08  00  20  00  64  61  74  61  C0  F8  12  01  00  00  00  00
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
"data"  [64 61 74 61]      "fact" [66 61 63 74]
This appears to be a valid RIFF WAV header
32 bit 96000 Hz WAV data size 18020544 bytes
Converted 32 bit/96000 Hz stereo WAV file to 24 bit stereo WAV file
Input file  (32 bit) test.wav  18020588 bytes
Output file (24 bit) conv24_test.wav  13515452 bytes
C:\...>conv32to24
*****  32 bit to 24 bit RIFF/WAV file converter *****
Enter 32 bit WAV filename:
wav_1000.wav
WAV header preview  [80 bytes]
52  49  46  46  48  58  0F  02  57  41  56  45  66  6D  74  20
28  00  00  00  FE  FF  02  00  00  77  01  00  00  CA  08  00
06  00  18  00  16  00  18  00  03  00  00  00  01  00  00  00
00  00  10  00  80  00  00  AA  00  38  9B  71  66  61  63  74
04  00  00  00  00  00  00  00  64  61  74  61  00  58  0F  02
"data"  [64 61 74 61]      "fact" [66 61 63 74]
Skipping 24 bytes in fmt chunk ..
Skipping subchunk of size 4 bytes
This appears to be a valid RIFF WAV header
This is not a 2 channel 32 bit WAV file
Channels: 2  nBitsPerSample: 24  nBlockAlign: 6 wavdata size: 34560000 bytes

.NET C# Utility to convert any valid RIFF stereo WAV file to 44 byte RIFF header WAV file with same data

riff44.cs C# source code
This utility parses any valid RIFF/WAV file with either WAVEFORMATEX or WAVEFORMATEXTENSIBLE header structure, performs basic validation on the WAV file and if a WAV file, writes a new WAV file with rudimentary 44-byte RIFF header (with simplest 16 byte fmt chunk), removing extra sub-chunks.

References

Multiple Channel Audio Data and WAVE Files
WAVEFORMATEXTENSIBLE documentation
Older RIFF/WAV Information