How can I detect whether a WAV file has a 44 or 46-byte header?

wav file header reader online
wav header
wav file format pdf
riff wavefmt converter
what does a wav file contain
wav file header and footer
write wav file header
how to read a wav file

I've discovered it is dangerous to assume that all PCM wav audio files have 44 bytes of header data before the samples begin. Though this is common, many applications (ffmpeg for example), will generate wavs with a 46-byte header and ignoring this fact while processing will result in a corrupt and unreadable file. But how can you detect how long the header actually is?

Obviously there is a way to do this, but I searched and found little discussion about this. A LOT of audio projects out there assume 44 (or conversely, 46) depending on the authors own context.

You should be checking all of the header data to see what the actual sizes are. Broadcast Wave Format files will contain an even larger extension subchunk. WAV and AIFF files from Pro Tools have even more extension chunks that are undocumented as well as data after the audio. If you want to be sure where the sample data begins and ends you need to actually look for the data chunk ('data' for WAV files and 'SSND' for AIFF).

As a review, all WAV subchunks conform to the following format:

Subchunk Descriptor (4 bytes)
    Subchunk Size (4 byte integer, little endian)
    Subchunk Data (size is Subchunk Size)

This is very easy to process. All you need to do is read the descriptor, if it's not the one you are looking for, read the data size and skip ahead to the next. A simple Java routine to do that would look like this:

//
// Quick note for people who don't know Java well:
// 'in.read(...)' returns -1 when the stream reaches
// the end of the file, so 'if (in.read(...) < 0)'
// is checking for the end of file.
//
public static void printWaveDescriptors(File file)
        throws IOException {
    try (FileInputStream in = new FileInputStream(file)) {
        byte[] bytes = new byte[4];

        // Read first 4 bytes.
        // (Should be RIFF descriptor.)
        if (in.read(bytes) < 0) {
            return;
        }

        printDescriptor(bytes);

        // First subchunk will always be at byte 12.
        // (There is no other dependable constant.)
        in.skip(8);

        for (;;) {
            // Read each chunk descriptor.
            if (in.read(bytes) < 0) {
                break;
            }

            printDescriptor(bytes);

            // Read chunk length.
            if (in.read(bytes) < 0) {
                break;
            }

            // Skip the length of this chunk.
            // Next bytes should be another descriptor or EOF.
            int length = (
                  Byte.toUnsignedInt(bytes[0])
                | Byte.toUnsignedInt(bytes[1]) << 8
                | Byte.toUnsignedInt(bytes[2]) << 16
                | Byte.toUnsignedInt(bytes[3]) << 24
            );
            in.skip(Integer.toUnsignedLong(length));
        }

        System.out.println("End of file.");
    }
}

private static void printDescriptor(byte[] bytes)
        throws IOException {
    String desc = new String(bytes, "US-ASCII");
    System.out.println("Found '" + desc + "' descriptor.");
}

For example here is a random WAV file I had:

Found 'RIFF' descriptor.
Found 'bext' descriptor.
Found 'fmt ' descriptor.
Found 'minf' descriptor.
Found 'elm1' descriptor.
Found 'data' descriptor.
Found 'regn' descriptor.
Found 'ovwf' descriptor.
Found 'umid' descriptor.
End of file.

Notably, here both 'fmt ' and 'data' legitimately appear in between other chunks because Microsoft's RIFF specification says that subchunks can appear in any order. Even some major audio systems that I know of get this wrong and don't account for that.

So if you want to find a certain chunk, loop through the file checking each descriptor until you find the one you're looking for.

How can I detect whether a WAV file has a 44 or 46-byte header , I've discovered it is dangerous to assume that all PCM wav audio files have 44 bytes of header data before the samples begin. Though this is common, many� I've discovered it is dangerous to assume that all PCM wav audio files have 44 bytes of header data before the samples begin. Though this is common, many applications (ffmpeg for example), will gen

The trick is to look at the "Subchunk1Size", which is a 4-byte integer beginning at byte 16 of the header. In a normal 44-byte wav, this integer will be 16 [10, 0, 0, 0]. If it's a 46-byte header, this integer will be 18 [12, 0, 0, 0] or maybe even higher if there is extra extensible meta data (rare?).

The extra data itself (if present), begins in byte 36.

So a simple C# program to detect the header length would look like this:

static void Main(string[] args)
{
    byte[] bytes = new byte[4];
    FileStream fileStream = new FileStream(args[0], FileMode.Open, FileAccess.Read);
    fileStream.Seek(16, 0);
    fileStream.Read(bytes, 0, 4);
    fileStream.Close();
    int Subchunk1Size = BitConverter.ToInt32(bytes, 0);

    if (Subchunk1Size < 16)
        Console.WriteLine("This is not a valid wav file");
    else
        switch (Subchunk1Size)
        {
            case 16:
                Console.WriteLine("44-byte header");
                break;
            case 18:
                Console.WriteLine("46-byte header");
                break;
            default:
                Console.WriteLine("Header contains extra data and is larger than 46 bytes");
                break;
        }
}

Wav (RIFF) File Format Tutorial, A WAV (RIFF) file is a multi-format file that contains a header and data. For the The header of a WAV (RIFF) file is 44 bytes long and has the following format:� The trick is to look at the “Subchunk1Size”, which is a 4-byte integer beginning at byte 16 of the header. In a normal 44-byte wav, this integer will be 16 [10, 0, 0, 0]. If it’s a 46-byte header, this integer will be 18 [12, 0, 0, 0] or maybe even higher if there is extra extensible meta data (rare?).

In addition to Radiodef's excellent reply, I'd like to add 3 things that aren't obvious.

  1. The only rule for WAV files is the FMT chunk comes before the DATA chunk. Apart from that, you will find chunks you don't know about at the beginning, before the DATA chunk and after it. You must read the header for each chunk to skip forward to find the next chunk.

  2. The FMT chunk is commonly found in 16 byte and 18 byte variations, but the spec actually allows more than 18 bytes as well. If the FMT chunk' header size field says greater than 16, Bytes 17 and 18 also specify how many extra bytes there are, so if they are both zero, you end up with an 18 byte FMT chunk identical to the 16 byte one. It is safe to read in just the first 16 bytes of the FMT chunk and parse those, ignoring any more. Why does this matter? - not much any more, but Windows XP's Media Player was able to play 16 bit WAV files, but 24 bit WAV files only if the FMT chunk was the Extended (18+ byte) version. There used to be a lot of complaints that "Windows doesn't play my 24 bit WAV files", but if it had an 18 byte FMT chunk, it would... Microsoft fixed that sometime during the early days of Windows 7, so 24 bit with 16 byte FMT files work fine now.

  3. (Newly added) Chunk sizes with odd sizes occur quite often. Mostly seen when a 24 bit mono file is made. It is unclear from the spec, but the chunk size specifies the actual data length (the odd value) and a pad byte (zero) is added after the chunk and before the start of the next chunk. So chunks always start on even boundaries, but the chunk size itself is stored as the actual odd value.

Wav file header and footer, Problems with using Magic Bytes for File Detection Magic bytes are not The header of a WAV (RIFF) file is 44 bytes long and has the following format: Positions. g. is dangerous to assume that all PCM wav audio files have 44 bytes of header applications (ffmpeg for example), will generate wavs with a 46 -byte header� How can I detect whether a WAV file has a 44 or 46-byte header? (5) In addition to Radiodef's excellent reply, I'd like to add 3 things that aren't obvious. The only rule for WAV files is the FMT chunk comes before the DATA chunk.

[PDF] Disassembling a Windows Wave File (.wav), and a Microsoft wave file, without the need of buying expensive wave form generator Before reading on, have a look at that documentation first. My document. I've discovered it is dangerous to assume that all PCM wav audio files have 44 bytes of header data before the samples begin. Though this is common, many applications (ffmpeg for example), will generate wavs with a 46-byte header and ignoring this fact while processing will result in a corrupt and unreadable file.

How do I combine/merge two wav files into one wav file?, new wav file = {header data1 data2 } = {44/46 size(data1) size(data2)} bytes at offset 40 or 42, depending on if you have a 44byte header or 46 byte header). How can I detect whether a WAV file has a 44 or 46-byte header? I've discovered it is dangerous to assume that all PCM wav audio files have 44 bytes of header data before the samples begin. Though this is common, many

File Signatures, My software utility page contains a custom signature file based upon this list, for use with FTK, Scalpel, Simple Carver, Simple Carver Lite, and 4F 4E 2D 58 46 49 4C 45 ON-XFILE RVT, Revit Project File subheader NOTE: It appears that the byte following the 0x52 ("R") is 41 4D 20 44 61 74 61 62 How can I detect whether a WAV file has a 44 or 46-byte header? I've discovered it is dangerous to assume that all PCM wav audio files have 44 bytes of header data before the samples begin. Though this is common, many

Comments
  • I have a lot of WAV files where the data starts somewhere else entirely: maybe hundreds of bytes from the start of the file, who knows? The WAV chunk headers are actually easy to parse, you have no excuse for not parsing them.
  • It's true there is no excuse for parsing the header, but there is a lot of misinformation out there about doing so. Search for "wav parser" on Google and many of top hits contain code that assumes 44-byte length with no discussion. SO contained only hints toward something larger. I'm try to draw attention to this issue for the next frustrated person who goes looking.
  • I've always found that the WAVE PCM soundfile format page on the Center for Computer Research in Music and Acoustics (Standford) website to be a useful resource for this type of thing.
  • Radiodef, thanks for your comment! I never used bit shifting before and can't find practical use examples in web. Could you please explain what this expression does why bit shifting is used here? <code> (bytes[0] & 0xFF) | (bytes[1] & 0xFF) << 8 | (bytes[2] & 0xFF) << 16 | (bytes[3] & 0xFF) << 24 </code> Thank you beforehand!
  • @RomanM It converts 4 bytes to a 32-bit integer. For example, a 32-bit integer 00000000000000001000000010000001 (decimal 32897) could be split in to four bytes, 00000000, 00000000, 10000000 and 10000001. The code with bit shifting takes bytes and creates a 32-bit integer out of them, by shifting each byte in to place and then combining them with bitwise OR. The & 0xFF part is specific to Java, and explained here.
  • Thank you very much!