如何使用 naudio 将立体声 pcm 样本转换为单声道样本
Posted
技术标签:
【中文标题】如何使用 naudio 将立体声 pcm 样本转换为单声道样本【英文标题】:How can i convert stereo pcm samples to mono samples using naudio 【发布时间】:2013-04-29 17:45:51 【问题描述】:?
或将立体声 mp3 文件转换为单声道原始样本!
我之前试过这个:
for (int u = 0; u < output.Length; u+=4)
byte[] Lbuffer = new byte[2];
byte[] Rbuffer = new byte[2];
Lbuffer[0] = output[u + 0];
Lbuffer[1] = output[u + 1];
Rbuffer[0] = output[u + 2];
Rbuffer[1] = output[u + 3];
Int16 leftSample = BitConverter.ToInt16(Lbuffer, 0);
Int16 rightSample = BitConverter.ToInt16(Rbuffer, 0);
Int16 mixedMono = (Int16)(0.5f * (float)leftSample + (float)rightSample);
Byte[] mixedMonoBytes = BitConverter.GetBytes(mixedMono);
mono[counter] = mixedMonoBytes[0];
mono[counter+1] = mixedMonoBytes[1];
//mono[counter] = Convert.ToByte((Convert.ToInt16(buffer[0]) + Convert.ToInt16(buffer[2]))/2);
//mono[counter+1] = Convert.ToByte((Convert.ToInt16(buffer[0]) + Convert.ToInt16(buffer[2]))/2);
counter += 2;
但它目前不起作用!结果有噪音! 输出是一个包含原始样本的数组!
【问题讨论】:
要将立体声转换为单声道,通常取一个立体声帧的两个样本并计算它们的平均值。结果就是你的单声道样本。 请阅读我的编辑! @user2326338 也许您可以提供更多详细信息来说明究竟是什么不起作用?您在输出文件中听到噪音? 你的左右混合方式是0.5 * left + right,是错误的;应该是 0.5 *(左 + 右)。此外,溢出可能会引起噪音;使用我在回答中建议的饱和算法。要检查的另一件事是数据的字节顺序——它是否与机器的字节序匹配,或者你需要字节交换吗? 理查德沃尔特斯!你的权利! 0.5 *(左+右)是正确的! 【参考方案1】:正如@daniel-s 指出的那样,要将 PCM 样本从立体声(2 个通道)转换为单声道(1 个通道),您可以简单地取两个通道的平均值:对于每个样本,取左通道的值,将右通道的值相加,然后除以 2。使用saturation arithmetic 避免溢出。
要将 MP3 文件转换为原始 (PCM) 样本,您需要通过文件解析器和 MP3 比特流解码器运行 MP3 文件。有许多库和应用程序可以做到这一点。例如,请参阅FFmpeg。
[编辑] 我忘了说,更重要的是,NAudio 支持通过 ACM 或 DMO 编解码器解码 MP3 文件;有关示例,请参见 NAudio - MP3。
【讨论】:
您可以使用乘法代替:0.5 * (1.0 + 1.0) = 1.0 当然,如果您不介意使用浮点类型。有时这可能是一个问题,例如在某些嵌入式环境中。如果您不介意截断分数,可能最好的除以二的方法是进行位移:(1 + 1) >> 1 = 1
完全同意你的看法:-)
一些代码示例,我会按下那个向上按钮以上是关于如何使用 naudio 将立体声 pcm 样本转换为单声道样本的主要内容,如果未能解决你的问题,请参考以下文章
使用 NAudio 将 PCM S16 LE (s16l) 转换为 GSM610
如何使用 PCM 8kHZ 和每个样本 16 位的 Naudio loopbackcapture 独占模式
我将如何使用 NAudio 压缩来自麦克风的传入 PCM 数据?