Java Sound API:从目标端口捕获声音输出
Posted
技术标签:
【中文标题】Java Sound API:从目标端口捕获声音输出【英文标题】:Java Sound API: Capturing sound output from a Target Port 【发布时间】:2010-05-19 22:28:37 【问题描述】:我正在编写一个通过 LAN 传输音频的简单软件。我已经实现了所有的网络部分,但我遇到的问题是使用 Java Sound API。我已成功从麦克风和线路输入中捕获音频,但我似乎无法从任何目标端口(例如扬声器)捕获音频。我的问题是,是否可以从主目标端口捕获?这是用于初始化该行的一段代码。
private boolean startCapture()
try
DataLine.Info info = new DataLine.Info( TargetDataLine.class, format);
line = (TargetDataLine)Audiosystem.getLine(info);
audioBuffer = new byte[bufferSize];
line.open(format);
line.start();
return true;
catch(Exception e)
System.out.println("Exception thrown when capturing audio:\n" + e);
return false;
像这样运行代码只会使用麦克风作为我的线路。 Here 是关于我的音响系统的信息。最重要的可能是我正在运行 Linux。
提前感谢您能给我的任何帮助。
【问题讨论】:
那么你成功了吗? 不。我永远无法直接访问我需要的东西。 所以你想从扬声器录制它? 是的,有点。我想以“你所听到的”方式录制音频。因此,我想要的 PCM 信号将发送到扬声器。我认为这是不可能的,至少在不使用 JNI 访问一些较低级别的库或其他东西的情况下是不可能的。 是的,它是..你只想要编程方式吗?? 【参考方案1】:网络声音的一个问题是,由于声卡时钟之间的差异,两端的计算机的采样率可能略有不同。计算机时钟各不相同。如果发送计算机的运行速度比接收计算机慢,那么即使您确实有缓冲区,您的缓冲区也会慢慢清空。如果它运行得更快,那么您将慢慢获得过多的数据。 This person 尝试了你正在做的事情并看到辍学。请注意,购买更昂贵的声卡会减少他的问题,但不能完全解决问题,除非他做一些事情,比如将它们锁定到 GPS 时间信号。一般的休闲用户不会这样做。
也许对于短传输,您可以摆脱它。例如,如果您正在做语音并且在扬声器安静时停止传输,那么您可以在重新开始时同步缓冲区。我想知道它会对延迟有什么影响。 “正确”的解决方案需要在接收端重新采样音频以处理采样率的细微差异。
对于如此小的频率变化,您可能会选择最近的邻居 - 有效地每隔一段时间跳过或复制样本。我听说过的数字业余无线电软件在样本之间使用线性插值。您需要维护一个缩放因子并对其进行控制,以确保您以新数据进入的速度清空缓冲区,但有一个控制循环不会因网络变幻莫测而过于不安,也不会尝试进行突然的大更改.
我不知道你是否考虑到了这一点。我见过有人尝试过,但没有。我除了现在人们会使用现成的音频会议库来处理这种事情。如果您对如何做到这一点感兴趣,那么数字业余无线电社区是一个不错的选择。
【讨论】:
这不是我考虑的问题。我很感激你的回复。我的这个副项目已经死了一段时间,因为我无法访问那个部分。我不太确定如何同步这两者,但您的解释对加深我的理解很有帮助。【参考方案2】:这是一种方式(不是程序化方式)。
转到:控制面板\硬件和声音\ 单击声音图标。现在转到录音,右键单击->选择两者-选择启用,断开设备。您将找到“立体声混音”图标。将其设为默认设备。
现在尝试录制声音。问题解决了。
【讨论】:
是的,这有效,但仅适用于 Windows。我需要跨平台兼容性。这就是它最初用 Java 编写的全部原因。【参考方案3】:演讲者是 SourceDataLine,而不是 TargetDataLine。我不明白你如何从演讲者那里“捕捉”?
【讨论】:
它仍然是调音台上的一个端口。我的理解是你仍然可以从混音器中得到它,然后它实际上是在送到扬声器的路上。必须有一种方法可以让数据流经该端口。以上是关于Java Sound API:从目标端口捕获声音输出的主要内容,如果未能解决你的问题,请参考以下文章
处理带有小数的字节数组后的 Java Sound API 噪声
Hololens官方教程精简版 - 06. Spatial sound(空间声音)