我已经通过了the tutorials for the Java Sound API,并且我已经成功地从麦克风中读出了数据。
现在我想更进一步,从麦克风阵列中的多个麦克风(如PS3 Eye或Respeaker)同步获取数据。
我可以为每个麦克风获取一个TargetDataLine,并打开/启动/写入缓冲区的输入--但我不知道如何这样做才能获得数据,然后我可以按时间排列(我想最终做波束成形)
当从像ALSA这样的东西读取时,我会同时从不同的麦克风中获得字节,所以我知道每个麦克风中的每个字节都来自相同的时刻--但是Java Sound API似乎有一个使这个b/c变得模糊的限制-你只是从单独的行缓冲区中转储/写入数据并处理它,并且每行都是单独执行的。您不会一次与整个设备/麦克风阵列交互
然而,我发现有人成功地在Java with the Kinect 1.0中进行了波束成形,所以我知道这应该是可能的。问题是秘密调料在.jar中的自定义Mixer对象中,该对象是从其他软件中提取的。所以我没有任何简单的方法来弄清楚他们是怎么做到的
发布于 2019-08-21 18:04:38
只有在底层硬件驱动程序支持的情况下,您才能将来自多个源的数据与时间同步精度对齐以执行波束成形。
如果底层硬件为您提供多个同步的数据流(例如,在两个声道中录制-在立体声中),那么您的阵列数据将是时间同步的。
如果你依赖于操作系统为你提供两个独立的流,那么也许你可以依赖于时间戳。你得到第一个元素的时间戳了吗?如果是这样,那么您可以根据您的采样率通过删除样本来重新对齐数据。可能有一个最终的差异(δ-t),您将在您的波束形成算法中考虑到这个因素。
阅读有关PS3 Eye (它有一个麦克风阵列)的内容时,如果音频驱动程序一次提供所有通道,您将能够做到这一点。
对于Java来说,这可能意味着“你能用包含4个通道的AudioFormat打开通道吗?”如果是,那么你的样本将包含多个帧,解码的帧数据将(几乎肯定)是时间对齐的。引用Java docs的话:“一个帧包含特定时间所有通道的数据”。
发布于 2019-08-22 02:35:00
IDK什么是“波束成形”,但如果有硬件可以提供同步,那么使用它显然是最好的解决方案。
这里,无论它是什么,都应该是一种合理的管理同步的算法方法。
(1)为每个TargetDataLine设置一个帧计数器。作为此过程的一部分,您必须将字节转换为PCM。
(2)设置一些代码来监控每条线路上的音量水平,我假设是某种RMS算法,用于PCM数据。
(3)创建同时到达每个麦克风的响亮的瞬时脉冲串,RMS算法能够检测到的脉冲串,并给出起始帧的计数。
(4)根据需要调整帧计数器,并在传入数据的每一行上引用它们。
基本原理: Java不提供实时保证,这在这篇关于real-time, low latency audio processing的文章中解释过。但根据我的经验,字节数据和时间(根据采样率)之间的对应关系在最接近Java与外部音频服务接口的线路上非常准确。
在不漂移的情况下,帧计数的准确性能保持多久?我从来没有做过任何测试来研究这个问题。但在实践层面上,我已经编写了一个完全令人满意的基于帧计数的“音频事件”调度器,用于通过实时合成播放多声部乐谱(全部使用Java完成),并且对于尝试的最长乐曲(长度为6-7分钟)来说,时间是无可挑剔的。
https://stackoverflow.com/questions/57586408
复制相似问题