我将如何使用 NAudio 压缩来自麦克风的传入 PCM 数据?
Posted
技术标签:
【中文标题】我将如何使用 NAudio 压缩来自麦克风的传入 PCM 数据?【英文标题】:How would I use NAudio to compress incoming PCM data from the microphone? 【发布时间】:2019-05-13 00:31:27 【问题描述】:
我正在开发一个 VOIP 应用程序,它将使用 NAudio 通过网络传输音频数据。由于带宽问题,我不想流式传输原始 PCM,所以我试图用 μ-law 对样本进行编码。到目前为止,我一直无法找到任何关于这是如何完成的解释。我假设我应该使用NAudio.Codecs.MuLawEncoder.LinearToMuLawSample(short s)
,但问题是我在 DataAvailable 事件中获得了一个字节数组。
我尝试遍历 DataAvailable 缓冲区,在每个字节上调用 LinearToMuLawSample。但是,数组的实际大小显然没有改变,因此我没有减少任何大小。
这是负责编码的代码:
byte[] sample = _rawSamples.Take(); //take from sample buffer
for (int i = 0; i < sample.Length; i++) //actual conversion code
sample[i] = MuLawEncoder.LinearToMuLawSample(sample[i]);
_encodedSamples.Add(sample); //add to network buffer
这是我的 DataAvailable 处理程序的内容:
private void _input_DataAvailable(object sender, WaveInEventArgs e)
byte[] buffer = e.Buffer;
Array.Resize(ref buffer, e.BytesRecorded);
_rawSamples.Add(audioData);
最后,这是我声明 WaveIn 的方式:
_input = new WaveIn();
_input.BufferMilliseconds = 100;
_input.DataAvailable += _input_DataAvailable;
_input.RecordingStopped += _input_InputRecordingStopped;
本质上,我正在寻找一种以字节数组形式获取 PCM 数据并将其转换为适合通过网络发送的格式的方法。我不太明白 MuLawEncoder 类如何以这种方式实际编码/压缩音频数据。
【问题讨论】:
即使输入是字节数组,单个样本的大小是多少?在this example 中,样本是 16 位的,因此它们将输入数组中的每对字节解释为 16 位整数,然后再将其传递给编码器... 我正在使用 16 位音频。那么这个示例代码将原始 PCM 的大小减半? 是的,你没看错。 一个很好的起点是查看 NAudioDemo 项目中网络聊天演示的代码。它显示了基本的麦克风捕获,而 Mulaw 是可用的编解码器之一 【参考方案1】:更新
我能够使用https://github.com/naudio/NAudio/blob/master/NAudioDemo/NetworkChatDemo/ 中的示例使其正常工作。以下是我最终使用的关键功能:
private byte[] EncodeSamples(byte[] data)
byte[] encoded = new byte[data.Length / 2];
int outIndex = 0;
for (int n = 0; n < data.Length; n += 2)
encoded[outIndex++] = MuLawEncoder.LinearToMuLawSample(BitConverter.ToInt16(data, n));
return encoded;
private byte[] DecodeSamples(byte[] data)
byte[] decoded = new byte[data.Length * 2];
int outIndex = 0;
for (int n = 0; n < data.Length; n++)
short decodedSample = MuLawDecoder.MuLawToLinearSample(data[n]);
decoded[outIndex++] = (byte)(decodedSample & 0xFF);
decoded[outIndex++] = (byte)(decodedSample >> 8);
return decoded;
关键是一次遍历两个字节的数据,将每一对转换为 Int16,将其传递给 LinearToMuLawSample,并将返回值打包成一个大小为一半的新数组。
【讨论】:
以上是关于我将如何使用 NAudio 压缩来自麦克风的传入 PCM 数据?的主要内容,如果未能解决你的问题,请参考以下文章
记录来自 NAudio WaveIn 的输入,并输出到 NAudio WaveOut
如何使用 NAudio 将麦克风(mic-in)设置为默认值?