Как программно объединить 2 или более файлов.WAV вместе?
Мне нужна возможность объединить 2 или более WAV-файлов в один WAV-файл. Я должен сделать это программно, используя C# (сторонние продукты не вариант). Я знаю класс System.Media.SoundPlayer, но я не хочу играть в.wav, а только для его создания.
4 ответа
Вот базовая функция конкатенации 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();
}
}
}
Один комментарий к ответу Марка:
Оператор ==, похоже, не работает для меня при сравнении волновых форматов. Это безопаснее сделать:
if (!reader.WaveFormat.Equals(waveFileWriter.WaveFormat))
В качестве альтернативы, вы можете обернуть читатель в WaveFormatConversionStream и полностью избавиться от проверки формата (не уверен, что она будет работать во всех сценариях, но я смог успешно протестировать ее).
Используйте из Как объединить.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);
}
Если вам нужно получить только байтовый массив, чтобы вставить в базу данных или кто-то еще. Вы можете использовать поток памяти:
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);
}
}
Посмотрите на этот пример кода проекта, кажется, это именно то, что вам нужно, с хорошим объяснением того, как это сделать тоже:
Конкатенация волновых файлов с использованием C# 2005
Похоже, он состоит в основном из извлечения и объединения звуковых данных из всех файлов WAV в один кусок данных с новым заголовком файла сверху.
РЕДАКТИРОВАТЬ: У меня нет опыта использования этого, а также я не эксперт. Я только что наткнулся на эту статью и подумал, что это может быть полезно. См. Ответ Марка Хита для лучшего решения