【发布时间】:2021-10-27 11:16:54
【问题描述】:
我正在创建一个应用程序,用于测试用户通过点击、鼠标点击/按钮按下等可以实现的节拍速度。
每次用户点击按钮时,我都会调用这个函数,beat();计算他们当前的 BPM 并用该 BPM 填充图形。我还想在最后计算一个平均值。请参阅下面我当前使用的代码。
我目前遇到的问题是,当用户点击时,BPM 到处都是,有时它是一致的,有时它是不准确的。查看我的代码让我感到困惑,因为我认为我实际上并没有在这里计算 BPM,或者至少不准确。
我还尝试在新旧 BPM 值之间添加 lerp,以平滑仪表,但似乎无法解决问题。
我在堆栈溢出中发现的最接近的问题是这个问题:Tap BPM code in Processing
但我仍然不确定这是否真的在准确计算用户 BPM。我非常感谢这里的一些帮助,特别是关于如何仅使用 2 个时间戳(一个旧节拍和一个新节拍)计算 BPM 背后的数学解释。
void beat()
{
if (beat0 == null)
{
beat0 = DateTime.Now;
return;
}
else if (beat1 == null)
{
beat1 = DateTime.Now;
}
else
{
beat0 = beat1;
beat1 = DateTime.Now;
}
if (beat0 != null && beat1 != null)
{
double delta = (beat1 - beat0).TotalSeconds;
double bpm = 60 / delta;
curBpm = (int)bpm;
if (oldBpm == -1)
{
oldBpm = curBpm;
return;
}
lerpBpm = (int)Mathf.Lerp(oldBpm, curBpm, (float)delta);
bpmText.text = lerpBpm.ToString();
FillGauge(lerpBpm);
oldBpm = lerpBpm;
}
}
【问题讨论】:
-
DateTime 对任何事情的计时都很糟糕;系统时钟的分辨率太粗。使用秒表。在一个数组中有一个小缓冲区,例如 5 个读数,使用递增计数器(圆形数组)的模数访问,该计数器在单击时为 1ups,并将经过的秒表存储在数组中。做读数的平均值(最大值减去最小值除以数组长度)并从该平均值计算 bpm 否则它将无处不在
-
您能否详细说明此评论,也许是在一个示例/一些伪代码的答案中?谢谢!
-
我问是因为我有点困惑;平均值 = 最大值 - 最小值 / 数组长度?不是平均数组/数组长度中所有数字的总和吗?
-
秒表不断计数,每次用户点击时,您都会将经过的时间存储在数组中,因此数组中的最大时间减去数组中的最小时间就是用户花费的时间最近的 5 次点击(如果它是一个 5 长的数组),didcide by 5 是点击之间的平均时间。如果将它们全部加起来,您将获得平均秒表读数,而不是从那时到现在的时间变化(您需要计算每分钟的点击次数。例如,每 1 秒 5 次点击是每分钟 300 次点击)
-
您询问如何计算 BPM。如果每拍有 100 毫秒,每分钟有 60000 毫秒,那么你可以在一分钟内适应 600 批 100 毫秒的间隔。一旦你有了 ms/b,你可以通过除以 ms/m 得到 b/m由 ms/b .. 在基本数学术语中
(ms/b) / (ms/m)与翻转 x/y 之一并将中间/更改为*相同。如果你翻转(ms/b) / (ms/m)所以它是(b/ms) * (ms/m)这是(b * ms) / (ms * m)然后两个ms和底部抵消只留下(b/m)即每分钟节拍
标签: c# datetime time logic lerp