Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用NAudio同时播放多个wav文件时出现音质问题_C#_Audio_Naudio - Fatal编程技术网

C# 使用NAudio同时播放多个wav文件时出现音质问题

C# 使用NAudio同时播放多个wav文件时出现音质问题,c#,audio,naudio,C#,Audio,Naudio,我的目标是:允许我的.NET程序的用户选择自己的.wav文件进行声音效果。这些效果可以同时播放。NAudio似乎是我最好的选择 我决定使用WaveMixerStream32。早期的一个挑战是,我的用户拥有不同格式的.wav文件,因此为了能够将它们与WaveMixerStream32混合在一起,我需要将它们“规范化”为通用格式。我没能找到一个好的例子,所以我怀疑我的问题是我做这部分错误的结果 我的问题是,当播放某些声音时,末端会有非常明显的“咔哒”声。我可以自己复制这个 此外,我的用户还抱怨说,有

我的目标是:允许我的.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);
音频样本是我的班级。其构造函数负责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对象。要播放音频样本,我的代码将其“位置”设置为0。执行此操作的代码被封送到UI线程


这几乎非常有效。我可以同时播放多种声音。不幸的是,如上所述,音质很差。有人能帮我找出原因吗?

回答您的问题时有几点:

  • 是的,在将所有输入输入输入混频器之前,必须使其具有相同的采样率。这就是数字音频的工作原理。波形转换流提供的ACM采样率转换并不出色(没有混叠保护)。您的输入文件的采样率通常是多少
  • 您正在通过两个波形转换流传递每个输入。只有在绝对必要时才这样做
  • 我很惊讶NumberOfBuffers=2的声音不好,这是NAudio中的默认值。您是否一直在暂停和恢复,因为存在一个可能会丢弃缓冲区的错误(最新修复,NAudio 1.4决赛将修复)
  • 在文件末尾单击可能意味着它不会在零样本上结束。您必须添加淡出以消除此问题(许多媒体播放器会自动进行此操作)
  • 每当你在解决一个糟糕的声音问题时,我总是建议你使用WaveFileWriter将你的WaveStream转换成一个WAV文件(注意不要产生一个永无止境的文件!),这样你就可以在另一个媒体播放器中收听它。这允许您快速确定是您的音频处理导致了问题,还是播放本身造成了问题

马克,非常感谢你的回复!我不是数字音频方面的专家,但我会尽可能理智地回答您的问题#1我的用户使用的wav文件的采样率分别为11025、22000和32000 Hz(至少,它们不在我的控制范围内)。我想我需要两个WaveFormatConversionStream-s,第一个用于处理具有可变速率编码的文件,第二个用于处理使它们都达到相同速率的文件。我很想知道我做错了:)我不确定我是否在使用最新的v1.4 NAudio;版本是1.4.0.0。其md5为8e5ee2282342b87fa489beda9c6140b0。我会试着用最新的,看看有没有区别。您建议添加淡出是有道理的;你知道NAudio做这件事的好例子吗?我也会四处看看。我真的很感谢您的WaveileWriter推荐。我查看了v1.4RC的MD5,可在上获得,它是一样的。如果不需要CreatePcmStream函数,它实际上会直接返回它的输入参数,但是第二个,只有在输入不是44.1kHz时才应该这样做。1.4RC是最新版本。如果愿意,可以下载SourceControl中的内容。我正在研究一种更简单的方法来构建32位浮点音频管道。我目前正在为WPF项目添加一个滚筒机样本,一旦完成,它将作为一个混合演示。我还没有写一个淡出的例子,但可能会考虑添加一个NooD1.5,我想我有三件事要尝试:下载最新的NoDead源,看看这是否允许我使用NoMuffFuffs=2;在转换后的流中添加淡出,看看是否消除了结束时的“咔嗒”声;使用WaveFileWriter将转换后的流转储到新的wav文件中,并在外部播放器中确认转换达到了我预期的效果。我就这么做!