Подтвердить что ты не робот

Как объединить 2 или более файлов .WAV вместе программно?

Мне нужна возможность объединить два или более WAV файла вместе в один .wav файл. Я должен делать это программно, используя С# (сторонние продукты не являются опцией). Я знаю класс System.Media.SoundPlayer, но я не хочу играть в WAV, но только для его создания.

4b9b3361

Ответ 1

Вот базовая функция конкатенации WAV, построенная с помощью NAudio. Это гарантирует, что только фрагменты данных объединены (в отличие от примера кода в этой статье CodeProject, связанной в другом ответе). Он также защитит вас от конкатенации файлов 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();
        }
    }

}

Ответ 2

Проверьте этот пример кода, кажется, именно то, что вам нужно, с хорошим объяснением, как это сделать:

Конкатенация волновых файлов с использованием С# 2005

Похоже, что он включает в себя извлечение и объединение звуковых данных из всех wav файлов в один фрагмент данных с новым заголовком файла сверху

EDIT: У меня нет опыта использования этого, и я не эксперт. Я просто наткнулся на эту статью и подумал, что это может быть полезно. См. Ответ Марка Хит для лучшего решения

Ответ 3

Один комментарий к ответу Марка:

Оператор ==, похоже, не работает для меня при сравнении волновых форматов. Это безопаснее:

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

В качестве альтернативы вы можете обернуть читателя в WaveFormatConversionStream и полностью избавиться от проверки формата (не уверен, что он будет работать во всех сценариях, но я смог успешно протестировать его).

Ответ 4

Использование Как присоединиться к файлам .Wav вместе

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

Ответ 5

Если вам нужно получить только байтовый массив, чтобы вставить в базу данных или кто-то еще. Вы можете использовать поток памяти:

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