流式传输音乐时CPU贪婪循环

时间:2014-10-20 17:22:06

标签: c# performance audio-streaming

为了给出一些背景知识,我正在开发一个开源替代桌面Spotify客户端,其核心是可访问性。你还会在这里看到一些NAudio。

一旦播放开始,我就会注意到相当强烈的CPU使用率。即使暂停,CPU也很高。

我运行了Visual Studio的内置分析器,试图揭示可能发生的任何资源生长。我怀疑,问题出在我的播放管理器的流媒体循环中。

探查器标记为样本丰富度最高的代码如下:

const int secondsToBuffer = 3;

    private void GetStreaming(object state)
    {
        this.fullyDownloaded = false;
        // secondsToBuffer is an integer to represent how many seconds we should buffer up at once to prevent choppy playback on slow connections

        try
        {
            do
            {
                if (bufferedWaveProvider == null)
                {
                    this.bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat(44100, 2));
                    this.bufferedWaveProvider.BufferDuration = TimeSpan.FromSeconds(20); // allow us to get well ahead of ourselves
                    Logger.WriteDebug("Creating buffered wave provider");
                    this.gatekeeper.MinimumSampleSize = bufferedWaveProvider.WaveFormat.AverageBytesPerSecond * secondsToBuffer;
                }
                // this bit in particular seems to be the hot point
                if (bufferedWaveProvider != null && bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes < bufferedWaveProvider.WaveFormat.AverageBytesPerSecond / 4)
                {
                    Logger.WriteDebug("Buffer getting full, taking a break");
                    Thread.Sleep(500);
                }
                // do we have at least double the buffered sample's size in free space, just in case
                else if (bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes > bufferedWaveProvider.WaveFormat.AverageBytesPerSecond * (secondsToBuffer * 2))
                {
                    var sample = gatekeeper.Read();
                    if (sample != null)
                    {
                        bufferedWaveProvider.AddSamples(sample, 0, sample.Length);
                    }
                }
            } while (playbackState != StreamingPlaybackState.Stopped);
            Logger.WriteDebug("Playback stopped");
        }
        finally
        {
            // no post-processing work here, right?
        }
    }

NAudio样本是我用这种方法处理流媒体的方式的灵感来源。要查找完整文件的源代码,您可以在此处查看:http://blindspot.codeplex.com/SourceControl/latest#Blindspot.Playback/PlaybackManager.cs

我是分析的新手,而且我也不是年度流媒体专家(两者都可能很明显)。

有什么办法可以让这个循环不那么耗费资源。会增加缓冲区满的if块中的睡眠量吗?或者我在这里咆哮错误的树。它似乎会,但我认为半秒就足够了。

感激不尽的任何帮助。

1 个答案:

答案 0 :(得分:0)

基本上,您已经创建了一个无限循环,直到缓冲区变满为止。您标有

的部分
// this bit in particular seems to be the hot point

可能看起来像if语句中的计算只是一遍又一遍地重复;可以将它们中的任何一个移到循环之外吗?

我在while语句之前放了一个Thread.Sleep(50)来防止颠簸,看看是否有所不同(我怀疑它会有所不同)。