use this information to design me a c# class for windows form app and give a void that takes an input folder and gets all the wav files in it to be used to combine them all then a string output filename.

How to join 2 or more .WAV files together programmatically?
Asked 13 years, 11 months ago
Modified 6 years, 3 months ago
Viewed 25k times
21

I need the ability to join 2 or more .wav files together in to one .wav file. I must do this programmatically, using C# (3rd-party products are not an option). I know of the System.Media.SoundPlayer class, but I am not looking to play the the .wav, but only to create it.

c#audiowav
Share
Improve this question
Follow
edited Sep 10, 2017 at 6:01
Cœur's user avatar
Cœur
38.9k2525 gold badges206206 silver badges281281 bronze badges
asked Jul 21, 2011 at 14:05
gangelo's user avatar
gangelo
3,19244 gold badges3434 silver badges4646 bronze badges
Add a comment
5 Answers
Sorted by:

Highest score (default)
32

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();
        }
    }

}
Share
Improve this answer
Follow
edited Jan 24, 2012 at 13:37
answered Jul 21, 2011 at 15:39
Mark Heath's user avatar
Mark Heath
49.7k2929 gold badges143143 silver badges200200 bronze badges
good sample... I confirm that the wavformat comparison does not work as expected, as noted by davidair. – 
Peter Walke
 CommentedJan 22, 2012 at 22:33
after adding the nuget Naudio into project and using above funtion to merge thowing one build error. "Failed to resolve "System.Runtime.InteropServices.StandardOleMarshalObject" reference from "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Why is this happening? – 
Riyas
 CommentedApr 23, 2018 at 6:17
Why not add this into the library?? – 
frenchie
 CommentedFeb 19, 2020 at 14:45
Add a comment
1

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

Share
Improve this answer
Follow
edited Oct 21, 2011 at 0:05
answered Oct 20, 2011 at 22:57
David Airapetyan's user avatar
David Airapetyan
5,67855 gold badges4747 silver badges6565 bronze badges
Add a comment
1

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

Share
Improve this answer
Follow
edited Aug 10, 2012 at 12:11
answered Jul 21, 2011 at 14:12
Iain Ward's user avatar
Iain Ward
9,97655 gold badges3737 silver badges4242 bronze badges
I would advise against using the code from this article. It assumes that the fmt chunk is always exactly the same length, and that the data chunk appears in exactly the same place in all WAV files. It assumes that no other chunks are present. None of these can be taken for granted with WAV files, and so it could easily create a garbage WAV file. – 
Mark Heath
 CommentedJul 21, 2011 at 15:33
@MarkHeath exactly same problem occurs to me, it create a merged but unsupported wav file, but its works for android not with ios. Can anyone having alternate ideas please suggest. Thanks in advance. – 
Riyas
 CommentedApr 23, 2018 at 6:23
Add a comment
1

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);
    }
Share
Improve this answer
Follow
edited Feb 2, 2014 at 13:34
answered Feb 1, 2014 at 16:56
Aleks's user avatar
Aleks
49255 silver badges55 bronze badges
what's AudioCompressionManager ? – 
Yuki
 CommentedMay 1, 2014 at 14:50
what is its nuget? – 
Riyas
 CommentedApr 18, 2018 at 13:09
Add a comment
1

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);
        }
    }
Share
Improve this answer
Follow
answered Apr 17, 2019 at 11:51
alfaSigma7i's user avatar
alfaSigma7i
111