使用DirectX在C#中进行无缝(循环)音频播放

时间:2010-03-17 16:21:01

标签: c# audio directx

我目前正在使用以下代码(C#):

    private static void PlayLoop(string filename)
    {
        Audio player = new Audio(filename);
        player.Play();
        while (player.Playing)
        {
            if (player.CurrentPosition >= player.Duration)
            {
                player.SeekCurrentPosition(0, SeekPositionFlags.AbsolutePositioning);
            }
            System.Threading.Thread.Sleep(100);
        }
    }

此代码有效,我正在播放的文件正在循环播放。但是,很明显,每次播放之间存在小的差距。

  • 我尝试减少Thread.Sleep它到10或5,但差距仍然存在。
  • 我也试过完全删除它,但随后CPU使用率提高到100%并且还有一个小差距。

是否有任何(简单)方法在DirectX中进行无间隙播放?这不是什么大问题,因为它只是个人项目,但如果我做了一些愚蠢或完全错误的事情,我我很想知道。

提前致谢。

2 个答案:

答案 0 :(得分:2)

你的方法的问题是你有一个线程旋转,检查播放器的位置。你增加睡眠的时间越长,它消耗的CPU越少,但是它会越晚注意到剪辑的结束。睡眠时间越短,它就越快注意到但是你的检查线程消耗的CPU越多。

我无法在文档中看到任何内容告诉剪辑循环。我唯一的建议是使用Audio.Ending事件重新开始播放剪辑。这将消除您对单独监控线程的需求,但我不确定这是否足够快以消除差距。

您还需要检查以确保您的音频剪辑不会以一段时间的静音开始或结束。

答案 1 :(得分:0)

由于您知道歌曲的持续时间,因此只需使用计时器定期呼叫您“倒带”方法,并为计时器提供比实际歌曲持续时间短的间隔。

private static void PlayLoop(string filename)
{
    Audio player = new Audio(filename);
    player.Play();

    //System.Timers.Timer (i reduce the length by 100 ms to try to avoid blank)
    var timer = new Timer((player.Duration - TimeSpan.FromMilliseconds(100)).TotalMilliseconds());
    timer.Elapsed += (sender, arg) =>
    {
        player.SeekCurrentPosition(0, SeekPositionFlags.AbsolutePositioning);
    };
    timer.Start();
}

当然,您需要停止计时器,使其成为实例成员而不是方法的局部变量,因此您可以使用Stop()方法禁用它。

我希望这会对你有所帮助。 Manitra