如何在 C# 中分层两个音频文件?

Posted

技术标签:

【中文标题】如何在 C# 中分层两个音频文件?【英文标题】:How can I layer two audio files in C#? 【发布时间】:2009-05-18 20:12:19 【问题描述】:

我需要混合两个音频文件。音频 1 将是一个静态文件,用于“标记”音频 2。为了清楚起见,我说的是音频标记而不是 ID3 标记。

有两个基本问题我无法解决。

1) 如何在与音频 2 混合时重复音频 1,以使结果与音频 2 的长度相同?

2) 音频 2 将是 MP3,我不想重新编码它并可能降低它的质量。

任何关于如何在 C# 中完成此操作的库或想法将不胜感激。

【问题讨论】:

【参考方案1】:

您可以使用NAudio 来执行此操作。使用 WaveFileReader 类创建一个可以从每个文件中读取的 WaveStream(MP3 需要先转换为 PCM - 请参阅 NAudio 演示代码中 Mp3FileReader 的使用)。然后我会创建一个循环的派生 WaveStream(即在 Read 方法中,当你到达源数据的末尾时,回到开头)。

然后使用 WaveMixerStream32 将它们混合在一起。 (需要先将它们转换为 32 位 - 使用 WaveChannel32 来执行此操作)。此类还允许您设置每个文件的音量级别。最后,使用 Wave32To16Stream 转换回 16 位,然后使用 WaveFileWriter 制作最终文件。然后使用 LAME 转换为 MP3。

【讨论】:

每当我尝试使用时,WaveChannel32 都会给我这个错误“数组的偏移量和长度超出范围或计数大于从索引到源集合末尾的元素数”。任何想法为什么? (更多信息naudio.codeplex.com/Thread/View.aspx?ThreadId=79458) 嗨,你能用例子解释一下吗..我是 Naudio 的新手,谢谢【参考方案2】:

您必须将 mp3 解码为波形格式,执行混合,然后将其编码回 mp3 格式。

必须有人向您指出一些 mp3 库。不过,我可以帮助你进行实际的混音。

这实际上是如何工作的,这有点酷。声音文件只是以一定间隔记录的一堆幅度样本。例如,这可能是一个声音:

0、12、128、14、-1、-13、-128、-64、-32

好的,这是一个非常短的声音,但请等我。假设我想将上面的声音与这个声音混合:

10、-12、-100、-150、-75、-25、-12、-0

这是很酷的部分,我们只需将两个数组相加即可:

10、0、28、-136、-76 ...

0 + 10 = 10 12 + -12 = 0 128 + -100 = 28 ...

您真正需要注意的唯一一件事是,您可以存储在波形文件中的幅度存在限制。现在大多数都是 16 位的,但您仍然可以制作 8 位的波形文件。如果您的振幅超过了波形文件的限制,您将不得不尽可能高或尽可能低并限制它。

无论如何,这就是它的要点。更精细的点,需要解决。

【讨论】:

分层不同位深度的音频文件时应考虑的其他事项。如果您尝试将 8 位文件与 16 位文件混合,则 16 位文件的精度更高。在添加之前,您需要放大 8 位文件或缩小 16 位文件。 确实如此。这让我想起了。混合音频的另一个要素是音量。每次混音时,基本上都是在增加音量。如果您的波形音量几乎达到最大值(音乐经常如此),您将不得不遍历原始样本以找到最高/最低峰值,然后将混合音频标准化为该峰值。这意味着您可能希望使用范围更大的中间数据类型(如 32 位整数),这样当您混合两个非常响亮的(?)声音样本时,您最终不会截断很多峰值。标准化后,您可以将声音存储回 16/8 位格式。【参考方案3】:

我建议使用 BASS 库。它可以“混合”并允许播放多种格式以及 DSP,例如 EQ/Fade/Compressor。 http://un4seen.com/bass.html

【讨论】:

以上是关于如何在 C# 中分层两个音频文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中使用 ContentPushStream 播放块音频?

在 C# 中合并两个音频文件

如何在 C# 中使用原始音频样本创建波形流?

如何在 C# 中读取 .wav 文件的比特率

在 C# (WP7) 中创建音频文件

如何在ffmpeg中合并音频和两个视频文件?