我将如何使用 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 值打包到一半大小的新数组中。