http://wenku.baidu.com/view/bb24a0380912a21614792943.html
http://wenku.baidu.com/view/ca78c3878762caaedd33d4f7.html
http://wenku.baidu.com/view/67117223af45b307e871977e.html
http://wenku.baidu.com/view/a6cc0117866fb84ae45c8dbf.html
http://book.51cto.com/art/200903/116331.htm
java高手真经-编程基础卷-17.3
假设有两个或两个以上的播放器同时播放音乐,我们就会听到几首音乐同时在我们耳边响起,而且如果我们想要这些音乐的声音大小是不同的,也是可以做到的,这是怎么做到的?
原来,我们的电脑上有一个叫做"混频器"的东西(频率混合器或混音器更准确,不过鉴于java中文版文档翻译为混频器,我们就也称之为混频器),它会把输入到"混频器"声音混合起来,让多个声音变成一个声音,再把这一个声音播放出来,就可以同时听多首音乐了(虽然听起来效果很差)。
在java中,混频器实现了对底层硬件的调用,通过它,可以向硬件读写声音信号,但是,不能直接向混频器i/o操作硬件,混频器对象更像是一个调度员,协调音频的输出顺序和查询正在输出的音频源。
混频器输出的数据从哪来?来自输出设备对象(或输出缓冲区、数据源、源数据行)javax.sound.sampled.SourceDataLine,SourceDataLine是混频器的缓冲区,每个输出设备对象必然关联一个混频器,被关联的混频器自动的通过硬件输出被缓存的数据,从应用程序的角度来看,SourceDataLine等效于输出设备。输出设备对象又怎么来的?来源主要是javax.sound.sampled.AudioSystem.getSourceDataLine(AudioFormat format)和AudioSystem.getSourceDataLine(AudioFormat format, Mixer.Info mixerinfo)两个方法,区别在于后者可以由指定的混频器输出数据,前者只能是默认的混频器输出数据。
又有一个问题,AudioFormat format是什么,怎么来的?AudioFormat即音频格式。是在声音流中指定特定数据安排的类。通过检查以音频格式存储的信息,可以发现在二进制声音数据中解释位的方式。 简单来说,这个类包括了这个音频流的文件格式(MP3,wav)、信道数(几声道的)、采样速率(每秒采集多少次麦克风表示声波幅度的线性电压幅度)、样本大小(线性电压幅度的精度)、字节顺序是大端还是小端、帧速率和帧大小等等播放声音所必须的属性。
AudioFormat的来源主要有3个:
1:通过javax.sound.sampled.AudioFormat
类的构建函数创建。
2:javax.sound.sampled.DataLine.getFormat()输入设备对象TargetDataLine输出设备对象SourceDataLine剪辑Clip都实现了DataLine接口。
3:javax.sound.sampled.AudioInputStream.getFormat() 通过音频输入流(常用)。
播放声音只要两个参数,输出设备对象和音频数据的源(文件、麦克风),我们只要打开输出设备,并源源不断从音频数据的源取出要播放的音频数据给输出设备,就可以听到悦耳的音乐了。例子如下:
package paly;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
public class Paly {
private static AudioInputStream audioInputStream;
private static AudioFormat audioFormat;
private static SourceDataLine res;
public static void main(String[] args)
throws UnsupportedAudioFileException, IOException,
LineUnavailableException {
paly(new File("8912289ddbc2bc06df6aabf9ba736b44.wav"));
paly(new File("献曼达.mp3"));//mp3格式的文件不支持,经过转换为mp3编码之后才支持
}
public static void paly(File file) throws UnsupportedAudioFileException,
IOException, LineUnavailableException {
audioInputStream = AudioSystem.getAudioInputStream(file);//得到要播放的文件的音频输入流
audioFormat = audioInputStream.getFormat();//音频流的
res = AudioSystem.getSourceDataLine(audioFormat);//得到输出设备对象
res.open(audioFormat);//打开输出设备
// res.open();
res.start();//开始播放
int inBytes = 0;
byte[] audioData = new byte[1024*200];//缓冲区
while ((inBytes != -1)) {
inBytes = audioInputStream.read(audioData, 0, audioData.length);//从音频输入流读取音频数据到缓冲区
if (inBytes >= 0) {//把音频数据写入到输出设备
res.write(audioData, 0, inBytes);
}
}
res.drain();//直到输出设备对象缓冲区的数据被输出,返回。加上这句,能完整的输出整个音频流
res.close();//关闭输出设备
audioInputStream.close();//关闭音频流
}
}
这还有个 eclipse工程的示例 。http://download.csdn.net/detail/lxqq0000/6956201,wav和mp3文件自备