C# 使用NAudio获取用于RTP的Ulaw样品
我一直在查看NAudio示例,试图找出如何获得适合包装为RTP有效负载的ulaw样本。我正在尝试使用下面的代码从mp3文件生成示例。毫不奇怪,因为我真的不知道我在用NAudio做什么,当我通过网络将样本传输到软电话时,我得到的是静态的 谁能告诉我如何使用NAudio从MP3文件中获取160字节(8Khz@20ms)的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
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标准,但它支持足够的基本音频传输。