使用 Java API 将声音输入链接到特定输出设备

Link sound input to specific output device with java api

提问人:Manticore 提问时间:12/6/2022 更新时间:12/8/2022 访问量:102

问:

我正在尝试执行一个简单的任务,选择一个输入设备并设置输出设备。

用例如下,我有 3.5 毫米插孔,我的用户可以从列表中选择输出设备(耳机或扬声器)。

我可以在给定的设备(带剪辑)上播放声音,我可以控制输入设备(静音/音量),但我还没有找到任何指定目标线路的方法,它始终是系统默认值。

我可以得到混音器

Optional<Mixer.Info> optJackInMixerInfo = Arrays.stream(AudioSystem.getMixerInfo())
        .filter(mixerInfo -> {
            // Filter based on the device name. 
        })
        .findFirst();
Mixer m = AudioSystem.getMixer(jackInMixerInfo);

目标

Line.Info[] lineInfos = m.getTargetLineInfo();
for (Line.Info lineInfo : lineInfos) {
  m.getLine(lineInfo);
  System.out.println("ici");
}

我只有“主音量控制”。

如何选择输出设备?我也可以对更改系统默认设备感到满意。

java windows javasound

评论


答:

0赞 Phil Freihofner 12/8/2022 #1

和的命名有点倒退。输出到本地音响系统进行播放,而输入到 Java 就像麦克风线路使用 .我曾经知道为什么它们被这样命名,但现在我的脑海里已经忘记了。TargetDataLineSourceDataLineSourceDataLineTargetDataLine

有一个教程访问音频系统资源,其中包含详细信息。

大多数计算机只有有限数量的浮点控件可用,“主音量”是最有可能实现的控件。您可以使用它来更改输出的音量。本系列中的另一个教程“使用控件处理音频”介绍了此主题。就我自己而言,我通常将音频流转换为 PCM 并直接处理音量(将每个值乘以 0 到 1 之间的系数),然后转换回字节流,而不是依赖可能存在也可能不存在的控件。

评论

0赞 Manticore 12/12/2022
我想我理解这个 API 的奇怪命名......至少足以控制设备。我已经阅读并测试了您提供的文档。我的问题实际上是如何将一行重定向到另一行,因为我可以分别控制两者。我想到了重新编码的解决方案,但我的设备很慢,如果可能的话,我想避免这个解决方案。(我做了一个解决方法,我调用了一个选择默认设备的批处理脚本)。这有效,但不是很优雅......
1赞 Phil Freihofner 12/13/2022
AFAIK,可以从 a 读取数据并直接写入 a,这可以在 while 循环中完成,只要读写大小相同且每行的音频格式相同即可。但是 IDK 性能会是什么样子,因为 SDL 和 TDL 都使用阻塞队列。可能存在辍学问题。TargetDataLineSourceDataLine
0赞 Phil Freihofner 12/13/2022
我曾经编写过代码,从麦克风获取输入,并通过笔记本电脑的扬声器将其作为回声播放(使用循环队列进行延迟)。其中一个关键是利用并发安全的FIFO队列作为缓冲区,以处理传入和传出数据的启动-停止性质。对于多个回声,我将麦克风数据转换为 PCM,因为当音频格式需要超过 8 位时,直接添加音频字节将不起作用。
0赞 Manticore 12/13/2022
是的,这可能是一种功能解决方法,但由于我的软件是唯一在系统上运行的软件,因此我更喜欢更改默认的 Windows 声音设备。这是有效的,因为当我必须将一个输入绑定到输出时,这是我唯一的用法。我的所有其他用法都使用来自缓冲区的绑定。