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