如何以编程方式将2个或更多.WAV文件连接在一起?

时间:2011-07-21 14:05:07

标签: c# audio wav

我需要能够将两个或多个.wav文件一起加入到一个.wav文件中。我必须使用C#以编程方式执行此操作(第三方产品不是一个选项)。我知道System.Media.SoundPlayer类,但我不打算播放.wav,只是为了创建它。

5 个答案:

答案 0 :(得分:28)

这是使用NAudio构建的基本WAV级联功能。这将确保仅连接数据块(与另一个答案中链接的this CodeProject article中的代码示例不同)。它还可以防止你连接不同格式的WAV文件。

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

}

答案 1 :(得分:1)

查看这个代码项目示例,似乎正是您需要的,并且对如何执行此操作也有很好的解释:

Concatenating Wave Files Using C# 2005

它似乎主要包括将所有wav文件中的声音数据提取并合并到一个数据块中,顶部有一个新的文件头

编辑:我没有使用此功能的经验,我也不是专家。我刚看到这篇文章并认为它可能有用。请参阅Mark Heath的答案以获得更好的解决方案

答案 2 :(得分:1)

关于马克回答的一条评论:

在比较波形时,==运算符似乎对我不起作用。这样做更安全:

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

或者,您可以将阅读器包装在WaveFormatConversionStream中并完全摆脱格式检查(不确定它是否适用于所有场景但我能够成功测试它)。

答案 3 :(得分:1)

使用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);
    }

答案 4 :(得分:0)

如果只需要字节数组,则可以插入数据库或其他人。您可以使用内存流:

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