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

因此,这就是问题所在。我们正在努力使两个节拍都在同一时间开始。我想到的一种方法是,一旦第一个用户按下手机上的发送按钮,就会创建一个时间戳。用户按下发送按钮后,此时间戳记将恰好是两秒钟。然后,时间戳将被发送到第二部手机,并且该手机将利用该时间戳在与第一部手机相同的确切时间启动节拍器。我试图通过将UTC时间置于while循环中,然后不断地检查时间来实现这一点,但没有用。是否有人对我们如何实现这一目标有任何想法?我在StackOverflow或其他任何网站上都找不到类似的问题。

最佳答案

对于您的项目来说可能有点晚了,但是如果有兴趣的话。这有点长,更像是一个案例研究。
如果您的项目是要远程同步两个设备时钟,那么这将无济于事,但如果要同步节拍,则可能是一个开始。

首先,几乎不可能使用Java在android中获得毫秒级的精确计时和回调,因为android并非实时系统(所有sleep方法和计时器都可能不会在您期望的毫秒级上执行)。您可能想使用NDK来触发您的心跳事件,因为android中的本机线程可以实现这一点,但是如果您对单个节拍器实现感到满意,那么足以阅读其余内容。

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

开发应用程序时遇到了同样的问题。
以及此答案是否会帮助您,具体取决于您的情况。
并且如果您采用的是“时钟同步”路线(我确实打算探索此路线来改进我的应用,以提供更多功能),但我发现的解决方案不涉及时间同步。

我将提及自己的方法,然后陈述每种方法的优缺点。

我选择了一种订阅/发布模型,其中多个设备可以“订阅”,而不是同步时钟(这是一个非常棘手的问题,尤其是对于应用程序应做的事情,即在“相同”时间触发多个设备的滴答声)。通过蓝牙发送到主机设备,然后主机设备控制并“发布”节拍器节拍。

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

但是,该方法确实需要不断的连接,您以后无法启动和分离设备,但是实现起来要容易得多。

现在有趣的部分是开始时我从未想到的问题,那就是Android 10 millisecond audio path latency问题。我与超级动力无关,但是我确实在我的应用程序中使用了它们的引擎来解决该问题。

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

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

08-26 04:22