Java实现音频播放JavaSoundAPI编写音频管理组织程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、JavaSound的体系结构
二、JavaSound混频原理
三、音频数据与存储格式
四、设计音乐播放器
五、播放音乐
六、支持更多的音频格式
━━━━━━━━━━━━━
桌面PC的性能日益提高,Java虚拟机的优化技术也不断获得突破,这一切使得用Java处理实时信号成为可能。本文将通过设计和构造一个支持实时MP3、WAV和Ogg音频格式解码/回放的Java音乐播放器,阐述用JavaSound API编写音频处理程序的思路和一般过程。
JavaSound是一个小巧的低层API,支持数字音频和MIDI数据的记录/回放。在JDK 1.3.0之前,JavaSound是一个标准的Java扩展API,但从Java 2的1.3.0版开始,JavaSound就被包含到JDK之中。由于Java有着跨平台(操作系统、硬件平台)的特点,基于JavaSound的音频处理程序(包括本文的程序)能够在任何实现了Java 1.3+的系统上运行,无需加装任何支持软件。
一、JavaSound的体系结构
当前JDK的JavaSound API随同Java媒体框架(JMF,Java Media Framework)一起发布,主页在/products/java-media/jmf/,适合JDK 1.1以及更高的版本。除了JDK实现的JavaSound API之外,还有一个源代码开放的JavaSound实现是Tritonus,主页在/。
图一描述了JavaSound API的体系结构,虚线表示Sun的JavaSound标准定义的API调用。上面一根虚线表示我们编写音频处理程序要调用的API,JavaSound API包含在javax.sound.sampled和javax.sound.midi包中。两根虚线之间的部分就是JavaSound API的具体实现。
图一:JavaSound体系结构
就象上面一根虚线表示的API具有统一标准一样,在所有的JavaSound实现中,图一下面一根虚线表示的SPI(服务提供者接口, Service Provider Interface)也是统一的。SPI的作用是以插件(Plug-In)的形式提供自定义的扩展模块,我们只要提供与SPI兼容的插件扩展模块,就可以在不改变API的情况下扩展音频处理程序的能力。SPI包含在java.sound.sampled.spi和javax.sound.midi.spi包中。
例如,假设有一个只能播放WAV文件的程序,我们只要增加一个支持MP3文件解码的插件模块,就可以在不改动播放程序的任何一行代码的前提下,为这个播放程序添加播放MP3的能力。
二、JavaSound混频原理
图二阐述了JavaSound的混频器原理。在处理输入音频的应用中,对于来自各种音频输入端口的信号,例如麦克风、CD播放器、磁带播放器,等等,我们可以在它们到达TargetDataLine之前,利用混频器控制输入混频,最后在程序中通过TargetDataLine获得数字化的音频输入流。
图二:JavaSound混频器
类似地,在处理输出音频的应用中,混频器用来对一系列来自SourceDataLine
的数据进行混频处理,经处理后的信号可输出到各种输出端口,例如扬声器、耳机等。SourceDataLine是一个可写入音频信号数字流的设备,例如,我们可以从一个WAV 文件读取内容写入到SourceDataLine,然后再通过扬声器输出。
输入到混频器的信号可以来源于剪辑。剪辑(Clip)是一个包含一段完整音频数
据流的设备,或者说,剪辑就是一个缓冲在内存中的完整音频数据流。在一些要求反
复播放音乐片段的场合,例如游戏的背景音乐,剪辑是很有用的。
图三描述了JavaSound API中一些常用的类、接口及其关系,所有图三显示的类、接口都通过Line这个基本接口统一起来。Line接口用来关闭/打开设备、注册事件监
听器,以及提供一些用来调整声音效果的对象,例如调整音量大小的对象。AudioSystem在JavaSound体系中起着一个工厂(Factory)类的作用,提供了一系列的静态方法,我们通过这些静态方法来获取JavaSound系统默认配置的资源(所谓静态方法,就是可以在不创建AudioSystem实例的情况下直接调用的方法)。
图三:常用的JavaSound类
顺便说明一下,在当前(JDK 1.4)实现的JavaSound的默认配置中,输入声音来自本地声卡的麦克风,输出声音到本地声卡的扬声器。应当说当前实现的JavaSound对端口和混频器的支持还不完善,但对于包括本文音乐播放器在内的许多应用来说,默认实现的JavaSound配置已经足够了。
三、音频数据与存储格式
取样得到的音频数据——也就是从TargetDataLine输入或从SourceDataLine 输出的数据,必须符合音频格式的标准。音频数据的格式选项由AudioFormat类封装,主要选项包括:编码方式,可以是PCM(Pulse Code Modulation,脉冲编码调制)、MP3等;通道数量;取样率;帧速率;等等。
音频数据可以用多种格式保存到磁盘上。在JavaSound参考实现中,直接支持的文件格式包括WAV(Windows)、AIFF(主要用于Apple的Macintosh)以及AU (主要用于UNIX),音频文件的格式由AudioFileFormat类指定。
并非所有音频数据格式都可以保存到任意音频文件格式(或从音频文件回放),
具体由平台和操作系统的类型决定。为简单计,本文的播放器只考虑包含PCM Mono 或Stereo数据的WAV文件,这是当前流行的音频数据/文件格式组合,常用于CD 音质的音频数据。压缩的音频数据(例如MP3和Ogg Vorbis)通常有各自特殊的存储格式(如.MP3和.OGG),通常不以WAV/AIFF/AU格式存储。
四、设计音乐播放器
我们要编写的音乐播放器(图四)由表一所示的几个类构成。鉴于构造用户界面往往需要大量的代码,且这些代码通常可以用IDE自动生成,所以下文只对一些关键的GUI元素略作介绍,不再给出完整的代码。
图四:播放器的用户界面