C# 如何以编程方式将2个或多个.WAV文件连接在一起?
我需要能够将2个或多个.wav文件合并到一个.wav文件中。我必须使用C#(第三方产品不是选项)以编程方式完成这项工作。我知道System.Media.SoundPlayer类,但我不想播放.wav,而只是想创建它。看看这个codeproject示例,它似乎正是您需要的,并提供了一个很好的解释,说明了如何操作: 它似乎主要包括从所有wav文件中提取声音数据并将其合并为一个数据块,并在顶部添加一个新的文件头C# 如何以编程方式将2个或多个.WAV文件连接在一起?,c#,audio,wav,C#,Audio,Wav,我需要能够将2个或多个.wav文件合并到一个.wav文件中。我必须使用C#(第三方产品不是选项)以编程方式完成这项工作。我知道System.Media.SoundPlayer类,但我不想播放.wav,而只是想创建它。看看这个codeproject示例,它似乎正是您需要的,并提供了一个很好的解释,说明了如何操作: 它似乎主要包括从所有wav文件中提取声音数据并将其合并为一个数据块,并在顶部添加一个新的文件头 编辑:我没有使用此功能的经验,也不是专家。我刚看到这篇文章,觉得它可能有用。有关更好的解
编辑:我没有使用此功能的经验,也不是专家。我刚看到这篇文章,觉得它可能有用。有关更好的解决方案,请参见Mark Heath的答案这里有一个使用创建的基本WAV连接函数。这将确保仅连接数据块(与另一个答案中链接的代码示例不同)。它还可以防止连接不共享相同格式的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();
}
}
}
publicstaticvoidconcatenate(字符串输出文件、IEnumerable源文件)
{
字节[]缓冲区=新字节[1024];
WaveFileWriter WaveFileWriter=null;
尝试
{
foreach(sourceFiles中的字符串sourceFile)
{
使用(WaveFileReader=新的WaveFileReader(源文件))
{
如果(waveFileWriter==null)
{
//第一次在“创建新作家”中
waveFileWriter=新的waveFileWriter(输出文件,reader.WaveFormat);
}
其他的
{
如果(!reader.WaveFormat.Equals(waveilewriter.WaveFormat))
{
抛出新的InvalidOperationException(“无法连接不共享相同格式的WAV文件”);
}
}
int-read;
而((read=reader.read(buffer,0,buffer.Length))>0)
{
waveFileWriter.WriteData(缓冲区,0,读取);
}
}
}
}
最后
{
如果(waveFileWriter!=null)
{
waveFileWriter.Dispose();
}
}
}
对马克的回答有一点评论:
比较波形格式时,==运算符似乎不适用于我。这样做更安全:
if (!reader.WaveFormat.Equals(waveFileWriter.WaveFormat))
或者,您可以将读卡器包装在波形转换流中,并完全取消格式检查(不确定它是否适用于所有场景,但我能够成功地测试它)。从
若您只需要获取字节数组,则可以将其插入数据库或其他人。您可以使用内存流:
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);
}
}
公共静态字节[]串联(IEnumerable sourceData)
{
var buffer=新字节[1024*4];
WaveFileWriter WaveFileWriter=null;
使用(var output=newmemoryStream())
{
尝试
{
foreach(sourceData中的var binaryData)
{
使用(var audioStream=newmemoryStream(二进制数据))
{
使用(WaveileReader=新的WaveileReader(音频流))
{
如果(waveFileWriter==null)
waveFileWriter=新的waveFileWriter(输出、读卡器、波形格式);
其他的
AssertWaveFormat(读卡器、波形编写器);
WaveStreamWrite(读卡器、waveFileWriter、缓冲器);
}
}
}
waveFileWriter.Flush();
返回输出.ToArray();
}
最后
{
waveFileWriter?.Dispose();
}
}
}
私有静态void资产waveformat(waveilereader读取器、waveilewriter writer)
{
如果(!reader.WaveFormat.Equals(writer.WaveFormat))
{
抛出新的InvalidOperationException(“无法连接不共享相同格式的WAV文件”);
}
}
专用静态无效WaveStreamWrite(WaveFileReader读取器、WaveFileWriter写入器、字节[]缓冲区)
{
int-read;
而((read=reader.read(buffer,0,buffer.Length))>0)
{
writer.Write(缓冲区,0,读取);
}
}
ty,看起来像我要找的。我建议不要使用本文中的代码。它假定fmt块始终具有完全相同的长度,并且数据块在所有WAV文件中显示在完全相同的位置。它假定不存在其他块。对于WAV文件,这些都不是理所当然的,因此它可以轻松创建一个垃圾WAV文件。@MarkHeath我也遇到了同样的问题,它创建了一个合并但不受支持的WAV文件,但它在android上工作,而不是在ios上。有其他想法的人可以提出建议吗。提前谢谢。样品很好。。。我确认wavformat比较没有按照预期工作,正如davidair所指出的。在将nuget Naudio添加到项目中并使用上述函数合并一个生成错误后。“未能解析”System.Runtime.InteropServices.StandardOleMarshallObject“引用自”System,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089“为什么会发生这种情况?为什么不将其添加到库中?什么是AudioCompressionManager?它的核心是什么?”?
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);
}
}