通过 Minim 访问 JavaSound SourceDataLine 不一致
Inconsistent Access to JavaSound SourceDataLine Through Minim
我在 Linux 世界中是一个不太了解的人,试图了解我在项目中遇到的音频问题。简而言之,我正在尝试通过名为 Minim (ddf.minim) 的 Java 库获取音频输出。我可以通过监听输入并启用“监控”来获得输出。监控将输入回显到输出。但是,我无法获得独立于此功能的工作输出线。
一些上下文:
此应用程序 运行 在装有 Debian Buster 的 BeagleBone Black 上运行。这是一个 ARM 微控制器。我的 Java 应用程序作为 root 用户作为 systemd 服务启动。它以无头模式运行,但具有虚拟帧缓冲区 (xvfb
),因为它是一个 Processing 应用程序。我有一个连接到 BeagleBone 的 USB 集线器,它装有一个 USB 转 AUX 适配器。 AUX 端分成 pink/green input/output 电缆。我有一个麦克风连接到粉红色端,耳塞连接到绿色端。
问题:
当使用 Minim 的 getLineIn()
获取输入时,没有看到任何错误。启用监控也不会产生错误。使用 getLineOut()
将显示如下所示的错误:
==== JavaSound Minim Error ====
==== Couldn't open the line: line with format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian not supported.
==== JavaSound Minim Error ====
==== Unable to return a SourceDataLine: unsupported format - PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
这是我要求输出的代码:
Mixer.Info mixers[] = AudioSystem.getMixerInfo();
for(Mixer.Info info : mixers)
{
try
{
mixer = AudioSystem.getMixer(info);
if(!mixer.isOpen())
{
mixer.open();
}
M.setOutputMixer(mixer);
LineOut = M.getLineOut();
}
catch(Exception e)
{
mixer = null; //This mixer can't be used.
continue;
}
if(mixer != null && LineOut != null)
{
break;
}
}
错误并不总是抛出异常,所以这就是我进行空值检查的原因。有趣的是,即使出现错误消息,LineOut
也不会为空。我可以将它传递给其他方法,但我永远听不到任何声音。只有两个混音器出现,一个用于 USB 适配器,另一个在打开后抛出异常。
我尝试过的解决方案:
使用 aplay
播放示例文件曾经失败,但一旦我安装了 PulseAudio,它们就可以工作了。
我没有声卡 0,但 USB 适配器显示为声卡 1。我已将 asound.conf
更改为在底部添加这些额外的行:
defaults.pcm.card 1
defaults.ctl.card 1
在阅读了 Java 对 PulseAudio 的弱支持后,我还在 /usr/lib/jdk1.8.0_251/jre/lib
下的 sound.properties 配置文件中添加了这些行:
javax.sound.sampled.Clip=com.sun.media.sound.DirectAudioDeviceProvider
javax.sound.sampled.Port=com.sun.media.sound.PortMixerProvider
javax.sound.sampled.SourceDataLine=com.sun.media.sound.DirectAudioDeviceProvider
javax.sound.sampled.TargetDataLine=com.sun.media.sound.DirectAudioDeviceProvider
我已经使用 AudioSystem
class 来查询混音器支持的格式。它们与我请求的格式相同,因此我不确定错误消息是否准确描述了问题。我试过单声道、立体声、不同的缓冲区大小……可能还有其他东西。
我已将我的应用程序更改为仅查找输出,而不查找输入。问题仍然存在。
这段代码在 Windows 上运行良好,这是我在将它移植到 Debian 机器之前测试的地方。
我在 Linux 上读了很多关于声音普遍脆弱的文章,所以我怀疑我做错了什么或者 Java 不适合输出声音用我独特的设置。帮忙?
我想通了!
调用 mixer.open()
时出现问题。我想 Minim 自己会这样做,并希望用户在请求线路时不要打开它。
不过,我也有其他发现。
- Java and/or Minim 对 re-requesting 音频资源非常敏感,至少在 Debian 上是这样。由于请求 line-in 隐式请求了监视功能的输入和输出,因此对
getLineOut()
的后续调用将失败。但是,您可以调用 Minim.stop()
重新开始并再次获取资源。
AudioPlayer
似乎坏了。我无法让它请求工作输出,但我发现 FilePlayer
出于某种原因工作正常。您甚至可以在 FilePlayer
之前使用 getLineOut()
请求输出。也许你必须在获得 AudioPlayer
之前调用 setOutputMixer()
(而不是调用 getLineOut()
)才能使其工作。
我在 Linux 世界中是一个不太了解的人,试图了解我在项目中遇到的音频问题。简而言之,我正在尝试通过名为 Minim (ddf.minim) 的 Java 库获取音频输出。我可以通过监听输入并启用“监控”来获得输出。监控将输入回显到输出。但是,我无法获得独立于此功能的工作输出线。
一些上下文:
此应用程序 运行 在装有 Debian Buster 的 BeagleBone Black 上运行。这是一个 ARM 微控制器。我的 Java 应用程序作为 root 用户作为 systemd 服务启动。它以无头模式运行,但具有虚拟帧缓冲区 (xvfb
),因为它是一个 Processing 应用程序。我有一个连接到 BeagleBone 的 USB 集线器,它装有一个 USB 转 AUX 适配器。 AUX 端分成 pink/green input/output 电缆。我有一个麦克风连接到粉红色端,耳塞连接到绿色端。
问题:
当使用 Minim 的 getLineIn()
获取输入时,没有看到任何错误。启用监控也不会产生错误。使用 getLineOut()
将显示如下所示的错误:
==== JavaSound Minim Error ====
==== Couldn't open the line: line with format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian not supported.
==== JavaSound Minim Error ====
==== Unable to return a SourceDataLine: unsupported format - PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
这是我要求输出的代码:
Mixer.Info mixers[] = AudioSystem.getMixerInfo();
for(Mixer.Info info : mixers)
{
try
{
mixer = AudioSystem.getMixer(info);
if(!mixer.isOpen())
{
mixer.open();
}
M.setOutputMixer(mixer);
LineOut = M.getLineOut();
}
catch(Exception e)
{
mixer = null; //This mixer can't be used.
continue;
}
if(mixer != null && LineOut != null)
{
break;
}
}
错误并不总是抛出异常,所以这就是我进行空值检查的原因。有趣的是,即使出现错误消息,LineOut
也不会为空。我可以将它传递给其他方法,但我永远听不到任何声音。只有两个混音器出现,一个用于 USB 适配器,另一个在打开后抛出异常。
我尝试过的解决方案:
使用 aplay
播放示例文件曾经失败,但一旦我安装了 PulseAudio,它们就可以工作了。
我没有声卡 0,但 USB 适配器显示为声卡 1。我已将 asound.conf
更改为在底部添加这些额外的行:
defaults.pcm.card 1
defaults.ctl.card 1
在阅读了 Java 对 PulseAudio 的弱支持后,我还在 /usr/lib/jdk1.8.0_251/jre/lib
下的 sound.properties 配置文件中添加了这些行:
javax.sound.sampled.Clip=com.sun.media.sound.DirectAudioDeviceProvider
javax.sound.sampled.Port=com.sun.media.sound.PortMixerProvider
javax.sound.sampled.SourceDataLine=com.sun.media.sound.DirectAudioDeviceProvider
javax.sound.sampled.TargetDataLine=com.sun.media.sound.DirectAudioDeviceProvider
我已经使用 AudioSystem
class 来查询混音器支持的格式。它们与我请求的格式相同,因此我不确定错误消息是否准确描述了问题。我试过单声道、立体声、不同的缓冲区大小……可能还有其他东西。
我已将我的应用程序更改为仅查找输出,而不查找输入。问题仍然存在。
这段代码在 Windows 上运行良好,这是我在将它移植到 Debian 机器之前测试的地方。
我在 Linux 上读了很多关于声音普遍脆弱的文章,所以我怀疑我做错了什么或者 Java 不适合输出声音用我独特的设置。帮忙?
我想通了!
调用 mixer.open()
时出现问题。我想 Minim 自己会这样做,并希望用户在请求线路时不要打开它。
不过,我也有其他发现。
- Java and/or Minim 对 re-requesting 音频资源非常敏感,至少在 Debian 上是这样。由于请求 line-in 隐式请求了监视功能的输入和输出,因此对
getLineOut()
的后续调用将失败。但是,您可以调用Minim.stop()
重新开始并再次获取资源。 AudioPlayer
似乎坏了。我无法让它请求工作输出,但我发现FilePlayer
出于某种原因工作正常。您甚至可以在FilePlayer
之前使用getLineOut()
请求输出。也许你必须在获得AudioPlayer
之前调用setOutputMixer()
(而不是调用getLineOut()
)才能使其工作。