查看文章 |
声明:Java Sound教程系列属于Sun Microsystem的Java Tutorials,由kingmmxtj于2008年11月5日开始翻译,并将在http://hi.baidu.com/kingmmxtj上发布。译者尊重Sun的权利,仅仅把文章用于学习交流。转贴请保留,谢谢! 原文地址:http://java.sun.com/docs/books/tutorial/sound/sampled-overview.html Sampled包综述
为了支持基本音频的输入和输出,Java Sound API提供了各种方法,包括在多种音频数据格式间转换、读取和写入常用声音格式文件。但是API并不是一个易于理解和使用的针对所有音乐文件的工具包。针对Java Sound API的某种具体实现不需要支持某些额外的文件集或者数据格式转换。第三方服务提供者可以提供“插件”给现有的系统来实现支持额外的文件和格式转换。 Java Sound API可以处理流化缓存形式(streaming,buffered fashion)和内存的非缓存形式(in-memory,unbuffered fashion)的音频传输。本文的“流化”(streaming)主要是指对某种音频格式的实时处理。用另一句话说,一个音频流是差不多以相同速度到达的一段连续的将被处理(播放、录制等等)的音频字节。在所有数据到达之前,已经开始对这些音频字节进行处理。在流体模型中,特别是在音频输入而不是音频输出的情况下,你不必提前知道声音有多长或者数据是否完全到达。你只需要一次处理一个缓存区的音频数据,除非操所别终止。在音频输出的情况下(回放),如果你需要播放的声音数据太大,不能一次装入内存中,你仍然需要缓冲数据。用另一句话说,你把你的音频字节用块的形式传输个音频机器,由音频机器来关注准确的播放每一个采样。这种机制可以很容易确定每个块中有多少数据。 仅仅在回放的情况下,Java Sound API也允许非缓冲传输,前提是你已经把要处理的数据全部准备好而且这些数据可以一次在内存中放下。在这种情况下,不再需要应用程序来缓冲音频,虽然仍然可以使用缓冲的实时方法。用另一句话说,整个声音能一次提前载入内存来进行连续回放。因为所有声音被提前载入,回放可以立即开始,例如从用户按下开始按钮的一瞬间。相对于缓冲模型的回放需要等待缓冲区的第一次装满,上述的特性是非缓冲模型的一个优点。另外,内存缓冲模型轻易的使声音循环(loop,cycled)或者从数据的某个任意特定位置来进行播放。 用Java Sound API来进行播放和捕捉声音,你至少需要3样东西:格式化音频数据(formatted audio data)、一个混频器(mixer)、一条线路(line)。下面将综述这些概念。 什么是格式化音频数据(formatted audio data)? 格式化音频数据指任一种标准格式的声音。Java Sound API主要区分数据格式(data formats)和文件格式(file formats)。 数据格式(data formats) 数据格式规定了如何解释”原始”(raw)采样音频数据的一系列字节。原始采样音频数据包括从一个声音文件读取的数据、从麦克风输入捕捉的采样。例如,你可能需要知道一个采样由多少个位(bit)组成(声音最小单元的表示),或者你也需要知道声音的采样频率(每2个采样点之间的时间间隔)。当设置回放或捕捉时,你必须描述你要播放或捕捉的声音的数据格式。 在Java Sound API中,数据格式由 l 编码技术,通常是脉冲编码调制(PCM) l 信道的数量(1代表单声道(mono),2代表立体声(stero)等等) l 采样频率(每秒每个信道的采样点数) l 每个采样点的比特数(每信道) l 帧速率 l 帧的字节大小 l 字节顺序(大端(big-endian)还是小段(little-endian)) PCM是一种声音波形编码技术。Java Sound API包括2种PCM编码:使用幅度线性量化(liner quantization of amplitude)和有符号或无符号整数值(signed or unsigned integer value)。线性量化意味着每个采样点存储的数值与该时刻原始声音的强度直接成比例(不包括噪声的影响),同样也与该时刻扬声器和耳膜的振动成相似的比例。例如,CD使用线性PCM编码音频。Mu-law编码和a-law编码是常用的非线性编码技术,这两种技术都提供了对音频数据的高压缩版本,主要用在电话技术和语音记录里。非线性编码通过非线性函数把原始声音幅度映射为一个存储的值,而该非线性被设计成相对与强信号可以提供给弱信号更多的幅度表示。 一个帧包含了一个特定时间所有信道所包含的数据。对于PCM编码的数据,帧就是所有信道里某个时间同步采样的集合,没有其他任何附加信息。在这种情况下,帧的速率相当于采样频率,而帧的字节长度相当与信道的数量乘以每个采样点的比特数除以一个字节所包含的比特数(8)。 对于其他的编码技术,一个帧可能包含除了采样点外的其他信息,而帧的速率可能与采样频率完全不同。例如,MP3编码技术(MPEG-1 Audio Layer 3),虽然在现在的Java Sound API版本中没有提及,但是可以被Java Sound API的实现或者第三方服务提供者来支持。在MP3里,每一个帧包含一系列采样点的一捆压缩数据,而不仅仅是每个信道一个采样点。因为每一个帧都封装了一整段采样点,所以帧的速率比采样速率要慢。MP3帧还包含帧头(header)。除了头部,MP3帧的字节长度比包含相同采样点信息的PCM帧(不止一个帧)的字节长度要短。(毕竟,MP3的目的是取得比PCM数据压缩率更高的数据)对于MP3这种编码,其采样频率和采样点大小将参考PCM数据,即在被传输进入数模转换器(DAC)之前,编码数据实际上要先被转换为PCM数据。 |

