当我的游戏中 CPU 使用率达到峰值时,为啥我的 NAudio 音乐会冻结?

Posted

技术标签:

【中文标题】当我的游戏中 CPU 使用率达到峰值时,为啥我的 NAudio 音乐会冻结?【英文标题】:Why does my NAudio music freeze when CPU usage spikes in my game?当我的游戏中 CPU 使用率达到峰值时,为什么我的 NAudio 音乐会冻结? 【发布时间】:2015-06-21 13:45:14 【问题描述】:

我正在编写游戏并尝试使用 NAudio 播放音乐和音效,但是当游戏使用大量 CPU 时,音乐会卡住。我尝试在单独的线程中运行音乐,但这似乎没有帮助。如何防止音乐冻结?

这是我的音乐播放代码:

        // (code to select a track goes here)

        // prepare the new track
        var tl = trackname.ToLower();
        var path = Path.Combine("Music", trackname);
        IWaveProvider p;
        if (tl.EndsWith("ogg"))
            p = new VorbisWaveReader(path);
        else if (tl.EndsWith("mp3"))
            p = new Mp3FileReader(path);
        else if (tl.EndsWith("wav"))
            p = new WaveFileReader(path);
        else
            throw new Exception("Unknown audio format for file " + path);
        waveout.Stop();
        if (CurrentMode == MusicMode.None)
            return; // no music!

        // fade between the two tracks
        prevTrack = curTrack;
        if (prevTrack != null)
            prevTrack.BeginFadeOut(FadeDuration);
        curTrack = new FadeInOutSampleProvider(p.ToSampleProvider(), true);
        curTrack.BeginFadeIn(FadeDuration);

        // start playing
        // TODO - start fade of new track even before old track is done?
        if (prevTrack != null)
            waveout.Init(new MixingSampleProvider(new ISampleProvider[]  curTrack, prevTrack ));
        else
            waveout.Init(curTrack);
        waveout.Play();
        waveout.PlaybackStopped += waveout_PlaybackStopped;

【问题讨论】:

prevTrack 和 curTrack 是 FadeInOutSampleProvider 的实例。 【参考方案1】:

WaveOut 是什么类型?使用WaveOutEvent 将在后台线程上播放音频。

另外,在同一个 WaveOut 实例上第二次调用 WaveOut.Init 不是 NAudio 官方支持的,可能会导致奇怪的事情发生。

提高音频性能的主要方法有:

    以更高的延迟运行 尽量减少音频引擎需要做的工作(例如,将音频从自定义格式预解压为 PCM 并将其存储在内存中)

对于您的场景,最好的办法可能是创建一个自定义的交叉淡入淡出示例提供程序。不幸的是,目前 NAudio 中还没有,但对于未来的博客文章/代码示例来说这是一个好主意,所以我会把它放在要写的东西列表中。

【讨论】:

waveOut 只是 WaveOut 的一个静态实例。每次我想播放一个新的音频文件时,我都应该创建一个新的吗?我认为这样做会很浪费,因为无论如何我只玩一个波浪设备! :) 是的,用 WaveOutEvent 实例替换 WaveOut 的实例似乎已经成功了!我想知道这两个课程有什么意义? 他们只是使用不同的回调模型。 WaveOutEvent 是我有一天由于其他回调的问题而创建的一个快速实验,但它已被证明是最可靠的选项之一。希望我能给它一个更好的名字!

以上是关于当我的游戏中 CPU 使用率达到峰值时,为啥我的 NAudio 音乐会冻结?的主要内容,如果未能解决你的问题,请参考以下文章

当我的 Web 应用程序空闲时,独立的 tomcat 9 每 10 秒将 CPU 峰值提高到 50%

SqlDataAdapter.Fill 命令使 SQL CPU 达到峰值

为啥我的电脑用了一会CPU使用率就达到100%

当我添加游戏循环时,为啥我的 Java 游戏会崩溃?

有人能告诉我为啥当我的游戏中的相机移动时一切都会振动吗?

为啥使用 gprof 会阻止程序的执行?