Java 音频 & 音乐软件在 Linux 上的应用,第一部分
我一直想写这篇文章很久了。多年来,我注意到基于 Java 的音乐和声音应用程序的数量和质量都在提高,但还没有全面的列表或摘要涵盖这些进展。因此,我终于推出了这份需要 Java 的音乐和声音应用程序的调查报告。演示文稿没有特定的顺序,但在第一部分中,我将首先质疑在声音和音乐应用程序开发中使用 Java 的原因,然后简要介绍 Java 的内部音频和 MIDI 功能。
为什么选择 Java?
在声音和音乐软件开发人员可用的众多编程语言中,为什么要选择 Java?以下是我想到的一些原因:
Java 是一种跨平台解决方案 - “一次编写,到处运行”的口号起源于 Java,只要平台存在 JVM(Java 虚拟机),该语言就能兑现这一信条。我曾在 Linux 上运行过为 Windows 设计的 jar 文件,有时效果完美。效果会因所需的平台特定组件的数量和类型而异(例如,Windows 独有的 Java MIDI 驱动程序)。
Java 具有内部音频/MIDI API - Java Sound API 提供了一种内置机制,用于处理音频和 MIDI 事件、文件和流。应用程序员可以编写针对 API 而不是机器特定硬件和/或其音频子系统的代码。
Java 拥有自己的 GUI 组件 - 虽然默认的外观和感觉并不令人惊叹,但 Java GUI 工具包可以被引导得看起来非常精致(见图 1)。
Java 是一种面向对象的语言 - 如果我在学习基于 Lisp 的 Common Music 时学到了什么,那就是面向对象的语言在音乐创作软件方面非常出色。“炸弹”。本文的第二部分展示了各种 Java 音乐和声音应用程序,其中包含一些非常强大的软件,用于创建和转换音乐事件和模式。
Java 部署广泛 - Java 可用于主要的计算平台,在许多计算场景中都有长期而强大的使用记录,并且背后有大型企业(Sun Microsystems)的支持。
Java 现在是 FOSS - 终于,Sun 看到了光明,并将 Java GPL 化了。哈利路亚!
该语言确实有其缺点,我在本文中会提到其中的一些缺陷。然而,在研究这些材料时,我发现 Java 已经在声音和音乐领域的许多程序员中悄然“流行起来”。他们的工作质量不言而喻,但也说明了 Java 的实用性和吸引力。我们将首先简要了解 Java Sound API,开始对这种吸引力进行考察。

Java 音频
Java Sound 从 Sun 的 Java 1.3 版本开始就一直是标准组件。该 API 支持常见的音频操作,例如播放、录制和混音,其 MIDI 功能包括对 MIDI 事件排序和 MIDI 合成的支持。Java Sound 的目标是普通用户的典型桌面声音需求,例如媒体播放和相对轻量级的制作功能。不支持 SMPTE 或 MTC 等同步方法,也不支持 JACK,但只有当目标应用程序需要它们时,这些因素才具有局限性。
Java 支持 OSS /dev/dsp 设备作为其默认音频设备。Java 也支持 ALSA 声音系统,但这种支持带有警告。当一个应用程序看起来运行完美,但我的扬声器却没有任何声音时,我感到非常困惑。在 Linux 音频开发者列表的成员的帮助下,我发现 Java 不喜欢我的主要 ALSA 音频设备 M-Audio Delta 66,因此它滚动到下一个可用的卡,SBLive。但是,我不使用该卡进行音频,我只需要它的硬件 MIDI 端口,所以我感到困惑和无声,直到我意识到我的错误并将一些扬声器连接到 Live 的音频输出。
显然,Java 找不到适用于 Delta 66(专业音频卡)的合适混音器设备,因此它选择下一个设备,直到找到一个具有此类混音器的设备。显然,这种行为是故意的,但在这方面,Java 需要加深对 ALSA 支持的所有设备的支持。更好的是,Java 应该提供对 JACK 的完全支持。唉,根据 Java Sound Resources 网站上的 杂项 FAQ 页面上的评论,似乎对 JACK 的直接支持不会很快到来。
3.4. 为什么 Java Sound 中没有 artsd/esd 支持?
在 Florian 和我的观点中,像 artsd、esd、JACK、rplay、NAS、yiff 等混音守护程序是绕过设备驱动程序缺点的黑客行为。我们认为混音应该由声卡硬件完成,或者由设备驱动程序在软件中完成。对于 Windows (DirectSound) 和 Solaris,这是不言而喻的,而 Linux 则落后了。无论如何,OSS 驱动程序模型是过时的技术,ALSA 可以使用 dmix 插件在软件中进行混音。在这种情况下,所有关于混音守护程序的讨论都可以一劳永逸地解决。声音程序永远不必再用 /dev/dsp、ALSA、esd、arts、[你能想到的] 的输出插件来重新发明轮子。就使用(与浪费)程序员时间而言,这将是一个非常有效的解决方案。它甚至可以实现多个混音守护程序共存以实现向后兼容性。那么为什么不采取显而易见、优雅、技术上干净、(人力)资源节约的方案呢?
关于 ASIO 的类似评论让我相信 Java 声音开发应该考虑专业级音频制作的需求。如今,这些需求当然包括 Windows 的 ASIO 和 Linux 和 OSX 的 JACK。如果没有这种支持,Java 声音应用程序在许多方面可能很有用,但在需要低延迟和自由连接的环境中,它们的价值将大大降低。
尽管在 JACK 和 ASIO 方面有所疏忽,但 Java Sound Resources 网站仍然是通过 Java 1.5 实现的 Java Sound 的权威资源。查看它以获取代码示例、小程序和应用程序,以及非常全面的 FAQ 页面集。

Java Sound API 还提供了一个内部 MIDI 控制合成器的接口。此合成器呈现一组通用 MIDI 乐器,这些乐器包含在 $JAVA_HOME/jre/lib/audio 中找到的音色库中。许多 Java 音频应用程序使用内部合成器,但默认音色库的声音质量相当平庸。我建议将其替换为 Java Sound API:音色库 页面提供的豪华套装,质量要好得多。为了进一步改进此支持,Sun 开发了一个新的内部合成引擎,称为 Gervill 合成器(图 2),它最近达到了 1.0 发布阶段。Gervill 的功能包括支持 DSL 和 SoundFont2 音源、通用 MIDI 音色图和 MIDI 调音标准。我测试了独立版本的合成器,它运行良好,我认为它将成为系统的改进。(给开发人员的建议:如果支持 JACK 会更好。)
Tritonus
Tritonus 项目是 Java Sound API 的纯室实现,最初是为了为 Java 提供开源音频编程接口而编写的。Tritonus 通过插件系统增强和扩展了原始 API,该插件系统添加了 CD 音频抓取器、OGG 解码器、对 GNOME 的 esd 声音守护程序的支持以及对 ALSA 的混音器和音序器的支持等便利功能。项目开发长期以来一直很缓慢,而 Sun 开源 Java 的决定实际上否定了对 Tritonus 的需求。但是,Tritonus 插件仍然有用,并且应该可以与 Java 1.5 的 Java Sound API 一起使用。
JJack
Jens Gulden 的 JJack 将 Java 声音系统与 JACK 音频服务器结合在一起。该软件包为此统一提供了四种方法,包括用于 JACK 的本机 Java Sound 驱动程序、用于 JJack 客户端的 shell 环境、使用 JJack 设计 Java Bean 的规定以及在编译独立应用程序时使用 JJack 库。
我在 Studio Dave 的两台机器上编译并测试了 JJack,仅使用了第一种方法。我在 $JAVA_HOME/jre/lib/ext 中安装了 jjack.jar 和 jjack-clients.jar,并将 libjjack.so 复制到 /usr/lib。根据软件包说明,JJack 将被识别并自动启动。两个系统都指示它已正确启动,但不幸的是,JJack 在我的 JAD 1.0 系统(Java 1.5)上立即僵尸化。我正在研究该机器上的一些可能的解决方案。JJack 在我的 64 Studio 盒子上似乎更快乐,但这仅在我将 JACK 的配置从我的 Delta 66 (hw:0) 切换到机器的第二张卡 SoundBlaster PCI128 (hw:1) 之后。唉,QJackCtl 报告了稳定的 xrun 流,直到我记起 PCI128 在单工模式下表现更好。我切换了模式,xrun 显着减少,当我将 JACK 缓冲区从 512 提高到 1024 个样本时,xrun 进一步减少。
我以为我已经解决了 JJack 的所有问题,但是当我尝试从 JJack 端口录制到 ecasound 时,我只创建了空文件。使用 strace,我进一步研究了这个问题,发现 Java 仍然没有访问 ALSA 设备,而是回滚到使用 /dev/dsp。因此,尽管 JJack 按广告宣传的那样运行,但它仍然没有接收来自 Java 内部声音处理程序的音频流。我已经联系了作者,我计划与他合作解决这些问题,但我再次声明,Sun 直接支持 JACK 将更符合其更大的利益。正如本文的第二部分将要展示的那样,Java 声音和音乐程序正在蓬勃发展,为它们提供 JACK 连接的礼物将丰富整个 Java 音频/MIDI 应用程序开发人员和用户社区。