Java Sound API实现多通道USB录音?

45

我正在尝试使用Java Sound在Snow Leopard上从三个USB麦克风录制/处理音频(但如果切换到Windows可能会修复问题)。问题是,当我尝试使用对应于USB麦克风的混音器时,Java Sound告诉我该线路不受支持。具体来说,它会说...

可用混音器:

Java Sound音频引擎

USBMIC序列号#041270067

内置输入内置麦克风

Soundflower(2ch)

Soundflower(16ch)

异常线程"AWT-EventQueue-0" java.lang.IllegalArgumentException: 线路不支持:接口 TargetDataLine支持格式 PCM_SIGNED 96000.0 Hz,8位,立体声, 2字节/帧,

...当我要求它选择USBMIC混音器时。

  Mixer mixer = AudioSystem.
          getMixer(mixerInfo[1]);

我已经尝试将音频格式与麦克风的确切规格匹配(16位,44100Hz,立体声),但没有任何区别。

问题出现在这里:

 final TargetDataLine line = (TargetDataLine)
        mixer.getLine(info);
似乎混音器和TargetDataLine不兼容。有没有办法让它们“匹配”并和谐相处?
我使用的麦克风确实有点奇怪。它们是为卡拉OK视频游戏SingStar设计的。麦克风本身带有标准的单声道线入连接器,插入一个小集线器(每个集线器两个),将它们转换为单个男性USB连接器。尽管有点奇怪,但它们在Audacity中作为独立通道可以正常工作,因此多通道录音显然是可能的,只是在Java中可能不行。
我还考虑使用像Soundflower这样的程序,在不同的程序之间共享音频。但是,我不确定这是否有效,因为我不知道如何使USB麦克风输入到Soundflower,然后将它们导入Java。一个快速的实验向我展示,我可以从麦克风中在Audacity中记录音频,通过Soundflower将其输出,然后在我的Java程序中处理。尽管如此,我仍然想在Java中实现实时处理。
有人熟悉这种问题吗?

哦...Audacity 只能同时从一个设备录制吗?这就是你所做的吗? - Sharun
我不会指望Java声音API在更复杂的情况下是正确的。您可以使用第三方Java程序来验证问题是否不在JRE级别吗?或者使用更新的JRE?在Windows上,USB音频设备驱动程序也有点贫乏。 - jbarlow
我已经有几年没涉及声音了..不过这可能会有所帮助:每个声音设备都有自己的内部时钟。当然也有例外,你会在音频卡/设备上看到这些时钟输入。那些运行在自己时钟上的设备会逐渐失去同步。它们在录制开始时可能是同步的,但由于采样速率略有不同,因此会出现漂移。录制的音频时间越长,漂移就越明显。 - Dan
3个回答

4
我认为一个简单的方法是使用Soundflower和Soundflowerbed。
我不知道如何将USB麦克风输入到Soundflower,然后将它们导入Java。
听起来你已经安装了Soundflower。Soundflowerbed在与Soundflower相同的磁盘映像中找到,并且是一个菜单栏应用程序。它可以让你在没有内置控件来选择声音设备的应用程序之间路由声音。从磁盘映像中安装它并单击运行即可。
以下所有操作都将使用我的Echo Audiofire 4,但原则上适用于任何音频设备。
使用Soundflowerbed
打开Soundflower并在Soundflower(16ch)下勾选您想要使用的音频设备。由于我是新用户,无法发布图片,但它们在下面链接。如果我获得赏金,那么我将编辑帖子以包含内联图像。
从这里开始,您将在Java声音中使用Soundflower(16ch)作为音频输入设备。
创建聚合音频设备
如果这种方法不起作用,则解决此问题的另一种替代方法是创建聚合设备。打开Applications> Utilities> Audio Midi Setup并单击加号以创建新的聚合设备。
勾选要聚合的设备。您只需要USBMIC(由于我是新的SO用户,因此每个答案只能发布两个图像,因此下面的两个图像都链接在此处)。
可能给您带来麻烦的关键部分是设备上的时钟。如果选择Mac作为时钟源,则可能更稳定。
如果仍然无法正常工作,则可以尝试将Mac内置音频添加到聚合设备中,并通过右键单击要成为主设备的设备来使其成为主时钟。
其他选项
最后,我以前没有使用过这个,但Pulse Audio(Google它,我无法在此帖子中插入更多链接)可能是混合音频流的可能解决方案。看起来相当沉重。

感谢您的出色努力,Daniel Campton。问题是在2010年提出的,所以提问者可能无法验证您的答案。但是,如果您可以确认(并可能讨论甚至给出Java示例),声音录制设备现在可用/可用于Java音频API,那么我将授予您赏金。(显然,如果提问者选择您当前的答案,则赏金属于您) - Shivan Dragon
很不幸,我对Java音频API一点也不熟悉,因此无法提供更多关于它如何工作的细节。我已经查看了Java音频API,但是我没有找到如何更改音频输入源的方法。如果我有最初提问者选择USB麦克风的代码,那么我可能可以从中着手解决问题。 - Daniel Compton

2
根据我的研究,特别是像这个帖子所说的那样,你正在使用的麦克风很可能是引起问题的罪魁祸首。该帖子指出,即使在切换游戏时,麦克风也会成为一个问题,因此我猜想在切换平台时也会遇到问题。
我的建议是-如果您没有尝试过-请使用不同的麦克风!我玩弄过的大多数麦克风都有特殊的芯片控制器,可以将数据转换为适用于游戏系统的数据。由于您正在计算机操作系统上使用它,所以您可能会得到一些非常奇怪的效果,在Playstation或其他游戏系统上不会出现这些效果。
希望这可以帮助您!快乐编码!

0
AudioFormat与TargetDataLine支持的格式不匹配。我不知道那是不是一个打字错误,但抛出的异常说TargetDataLine支持8位音频,而在下面你又说你正在使用16位的AudioFormat。它还支持每帧最多2个字节,你尝试以多快的速度和以什么大小的块读取数据?如果这没有帮助,我很抱歉,但我想指出这一点以防被忽视。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接