Press "Enter" to skip to content

C# Merge wav files

Merging wav files by manupulating byte array.

Here is a very handy wav file structure,

There are several properties but our main goal is merge two wav files without ruining them. So we need to focus on two things.

First, ChunkSize

Every wav file’s 0 to 44 contains information about the file. Between 4th and 8th indexes, it keeps the length of the file.

So we have to extract this information from two wav files’ byte array’s and sum them,

I have created a simple Console Application. First, let’s read bytes from wav files.

static void Main(string[] args)
{
    byte[] firstWavFile = File.ReadAllBytes("one.wav");
    byte[] secondWavFile = File.ReadAllBytes("two.wav");

    byte[] secondWavFileData = secondWavFile.Skip(44).ToArray();
}

And we can skip first 44 bytes from second file data. Because we don’t need it’s headers.

Then we can define a method that extracts 4 to 8 byte values from given array.

public static int ExtractLength(byte[] sourceArray)
{
     byte[] innerValue = new byte[4]; // we know that it has 4 length
     Array.Copy(sourceArray, 4, innerValue, 0, 4); // we have copied values
     return BitConverter.ToInt32(innerValue, 0); // and return to integer 
}

Now we can call it from Main()

static void Main(string[] args)
{
    byte[] firstWavFile = File.ReadAllBytes("one.wav");
    byte[] secondWavFile = File.ReadAllBytes("two.wav");

    byte[] secondWavFileData = secondWavFile.Skip(44).ToArray();
    
    int lengthOfFirst = ExtractLength(firstWavFile);
    int lengthOfSecond = ExtractLength(secondWavFile);

    byte[] finalLengthArray = BitConverter.GetBytes(lengthOfFirst + lengthOfSecond);
}

Okay let’s say lengthOfFirst is 1000 and lengthOfSecond is 2000. We got 3000 in finalLengthArray.

And next we have to manipulate the firstWavFile‘s header. We have to replace 1000 with 3000.

40 to 44 contains this information. So we need to set 3000 to here.

Basically we just need to do is,

firstWavFile[40] = finalLengthArray[0];
firstWavFile[41] = finalLengthArray[1];
firstWavFile[42] = finalLengthArray[2];
firstWavFile[43] = finalLengthArray[3];

After all, manipulation has been done. One more step to go. Concat data parts and write to file.

byte[] result = firstWavFile.Concat(secondWavFileData).ToArray();
File.WriteAllBytes("final.wav", result);

Here is the result, (1:03 file generated)

Full code:

class Program
{
    static void Main(string[] args)
    {
        byte[] firstWavFile = File.ReadAllBytes("one.wav");
        byte[] secondWavFile = File.ReadAllBytes("two.wav");
        byte[] secondWavFileData = secondWavFile.Skip(44).ToArray();

        int lengthOfFirst = ExtractLength(firstWavFile);
        int lengthOfSecond = ExtractLength(secondWavFile);

        byte[] finalLengthArray = BitConverter.GetBytes(lengthOfFirst + lengthOfSecond);

        firstWavFile[40] = finalLengthArray[0];
        firstWavFile[41] = finalLengthArray[1];
        firstWavFile[42] = finalLengthArray[2];
        firstWavFile[43] = finalLengthArray[3];

        byte[] result = firstWavFile.Concat(secondWavFileData).ToArray();

        File.WriteAllBytes("final.wav", result);
    }

    public static int ExtractLength(byte[] sourceArray)
    {
        byte[] innerValue = new byte[4];
        Array.Copy(sourceArray, 4, innerValue, 0, 4);
        return BitConverter.ToInt32(innerValue, 0);
    }
}

Cheers!