简体   繁体   English

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

[英]Sound quality issues when using NAudio to play several wav files at once

My objective is this: to allow users of my .NET program to choose their own.wav files for sound effects.我的目标是:让我的 .NET 程序的用户选择他们自己的.wav 文件来获得音效。 These effects may be played simultaneously.这些效果可以同时播放。 NAudio seemed like my best bet. NAudio 似乎是我最好的选择。

I decided to use WaveMixerStream32.我决定使用 WaveMixerStream32。 One early challenge was that my users had.wav files of different formats, so to be able to mix them together with WaveMixerStream32, I needed to "normalize" them to a common format.一个早期的挑战是我的用户有不同格式的.wav 文件,因此为了能够将它们与 WaveMixerStream32 混合在一起,我需要将它们“标准化”为一种通用格式。 I wasn't able to find a good example of this to follow so I suspect my problem is a result of my doing this part wrong.我无法找到一个很好的例子来遵循,所以我怀疑我的问题是我做错了这部分的结果。

My problem is that when some sounds are played, there are very noticeable "clicking" sounds at their end.我的问题是,当播放某些声音时,结尾处会发出非常明显的“咔哒”声。 I can reproduce this myself.我可以自己重现这个。

Also, my users have complained that sometimes, sounds aren't played at all, or are "scratchy" all the way through.此外,我的用户抱怨说,有时声音根本没有播放,或者一直“刺耳”。 I haven't been able to reproduce this in development but I have heard this for myself in our production environment.我无法在开发中重现这一点,但我在我们的生产环境中亲耳听到了这一点。

I've played the user's wav files myself using Windows Media and VLC, so I know the files aren't corrupt.我自己使用 Windows Media 和 VLC 播放了用户的 wav 文件,所以我知道这些文件没有损坏。 It must be a problem with how I'm using them with NAudio.我如何将它们与NAudio一起使用一定是个问题。

My NAudio version is v1.4.0.0.我的 NAudio 版本是 v1.4.0.0。

Here's the code I used.这是我使用的代码。 To set up the mixer:要设置混音器:

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

Surprisingly, if I set "NumberOfBuffers" to 2 here I found that sound quality was awful, with audible "ticks" occurring several times a second.令人惊讶的是,如果我在这里将“NumberOfBuffers”设置为 2,我发现声音质量很糟糕,每秒会出现几次“滴答声”。

To initialize a sound file, I did this:为了初始化一个声音文件,我这样做了:

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

AudioSample is my class. AudioSample 是我的 class。 Its constructor is responsible for the "normalization" of the wav file format.它的构造函数负责 wav 文件格式的“规范化”。 It looks like this:它看起来像这样:

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);
}

Basically, the AudioSample delegates to its _channelStream object.基本上,AudioSample 委托给它的 _channelStream object。 To play an AudioSample, my code sets its "Position" to 0. This code that does this is marshalled onto the UI thread.为了播放 AudioSample,我的代码将其“Position”设置为 0。执行此操作的代码被编组到 UI 线程。

This almost works great.几乎效果很好。 I can play multiple sounds simultaneously.我可以同时播放多个声音。 Unfortunately the sound quality is bad as described above.不幸的是,如上所述,音质很差。 Can anyone help me figure out why?谁能帮我弄清楚为什么?

Some points in response to your question:回答您的问题的几点:

  • Yes, you have to have all inputs at the same sample rate before you feed them into a mixer.是的,在将它们输入混音器之前,您必须让所有输入具有相同的采样率。 This is simply how digital audio works.这就是数字音频的工作原理。 The ACM sample rate conversion provided by WaveFormatConversion stream isn't brilliant (has no aliasing protection). WaveFormatConversion stream 提供的 ACM 采样率转换并不出色(没有混叠保护)。 What sample rates are your input files typically at?您的输入文件通常采用什么采样率?
  • You are passing every input through two WaveFormatConversionStreams.您通过两个 WaveFormatConversionStreams 传递每个输入。 Only do this if it is absolutely necessary.只有在绝对必要时才这样做。
  • I'm surprised that you are getting bad sound with NumberOfBuffers=2, which is now the default in NAudio.我很惊讶您在 NumberOfBuffers=2 时声音变差,现在这是 NAudio 中的默认设置。 Have you been pausing and resuming, because there was a bug where a buffer could get dropped (fixed in the latest and will be fixed for NAudio 1.4 final)您是否一直在暂停和恢复,因为存在一个缓冲区可能被丢弃的错误(已在最新版本中修复,并将在 NAudio 1.4 最终版中修复)
  • A click at the end of a file can just mean it doesn't end on a zero sample.单击文件末尾可能意味着它不会以零样本结束。 You would have to add a fade out to eliminate this (a lot of media players do this automatically)您必须添加淡出来消除这种情况(很多媒体播放器会自动执行此操作)
  • Whenever you are troubleshooting a bad sound issue, I always recommend using WaveFileWriter to convert your WaveStream into a WAV file (taking care not to produce a never ending file,).每当您解决声音问题时,我总是建议使用 WaveFileWriter 将您的 WaveStream 转换为 WAV 文件(注意不要生成一个永无止境的文件)。 so you can listen to it in another media player, This allows you to quickly determine whether it is your audio processing that is causing the problem.这样您就可以在另一个媒体播放器中收听它,这使您可以快速确定是否是您的音频处理导致了问题。 or the playback itself.或播放本身。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM