Search code examples
audiowav

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 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.


Solution

  • 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;
            }
    }