Java中可靠的声音API,用于简单的数字样本回放

时间:2012-12-23 01:05:18

标签: java lwjgl javasound openal alsa

是否有一个很好的方法可以在Java中获得体面,可靠的数字采样声音播放?

我的请求列表很短:

  • 将数字化样本加载到内存中(例如,来自jar中捆绑的资源),例如.wav文件
  • 以非阻止方式播放
  • 当我同时播放多个样本并且它们及时交叉时,它们应该正确混合

拥有以下内容会很高兴,但实际上我可以不用它来生活:

  • 播放.ogg或类似的压缩格式(显然没有在Java中实现需要CPU的解码器)
  • 在播放时仍然播放相同的样本不应该停止先前播放给定的样本,但是第二个副本应该开始并与第一个正确混合

我已经尝试了臭名昭着的Java Sound API,但发现它完全不可靠,似乎无法满足我的最小愿望清单。我得到的问题:

  • 在使用ALSA dmix(OpenJDK 6)的Linux上,在初始化Java Sound API时让任何其他应用程序使用音频只会使Java应用程序中的所有声音消失,而不会出现任何错误/警告。

  • 在Linux(OpenJDK 6)上,列出MixerInfo并尝试使用其中任何一个获取Clip对象时,在尝试加载wav文件时会抛出以下异常:

    java.lang.IllegalArgumentException: Line unsupported: interface Clip supporting format PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
    

    因此,AudioSystem.getClip(anySortOfMixer)似乎根本不起作用。只有AudioSystem.getClip()有效。

  • 使用Clip加载具有不同采样率/位/格式的文件时,LineUnavailableException失败。似乎第一次调用clip.open将声音系统设置为特定的声音选项,在调用后加载具有略微不同采样率的文件(例如,第一个是44100,第二个是48000)

  • 在Linux(OpenJDK 6)上初始化几个不同的Clip并尝试播放它们只会使最后一次加载Clip听到 - 没有给出错误/警告,但仅使用{{1在最后play加载时发出任何声音 - 所有其他声音都是沉默的:

    Clip

    Windows上的这些代码一切都很好 - 所有剪辑都可以听到,播放和混合正常。尚未在Mac上测试过。

  • 支持的文件格式(使用Clip loadSound(String name) { URL url = this.getClass().getResource("/" + name + ".wav"); Clip clip = AudioSystem.getClip(); AudioInputStream ais = AudioSystem.getAudioInputStream(url); clip.open(ais); return clip; } void playSound(Clip) { if (clip.isRunning()) clip.stop(); clip.setFramePosition(0); clip.start(); } ... Clip c1 = loadSound("foo"); Clip c2 = loadSound("bar"); ... playSound(c1); // silence ... playSound(c2); // audible 分析)在Linux / OpenJDK6和Windows / Oracle JDK 7上返回wav / au / aif,因此没有oggs甚至是mp3 :(

  • 似乎没有简单的方法可以同时制作相同AudioSystem.getAudioFileTypes声音的两个副本,而无需将第二个副本作为不同的Clip加载。

所以,问题是 - 是否有一个很好的解决方案/解决方法来补救所有这些东西并使其更可靠?切换到其他声音系统(例如LWJGL OpenALpaulscode.com sound system)会有帮助吗?或者是否可以将Java Sound API包装在一些安全防护装置中并且它可以正常工作?

我做了一个小应用程序来测试上述所有内容,但它有点长,所以我想我会把它发布为gist,但不幸的是,GitHub正在解决一些网络问题现在。所以,我想,稍后我会发布它。

1 个答案:

答案 0 :(得分:2)

我在Java-gaming.org上发布了一个相当简单,有限的音频混音器,欢迎您查看以下网址: http://www.java-gaming.org/topics/simple-audio-mixer-2nd-pass/27943/view.html

第一篇文章中列出的jar包含源代码和示例用法,我在制作javadoc注释时付出了一些精力。 (98%的下载是我收录的单个样本。)另外,在线程上有很多api信息。

它还存在Linux问题。但是我对你的分析印象深刻,并且想知道分享努力尝试排除故障并解决这个问题!

关于你的观点:

  • 我记得在一些Linux系统中,只有一个输出是可能的,并且有些应用程序不公平,并且在存在争用时将音频发布到Java。如果这是准确的,那么很难将其称为Java问题,而可能是Linux OS问题?

  • 第二点:我还没有尝试从Linux中的Mixer加载,但我知道有些人已经能够通过我的网络应用程序Java Theremin做到这一点。在该应用程序(在上面的线程中链接)中,我包含一个允许用户选择混音器的下拉列表。至少有一些Linux用户已经成功了。

  • 我没有使用Big-Endian wavs - 但只有小端的wavs。您必须翻转Audacity中的字节或类似的东西才能使用我目前的调音台。

  • 我的系统处理并发。您将wav加载到PFClipData对象中。然后,您可以通过PFClipShooter(可以处理并发播放 - 20或30,以及不同的音高)或PFClipLooper(将使用末尾的可选重叠模式循环剪辑)以多种不同方式播放帮助平滑循环点)。所有输出都在后台汇集到一个SourceDataLine中。

  • 我还没有实现ogg或mp3,只有16位,44100fps的立体声小端wav文件。

  • 如果有其他人愿意分享,可以考虑将其作为开源git项目。

- 我最近在我的PC上的双启动分区中成功安装了Linux(Ubuntu Desktop),并且即将安装声卡,看看我是否重新创建并希望修复一些正在描述的问题。 Ubuntu同时具有OpenJDK和Oracle的JDK,所以我希望看看Java实现是否可能成为问题的一部分。正在进行中......