我将如何使用 NAudio 压缩来自麦克风的传入 PCM 数据?
How would I use NAudio to compress incoming PCM data from the microphone?
我正在开发一个 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 class 如何以这种方式实际 encode/compress 音频数据。
更新
我能够使用 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,并将 return 值打包到一半大小的新数组中。
我正在开发一个 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 class 如何以这种方式实际 encode/compress 音频数据。
更新
我能够使用 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,并将 return 值打包到一半大小的新数组中。