How to join 2 or more .WAV files together programmatically?

和自甴很熟 提交于 2019-11-27 03:59:49

Here's a basic WAV concatenation function built using NAudio. This will ensure that only the data chunks are concatenated (unlike the code example in this CodeProject article linked in another answer). It will also protect you against concatenating WAV files that do not share the same format.

public static void Concatenate(string outputFile, IEnumerable<string> sourceFiles)
{
    byte[] buffer = new byte[1024];
    WaveFileWriter waveFileWriter = null;

    try
    {
        foreach (string sourceFile in sourceFiles)
        {
            using (WaveFileReader reader = new WaveFileReader(sourceFile))
            {
                if (waveFileWriter == null)
                {
                    // first time in create new Writer
                    waveFileWriter = new WaveFileWriter(outputFile, reader.WaveFormat);
                }
                else
                {
                    if (!reader.WaveFormat.Equals(waveFileWriter.WaveFormat))
                    {
                        throw new InvalidOperationException("Can't concatenate WAV Files that don't share the same format");
                    }
                }

                int read;
                while ((read = reader.Read(buffer, 0, buffer.Length)) > 0)
                {
                    waveFileWriter.WriteData(buffer, 0, read);
                }
            }
        }
    }
    finally
    {
        if (waveFileWriter != null)
        {
            waveFileWriter.Dispose();
        }
    }

}

One comment on Mark's answer:

The == operator does not seem to work for me when comparing wave formats. It's safer to do this:

if (!reader.WaveFormat.Equals(waveFileWriter.WaveFormat))

Alternatively, you could wrap the reader in a WaveFormatConversionStream and get rid of the format check altogether (not sure if it will work on all scenarios but I was able to succesfully test it).

Check out this codeproject example, seems to be exactly what you need with a good explanation of how to do it too:

Concatenating Wave Files Using C# 2005

It seems to comprise essentially of extracting and merging the sound data from all the wav files into one chunk of data with a new file header on top

EDIT: I have no experience of using this, nor am I an expert. I just came across this article and thought it may be useful. See Mark Heath's answer for a better solution

Use from How to join .Wav files together

    private void JoinWav()
    {
        string[] files = new string[] { "1990764-ENG-CONSEC-RESPONSE7.WAV","1990764-ND_A.WAV", "1990764-SIGHT-SP.WAV",
            "1990764-SP-CONSEC-RESPONSE6.WAV","1990764-VOCABWORD-004-12-SP.WAV","bi-consec-1-successful.wav",
            "bi-transition-instruct.wav","nd_B.wav","sightreceived_B.wav","teststamp_A.wav" };
        AudioCompressionManager.Join("res.wav", files);
    }

If you need get only byte array, to insert in database or somebody else. You may use memory stream:

        public static byte[] Concatenate(IEnumerable<byte[]> sourceData)
    {
        var buffer = new byte[1024 * 4];
        WaveFileWriter waveFileWriter = null;

        using (var output = new MemoryStream())
        {
            try
            {
                foreach (var binaryData in sourceData)
                {
                    using (var audioStream = new MemoryStream(binaryData))
                    {
                        using (WaveFileReader reader = new WaveFileReader(audioStream))
                        {
                            if (waveFileWriter == null)
                                waveFileWriter = new WaveFileWriter(output, reader.WaveFormat);
                            else
                                AssertWaveFormat(reader, waveFileWriter);

                            WaveStreamWrite(reader, waveFileWriter, buffer);
                        }
                    }
                }

                waveFileWriter.Flush();

                return output.ToArray();
            }
            finally
            {
                waveFileWriter?.Dispose();
            }
        }
    }

    private static void AssertWaveFormat(WaveFileReader reader, WaveFileWriter writer)
    {
        if (!reader.WaveFormat.Equals(writer.WaveFormat))
        {
            throw new InvalidOperationException("Can't concatenate WAV Files that don't share the same format");
        }
    }

    private static void WaveStreamWrite(WaveFileReader reader, WaveFileWriter writer, byte[] buffer)
    {
        int read;
        while ((read = reader.Read(buffer, 0, buffer.Length)) > 0)
        {
            writer.Write(buffer, 0, read);
        }
    }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!