C# 使用NAudio获取用于RTP的Ulaw样品

C# 使用NAudio获取用于RTP的Ulaw样品,c#,rtp,naudio,C#,Rtp,Naudio,我一直在查看NAudio示例,试图找出如何获得适合包装为RTP有效负载的ulaw样本。我正在尝试使用下面的代码从mp3文件生成示例。毫不奇怪,因为我真的不知道我在用NAudio做什么,当我通过网络将样本传输到软电话时,我得到的是静态的 谁能告诉我如何使用NAudio从MP3文件中获取160字节(8Khz@20ms)的ULAW样本 private void GetAudioSamples() { var pcmStream = WaveFormatConversionStream.Crea

我一直在查看NAudio示例,试图找出如何获得适合包装为RTP有效负载的ulaw样本。我正在尝试使用下面的代码从mp3文件生成示例。毫不奇怪,因为我真的不知道我在用NAudio做什么,当我通过网络将样本传输到软电话时,我得到的是静态的

谁能告诉我如何使用NAudio从MP3文件中获取160字节(8Khz@20ms)的ULAW样本

private void GetAudioSamples()
{
    var pcmStream = WaveFormatConversionStream.CreatePcmStream(new Mp3FileReader("whitelight.mp3"));
    byte[] buffer = new byte[2];
    byte[] sampleBuffer = new byte[160];
    int sampleIndex = 0;
    int bytesRead = pcmStream.Read(buffer, 0, 2);

    while (bytesRead > 0)
    {
        var ulawByte = MuLawEncoder.LinearToMuLawSample(BitConverter.ToInt16(buffer, 0));
        sampleBuffer[sampleIndex++] = ulawByte;

        if (sampleIndex == 160)
        {
            m_rtpChannel.AddSample(sampleBuffer);
            sampleBuffer = new byte[160];
            sampleIndex = 0;
        }

        bytesRead = pcmStream.Read(buffer, 0, 2);
    }

    logger.Debug("Finished adding audio samples.");
}

这里有几点建议。首先,只要您使用NAudio 1.5,就不需要额外的波形转换流—Mp3FileReader的读取方法返回PCM

但是,您将无法获得8kHz,因此需要先对其重新采样。WaveFormatConversionStream可以做到这一点,尽管它使用内置的Windows ACM采样率转换,这似乎无法很好地过滤传入的音频,因此可能存在混叠伪影

此外,您通常一次读取的块大于两个字节,因为MP3解码器需要一次解码一个帧(重采样器还需要处理较大的块大小)。我会尝试一次读取至少20毫秒的字节

您使用BitConverter.ToInt16获取16位采样值是正确的,但请记住,MP3可能是立体声的,具有左、右采样。你确定你的手机需要立体声吗


最后,我建议首先使用WaveFileWriter制作一个mu-law WAV文件。然后,您可以在Windows Media Player中轻松收听,并检查发送到软电话的内容是否符合您的预期。

以下是我最终使其工作的方式。我确实丢失了mp3中的一个频道,我想有某种方法可以将这些频道组合起来作为转换的一部分,但这对我的情况并不重要

160字节的缓冲区大小为我提供了20ms的ulaw样本,这些样本与我正在测试的SIP软电话完美配合

var pcmFormat = new WaveFormat(8000, 16, 1);
var ulawFormat = WaveFormat.CreateMuLawFormat(8000, 1);

using (WaveFormatConversionStream pcmStm = new WaveFormatConversionStream(pcmFormat, new Mp3FileReader("whitelight.mp3")))
{
    using (WaveFormatConversionStream ulawStm = new WaveFormatConversionStream(ulawFormat, pcmStm))
    {
        byte[] buffer = new byte[160];
        int bytesRead = ulawStm.Read(buffer, 0, 160);

        while (bytesRead > 0)
        {
            byte[] sample = new byte[bytesRead];
            Array.Copy(buffer, sample, bytesRead);
            m_rtpChannel.AddSample(sample);

            bytesRead = ulawStm.Read(buffer, 0, 160);
        }
    }
}

嗨,你在c#中使用了什么来实现RTP?@Gabsnake我使用了我自己的原始RTP实现。它不支持完整的RTP标准,但它支持足够的基本音频传输。