文档

Java™ 教程

教程:声音

Java声音API是一个用于影响和控制声音媒体输入和输出的低级API,包括音频和MIDI数据。Java声音API提供了对通常用于声音输入和输出的功能的显式控制,以促进可扩展性和灵活性。

Java声音API满足广泛的应用程序开发人员的需求。潜在的应用领域包括:

Java声音API提供了Java平台上最低级别的声音支持。它为应用程序提供了对声音操作的极大控制,并且它是可扩展的。例如,Java声音API提供了安装、访问和操作系统资源(如音频混音器、MIDI合成器、其他音频或MIDI设备、文件读取器和写入器以及声音格式转换器)的机制。Java声音API不包括复杂的声音编辑器或图形工具,但它提供了构建此类程序所需的功能。它强调超出最终用户通常期望的低级控制。

Java声音API包括对数字音频和MIDI数据的支持。这两个主要的功能模块在单独的包中提供:

另外两个包允许服务提供商(而不是应用程序开发人员)创建自定义软件组件,扩展Java声音API的功能:

本页面介绍了采样音频系统、MIDI系统和SPI包。然后在教程的后面详细讨论了每个包。


注意: 

还有其他与音频相关的Java平台API。 Java媒体框架API(JMF)是一个更高级的API,目前作为Java平台的标准扩展可用。JMF指定了统一的架构、消息协议和编程接口,用于捕获和播放基于时间的媒体。JMF为基本媒体播放器应用程序提供了更简单的解决方案,并且它可以实现不同媒体类型(如音频和视频)之间的同步。另一方面,如果程序专注于音频,尤其是需要更高级功能(如精确控制缓冲音频播放或直接操作MIDI合成器的能力),则可以从Java Sound API中受益。其他具有声音方面的Java API包括Java 3D和用于电话和语音的API。这些API中的任何一个实现都可以在内部使用Java Sound API的实现,但不是必需的。


什么是采样音频?

javax.sound.sampled包处理数字音频数据,Java Sound API将其称为采样音频。 样本是信号的连续快照。在音频的情况下,信号是声波。麦克风将声学信号转换成相应的模拟电信号,模数转换器将该模拟信号转换成采样的数字形式。下图显示了声音录制的一个短暂时刻。

一个采样声波

一个采样声波

此图以声压(振幅)为纵轴,时间为横轴绘制。模拟声波的振幅以一定的频率周期性地测量,从而得到由数字音频信号组成的离散样本(图中的红色数据点)。中心水平线表示零振幅;线上方是正值样本,线下方是负值样本。数字信号对模拟信号的数字近似精度取决于时间上的分辨率(采样率)和振幅上的量化,即振幅分辨率(用于表示每个样本所使用的位数)。作为参考,存储在CD上的音频每秒采样44,100次,并使用每个样本16位表示。

这里的术语“采样音频”使用得有些宽泛。声波可以在模拟形式下以离散间隔进行采样。然而,对于Java音频API来说,“采样音频”等同于“数字音频”。

通常,计算机上的采样音频来自音频录制,但声音也可以是合成生成的(例如,创建触摸音调电话的声音)。术语“采样音频”指的是数据类型,而不是其来源。

Java音频API不假设特定的音频硬件配置;它被设计成允许在系统上安装不同类型的音频组件并通过API进行访问。Java音频API支持常见的功能,例如从声卡进行输入和输出(例如,录制和播放声音文件)以及多个音频流的混合。下面是一个典型音频架构的示例:

以下上下文描述了该图

典型音频架构

在这个示例中,诸如声卡之类的设备具有各种输入和输出端口,并且混音由软件提供。混音器可能会接收从文件中读取的数据,从网络流式传输的数据,由应用程序动态生成的数据,或者由MIDI合成器产生的数据。混音器将所有音频输入组合成一个单一的流,可以发送到输出设备进行渲染。

什么是MIDI?

javax.sound.midi包中包含了传输和排序MIDI事件以及根据这些事件合成声音的API。

与采样音频直接表示声音本身不同,MIDI数据可以被看作是创建声音的配方,特别是音乐声音的配方。与音频数据不同,MIDI数据不直接描述声音,而是描述影响由MIDI设备或乐器(例如合成器)执行的声音(或动作)的事件。 MIDI数据类似于图形用户界面的键盘和鼠标事件。对于MIDI来说,这些事件可以被视为对音乐键盘上的动作,以及对该乐器上的各种踏板,滑块,开关和旋钮的动作。这些事件不一定实际源自硬件乐器;它们可以在软件中模拟,并且可以存储在MIDI文件中。可以创建,编辑和执行这些文件的程序称为序列器。许多计算机声卡包括可通过MIDI发送其MIDI事件的可控音乐合成器芯片。合成器也可以完全以软件形式实现。合成器解释它们接收到的MIDI事件并生成音频输出。通常,从MIDI数据合成的声音是音乐声音(与语音等相对)。MIDI合成器还能够生成各种类型的音效。

一些声卡包括MIDI输入和输出端口,可以连接外部的MIDI硬件设备(如键盘合成器或其他乐器)。应用程序可以从MIDI输入端口接收外部MIDI设备生成的事件。该程序可以使用计算机内部的合成器播放音乐表演,将其保存到磁盘上作为MIDI文件,或将其渲染成音乐符号。程序可以使用MIDI输出端口来播放外部乐器,或控制其他外部设备,如录音设备。

下图说明了基于Java Sound API的可能的MIDI配置中主要组件之间的功能关系。(与音频一样,Java Sound API允许安装和互连多种MIDI软件设备。这里显示的系统只是一个潜在的方案。)箭头表示组件之间的数据流动。数据可以是标准的文件格式,或者(如图示右下角的键所示)可以是音频、原始MIDI字节或时间标记的MIDI消息。

以下内容描述了该图。

可能的MIDI配置

在这个例子中,应用程序通过从磁盘上读取存储为标准MIDI文件的音乐乐谱(图示左侧)来准备音乐表演。标准MIDI文件包含多个轨道,每个轨道都是一个时间标记的MIDI事件列表。大多数事件代表音符(音高和节奏)。该MIDI文件由软件序列器读取,然后通过发送MIDI消息给其他设备(如内部或外部合成器)来“演奏”音乐。合成器本身可以读取包含模拟某些乐器声音指令的声库文件。如果没有,合成器将使用已加载到其中的任何乐器声音来播放MIDI文件中存储的音符。

如图所示,MIDI事件在通过MIDI输出端口发送到外部MIDI设备之前必须转换为原始(非时间标记的)MIDI。同样,从外部MIDI源(图示中的键盘乐器)进入计算机的原始MIDI数据被转换为时间标记的MIDI消息,可以控制合成器,或者可以由序列器存储以供以后使用。

服务提供者接口

javax.sound.sampled.spijavax.sound.midi.spi包含的API允许软件开发人员创建新的音频或MIDI资源,可以分别提供给用户,并“插入”到现有的Java Sound API实现中。以下是一些可以以这种方式添加的服务(资源)的示例:

在某些情况下,服务是对硬件设备(如声卡)功能的软件接口,服务提供者可能与硬件的供应商相同。在其他情况下,服务纯粹存在于软件中。例如,合成器或混音器可以是声卡上的芯片的接口,也可以在没有任何硬件支持的情况下实现。

Java音频API的实现包含一组基本的服务,但服务提供者接口(SPI)包允许第三方创建新的服务。这些第三方服务以与内置服务相同的方式集成到系统中。 AudioSystem类和MidiSystem类充当协调器,使应用程序能够显式或隐式地访问服务。通常,应用程序对使用的服务的存在完全透明。服务提供者机制使基于Java音频API的应用程序的用户受益,因为可以向程序添加新的声音功能,而无需更新JDK或运行时环境的新版本,甚至在许多情况下,无需更新应用程序本身的新版本。


上一页:教程的开始
下一页:示例包的概述