简体   繁体   English

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

[英]Gapless (looping) audio playback with DirectX in C#

I'm currently using the following code (C#): 我当前正在使用以下代码(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);
        }
    }

This code works, and the file I'm playing is looping. 此代码有效,并且我正在播放的文件正在循环播放。 But, obviously, there is a small gap between each playback. 但是,显然,每次播放之间都存在很小的差距。

  • I tried reducing the Thread.Sleep it to 10 or 5, but the gap remains. 我尝试将Thread.Sleep减小为10或5,但差距仍然存在。
  • I also tried removing it completely, but then the CPU usage raises to 100% and there's still a small gap. 我还尝试将其完全删除,但是随后CPU使用率提高到100%,并且仍然存在很小的差距。

Is there any (simple) way to make playback in DirectX gapless? 有什么(简单的)方法可以使DirectX中的播放畅通无阻? It's not a big deal since it's only a personal project, but if I'm doing something foolish or otherwise completely wrong, I'd love to know. 没什么大不了的,因为它只是一个个人项目,但是如果我做的事愚蠢或完全错误,我很想知道。

Thanks in advance. 提前致谢。

The problem with your approach is that you have a thread spinning, checking the position of the player. 方法的问题是您正在旋转线程,请检查播放器的位置。 The longer you increase your sleep, the less CPU it drains but the later it will notice the end of the clip. 您增加睡眠的时间越长,消耗的CPU越少,但注意片段结束的时间就越晚。 The shorter the sleep, the quicker it will notice but the more CPU your checker thread consumes. 睡眠时间越短,它将注意到的越快,但是检查线程消耗的CPU越多。

I can see nothing in the docs to tell the clip to loop. 我在文档中看不到任何告诉剪辑循环的内容。 The only suggestion I have is to use the Audio.Ending event to start the clip playing again. 我唯一的建议是使用Audio.Ending事件再次开始播放剪辑。 This will remove the need for your separate monitoring thread but I am not sure whether this will be quick enough to eliminate the gap. 这将消除对您单独的监视线程的需要,但是我不确定这是否足够快来消除差距。

You will also want to check to ensure your audio clip does not begin or end with a period of silence. 您还需要检查以确保您的音频剪辑没有以静默期开始或结束。

Since you know the duration of the song, just use a timer to regularly call you "rewind" method and give the timer an interval sligthly shorter than the real song duration. 由于您知道歌曲的持续时间,因此只需使用计时器定期调用“倒带”方法,并给计时器指定一个比实际歌曲持续时间短的间隔即可。

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

Of course, you'll need to stop the timer so make it an instance member instead of a local variable of your method, so you can disable it with a Stop() method. 当然,您需要停止计时器,因此使其成为实例成员而不是方法的局部变量,因此可以使用Stop()方法禁用它。

I hope this will help you. 我希望这能帮到您。 Manitra 马尼特拉

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

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