首页 > 解决方案 > Naudio C#:如何准确地将秒表与音频播放进度同步?

问题描述

我正在开发一个节奏游戏,这意味着我希望屏幕元素显示在节拍中。为此,我需要能够分辨出我目前在音乐时间线上的哪个位置。我正在使用 Naudio 库(更具体地说是 ASIO),并且我知道我可以调用我当前正在播放的CurrentTime字段,WaveStream以了解自音乐开始播放以来已经过去了多少时间,但是该字段似乎没有非常准确(至少不够准确,无法流畅地显示移动的屏幕元素),因为它只是基于每秒平均字节数的近似值。这就是为什么我尝试将 aStopWatch与音乐同步。但是,无论我尝试什么,我总是会得到一个偏移量。我当前的设置是这样的:

var audioFileReader = new AudioFileReader("music.mp3");
var waveChannel32 = new WaveChannel32(audioFileReader); //
var asioOut = new AsioOut(0);
var stopWatch = new Stopwatch();
asioOut.Init(waveChannel32);
asioOut.Play();
Task.Delay(1000).Wait();
waveChannel32.Position = 0;
stopWatch.Start();

如果我然后与它进行比较stopWatch.ElapsedwaveChannel32.CurrentTime它看起来stopWatch就在现场(它会在∓10ms左右跳跃,因为后者不准确,但平均而言它们大致相等。如果我将它与其他节奏游戏的文件进行比较(那个注释时间戳记节拍踢),我的StopWatch结果是提前 50∓25 毫秒。现在有人可能会争辩说文件可能不准确,或者其他节奏游戏有偏移,但在检查了几场比赛中的无数文件后,我觉得可以这么说我已经排除了这个。

是什么导致了我的偏移,我该如何解决?

编辑:

我正在测量这样的偏移量:每当我按下一个键时,我都会播放一个咔哒声(在节奏游戏中称为“hitsount”),然后随着歌曲的标签尝试同步而不是我的键盘输入,将产生的 hitsound 与节拍和测量我的平均偏移量。这样我就不需要考虑硬件和音频驱动程序的延迟。当然,我不是机器人,因此并不完全准确,但我的不准确性通常会传播,所以我可以取平均值,即使没有,我至少也足够准确,能够判断出问题所在。

标签: c#naudio

解决方案


推荐阅读