【问题标题】:Syncing Two Metronomes In Java using Bluetooth for Android使用 Android 的蓝牙在 Java 中同步两个节拍器
【发布时间】:2015-12-23 20:53:26
【问题描述】:

我有一个独特的问题。我正在与我大学的其他几个计算机科学专业的学生合作开发一个 Android 节拍器应用程序,该应用程序允许两个用户使用该应用程序同步节拍器。现在,我可以将所需的节拍器每分钟节拍从一部手机发送到另一部手机,两部手机都将开始播放各自的节拍器。由于蓝牙的延迟,节拍器只有大约 20% 的时间同步。

所以,这就是问题所在。我们正在努力让两个节拍器同时启动。我想到的一种方法是,一旦第一个用户按下手机上的发送按钮,就会创建一个时间戳。该时间戳将恰好是用户按下发送按钮后的两秒。然后时间戳将发送到第二部手机,手机将利用此时间戳在与第一部手机相同的时间启动节拍器。我尝试通过将 UTC 时间放在一个 while 循环中然后不断检查时间来实现这一点,但无济于事。有没有人对我们如何实现这一点有任何想法?我在 StackOverflow 或任何其他网站上找不到任何类似的问题。

【问题讨论】:

  • 重复问题解决了不同应用程序中的相同基本问题。最好的办法是实现 NTC 客户端并确定 NIST 与系统时间的偏移,然后使用它来解决任何抖动。我用同样的方法让两台设备同步视频/音频播放,你可以在5-10ms内得到准确,这对于音频来说似乎足够了。忘记 GPS 时间,对我来说,它总是返回系统时间。

标签: java android bluetooth


【解决方案1】:

您的项目可能有点晚了,但如果有兴趣。这有点长,更像是一个案例研究。 如果您的项目是关于远程同步两个设备时钟,那么这对您没有帮助,但如果它是关于同步节拍器,那么这可能是一个开始。

首先,使用 java 在 android 中获得毫秒精确的计时和回调几乎是不可能的,因为 android 不是实时系统(所有睡眠方法和计时器可能不会在您期望的精确毫秒上执行)。您可能希望使用 NDK 来触发节拍事件,因为 android 中的原生线程可以实现这一点,但如果您对单个节拍器的实现感到满意,那么阅读其余部分就足够了。

全面披露: 我是JAM我几天前刚刚发布的答案中引用的应用程序的作者。

我在开发应用程序时遇到了同样的问题。 这个答案是否对你有帮助,取决于你的情况。 如果您要走“时钟同步”路线(我确实计划探索这条路线,以通过更多功能改进我的应用程序),但我发现的解决方案不涉及时间同步。

我会提到我的方法,然后说明我发现的每种方法的优点/缺点。

我选择了订阅/发布模型,而不是同步时钟(这是一个非常困难的问题,尤其是对于应用程序应该做的事情,那就是在“同一”时间触发多个设备上的滴答声)我选择了订阅/发布模型,其中多个设备可以通过蓝牙“订阅”主机设备,主机设备控制和“发布”节拍器节拍。

大多数时候通过蓝牙发送几百个字节(关于每个节拍的足够信息)需要不到 2 毫秒,它可能会飙升至 10 有时甚至 30,但这似乎很少发生。 这种方法解决了同步问题,现在我可以在 2ms 内将节拍事件从一个设备发送到另一个设备,如果发生某种延迟,一旦干扰消失,它将自我纠正,因为另一个事件及时到来。

但是,这种方法确实需要持续连接,您无法在以后启动和分离设备,但实施起来要容易得多。

现在有趣的部分是我在开始时从未想过的问题,那就是Android 10 millisecond audio path latency 问题。我不隶属于 superpowered,但我确实在我的应用程序中使用了他们的引擎来处理这个问题。

总结一下: Android 中通过蓝牙进行节拍器同步有两个问题:
1 - 同时触发节拍事件(或在可接受的延迟内)
2 - 节拍事件应在收到节拍事件后以最小延迟触发声音事件

#1 与原始问题有关,#2 我认为是对原始问题的重要补充。

【讨论】:

    【解决方案2】:

    我会使用(S)NTP 来检查时钟漂移到公共时间服务器。之后,我只需发送间隔和开始时间,让设备单独计算间隔。因此,您只需要同步更改并中继各个设备的时钟。结合现在已知的时钟漂移,您可以修复此错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-01
      • 2012-04-19
      • 1970-01-01
      • 1970-01-01
      • 2013-08-09
      • 1970-01-01
      • 2018-03-09
      相关资源
      最近更新 更多