在 C# 中使用 DirectX 进行无缝(循环)音频播放
Posted
技术标签:
【中文标题】在 C# 中使用 DirectX 进行无缝(循环)音频播放【英文标题】:Gapless (looping) audio playback with DirectX in C# 【发布时间】:2010-03-17 16:21:00 【问题描述】:我目前正在使用以下代码 (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 中无缝播放吗? 这没什么大不了的,因为它只是一个个人项目,但如果我做的事情很愚蠢或完全错误,我很想知道。
提前致谢。
【问题讨论】:
【参考方案1】:你的方法的问题是你有一个线程在旋转,检查玩家的位置。增加睡眠的时间越长,消耗的 CPU 越少,但它会越晚注意到剪辑的结束。睡眠时间越短,它会越快注意到,但检查器线程消耗的 CPU 越多。
我在文档中看不到任何东西告诉剪辑循环。我唯一的建议是使用 Audio.Ending 事件重新开始播放剪辑。这将消除对单独监控线程的需要,但我不确定这是否足够快以消除差距。
您还需要检查以确保您的音频剪辑不会以一段沉默开始或结束。
【讨论】:
【参考方案2】:既然你知道歌曲的时长,只需使用定时器定期调用你的“倒带”方法,并给定时器一个比实际歌曲时长略短的间隔。
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() 方法禁用它。
我希望这会对你有所帮助。 咒语
【讨论】:
以上是关于在 C# 中使用 DirectX 进行无缝(循环)音频播放的主要内容,如果未能解决你的问题,请参考以下文章
在 C# 中使用 DirectX11 和 SlimDX 的 Nvidia 3d 视频
使用 C#、DirectX 和 XNA 播放音频和最终用户的要求