Split .wav file into parts using NAudio

Published on Saturday, 29 April 2017

Some time ago I needed to spit PCM wav file into equal pieces. For example I have a 5 minute wav file and I want to split it into a 2 seconds parts. Audio editors are not very helpful here.

We could use ffmpeg here:

ffmpeg -ss 0 -t 30 -i file.mp3 file.wav
-ss 0 - Start at 0 seconds
-t 30 - Capture 30 seconds (from 0, so 0:00 - 0:30). If you want 1 minute of audio, use -t 60.
file.mp3 - Input file
file.wav - output file

(see stackoverflow)

But I want to have more control over the process (especially file naming) and would like to try NAudio (I'm using version 1.8).

The basic idea is to convert time into stream position and then write each part into its own .wav file. We can get number of bytes per second using this:

waveFileReader.WaveFormat.AverageBytesPerSecond

But for better accuracy let's convert seconds to milliseconds:

//for PCM WAV AverageBytesPerSecond = sampleRate * (channels * (bits / 8));
int bytesPerMilliseconds = waveFileReader.WaveFormat.AverageBytesPerSecond / 1000;

So at first we have startPos = 0 And

endPos = startPos + (partDurationMilliseconds * bytesPerMilliseconds);

Here is one of possible implementations of the method which read and write a "chunk" of wave file

private static void WriteWavChunk(WaveFileReader reader, WaveFileWriter writer, long startPos, long endPos)
{
    reader.Position = startPos;

    // make sure that buffer is sized to a multiple of our WaveFormat.BlockAlign.
    // WaveFormat.BlockAlign = channels * (bits / 8), so for 16 bit stereo wav it will be 4096 bytes
    var buffer = new byte[reader.BlockAlign * 1024];
    while (reader.Position < endPos)
    {
        long bytesRequired = endPos - reader.Position;
        if (bytesRequired > 0)
        {
            int bytesToRead = (int)Math.Min(bytesRequired, buffer.Length);
            int bytesRead = reader.Read(buffer, 0, bytesToRead);
            if (bytesRead > 0)
            {
                writer.Write(buffer, 0, bytesToRead);
            }
        }
    }
}

You could find a complete example here on github

Happy Coding!