使用NAudio一次播放多个wav文件时的声音质量问题

时间:2011-05-31 18:17:49

标签: c# audio naudio

我的目标是:允许我的.NET程序的用户选择他们自己的.wav文件来获得音效。这些效果可以同时播放。 NAudio似乎是我最好的选择。

我决定使用WaveMixerStream32。一个早期的挑战是我的用户拥有不同格式的.wav文件,因此为了能够将它们与WaveMixerStream32混合在一起,我需要将它们“标准化”为通用格式。我无法找到一个很好的例子,所以我怀疑我的问题是由于我做错了这个部分。

我的问题是,当播放某些声音时,结尾会发出非常明显的“咔嗒”声。我自己可以重现这一点。

此外,我的用户抱怨说,有时候,声音根本没有播放,或者一直都是“沙哑”。我无法在开发中重现这一点,但我在自己的生产环境中已经听过这个。

我自己使用Windows Media和VLC播放了用户的wav文件,所以我知道文件没有损坏。我和NAudio一起使用它一定是个问题。

我的NAudio版本是v1.4.0.0。

这是我使用的代码。要设置调音台:

_mixer = new WaveMixerStream32 { AutoStop = false, };
_waveOutDevice = new WaveOut(WaveCallbackInfo.NewWindow())
{
    DeviceNumber = -1,
    DesiredLatency = 300,
    NumberOfBuffers = 3,
};
_waveOutDevice.Init(_mixer);
_waveOutDevice.Play();

令人惊讶的是,如果我在这里将“NumberOfBuffers”设置为2,我发现声音质量非常糟糕,每秒钟会发出几次声音“滴答声”。

要初始化声音文件,我这样做了:

var sample = new AudioSample(fileName);
sample.Position = sample.Length; // To prevent the sample from playing right away
_mixer.AddInputStream(sample);

AudioSample是我的班级。它的构造函数负责wav文件格式的“规范化”。它看起来像这样:

private class AudioSample : WaveStream
{
private readonly WaveChannel32 _channelStream;
public AudioSample(string fileName)
{
    MemoryStream memStream;
    using (var fileStream = File.OpenRead(fileName))
    {
        memStream = new MemoryStream();
        memStream.SetLength(fileStream.Length);
        fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length);
    }
    WaveStream originalStream = new WaveFileReader(memStream);
    var pcmStream = WaveFormatConversionStream.CreatePcmStream(originalStream);
    var blockAlignReductionStream = new BlockAlignReductionStream(pcmStream);
    var waveFormatConversionStream = new WaveFormatConversionStream(
        new WaveFormat(44100, blockAlignReductionStream.WaveFormat.BitsPerSample, 2), blockAlignReductionStream);
    var waveOffsetStream = new WaveOffsetStream(waveFormatConversionStream);
    _channelStream = new WaveChannel32(waveOffsetStream);
}

基本上,AudioSample委托给它的_channelStream对象。要播放AudioSample,我的代码将其“Position”设置为0.执行此操作的代码将编组到UI线程上。

这个几乎效果很好。我可以同时播放多个声音。不幸的是,如上所述,声音质量很差。任何人都可以帮我找出原因吗?

1 个答案:

答案 0 :(得分:4)

回答你的问题的一些要点:

  • 是的,在将它们送入调音台之前,您必须以相同的采样率进行所有输入。这就是数字音频的工作原理。 WaveFormatConversion流提供的ACM采样率转换并不精彩(没有别名保护)。您的输入文件通常采用什么样本率?
  • 您正在通过两个WaveFormatConversionStream传递每个输入。只有在绝对必要时才这样做。
  • 我很惊讶您使用NumberOfBuffers = 2获得了糟糕的声音,这现在是NAudio中的默认声音。你有没有暂停和恢复,因为有一个缓冲区可能被丢弃的错误(最新修复,将修复为NAudio 1.4 final)
  • 文件末尾的单击只表示它不会以零样本结束。你必须添加淡出来消除这种情况(许多媒体播放器会自动执行此操作)
  • 每当您对一个糟糕的声音问题进行故障排除时,我总是建议使用WaveFileWriter将您的WaveStream转换为WAV文件(注意不要生成永不停止的文件!),这样您就可以在另一个媒体播放器中收听它。这使您可以快速确定是导致问题的音频处理还是播放本身。