11 音频播放器
基础知识:(Sequencer:javax.sound.midi)
1、JavaSound API:
JavaSound被分为两个部分:MIDI(Musical Instrument Digital Interface)和取样(sampled).
MIDI本身不带有声音,它带的是有MIDI播放功能装置的指令(想象成某种乐谱,它可以输入到某种电子琴中)
MIDI数据表示执行的动作,但没有实际的声音,实际的声音是靠装置发出的
2、创建Sequencer:(javax.sound.midi)
在我们能够发出任何声音之前,必须先要取得Sequencer对象,此对象会将所有的MIDI数据送到正确的装置上,
由装置来产生音乐。
import javax.sound.midi.*; public class Test { public static void main(String[] args) { Test t = new Test(); t.play(); } public void play() { try {//使用的javax.sound.midi包中的方法基本上都会抛出异常,所以注意try/catch使用 Sequencer sequence = MidiSystem.getSequencer();//无法实例化 MidiSystem;所有的方法都是静态的。 System.out.println("we got a sequencer"); } catch(MidiUnavailableException ae) { ae.printStackTrace(); } }//关闭播放 }
3、JavaSound工作原理:
4个条件:
5个步骤: 第五步:按下Play键的步骤player.start();
第一个声音播放程序:
import javax.sound.midi.*; public class Test { public static void main(String[] args) { Test t = new Test(); t.play(); } public void play() { try { //1、取得Sequencer并将其打开 Sequencer player = MidiSystem.getSequencer(); player.open(); //2、创建新的Sequence Sequence seq = new Sequence(Sequence.PPQ,4); //3、从Sequence中创建新的Track Track track = seq.createTrack(); /* 对Track加入几个MidiEvent,要注意的是setMessage()的参数, 以及MIdiEvent的constructor。 */ ShortMessage a = new ShortMessage(); a.setMessage(144, 1, 44, 100); MidiEvent noteOn = new MidiEvent(a, 1); track.add(noteOn);//4、填入MidiEvent ShortMessage b = new ShortMessage(); b.setMessage(128, 1, 44, 100); MidiEvent noteOff = new MidiEvent(b, 16); track.add(noteOff);//4、填入MidiEvent //4、将Sequence送到Sequencer上 player.setSequence(seq); //5、开始播放 player.start(); } catch(Exception ex) { ex.printStackTrace(); } }//关闭播放器 }//关闭类
4、制作MidiEvent
MidiEvent是组合乐曲的指令。一连串的MidiEvent就好像是乐谱一样。
MIDI指令会放在Message对象中,MidiEvent是由Message加上发音时机所组成的
Message描述做什么,MidiEvent指定何时做
import javax.sound.midi.*; public class Test { public static void main(String[] args) { Test t = new Test(); t.play(); } public void play() { try { //1、取得Sequencer并将其打开 Sequencer player = MidiSystem.getSequencer(); player.open(); //2、创建新的Sequence Sequence seq = new Sequence(Sequence.PPQ,4); //3、从Sequence中创建新的Track Track track = seq.createTrack(); /* 对Track加入几个MidiEvent,要注意的是setMessage()的参数, 以及MIdiEvent的constructor。 */ ShortMessage a = new ShortMessage();/*a、创建Message*/ a.setMessage(144, 1, 44, 100);/*b、置入指令,代表发出44音符*/ MidiEvent noteOn = new MidiEvent(a, 1);/*c、用Message创建MidiEvent,在第一拍启动a这个Message*/ track.add(noteOn);/*d、将MidiEvent加到Track中,Track带有全部的MidiEvent对象,Sequence会根据事件时间组织他们, 然后Sequencer会根据次顺序来播放,同一时间可以执行多个操作,例如和弦声音或不同乐器的声音*/ ShortMessage b = new ShortMessage(); b.setMessage(128, 1, 44, 100); MidiEvent noteOff = new MidiEvent(b, 16); track.add(noteOff);//4、填入MidiEvent //4、将Sequence送到Sequencer上 player.setSequence(seq); //5、开始播放 player.start(); } catch(Exception ex) { ex.printStackTrace(); } }//关闭播放器 }//关闭类
****************************************************************************************************************************************************************************************************
个人整理
import javax.sound.midi.*; public class Test { public static void main(String[] args) { Test t = new Test(); t.play(); } public void play() { try { //1、取得Sequencer并将其打开 Sequencer player = MidiSystem.getSequencer();// 1 player.open(); //2、创建新的Sequence Sequence seq = new Sequence(Sequence.PPQ,4); // 2 //3、从Sequence中创建新的Track Track track = seq.createTrack(); // 3 /* 对Track加入几个MidiEvent,要注意的是setMessage()的参数, 以及MIdiEvent的constructor。 */ ShortMessage a = new ShortMessage();/*a、创建Message*/ a.setMessage(144, 1, 44, 100);/*b、置入指令,代表发出44音符*/ MidiEvent noteOn = new MidiEvent(a, 1);/*c、用Message创建MidiEvent,在第一拍启动a这个Message*/ track.add(noteOn);/*d、将MidiEvent加到Track中,Track带有全部的MidiEvent对象,Sequence会根据事件时间组织他们 然后Sequencer会根据次顺序来播放,同一时间可以执行多个操作,例如和弦声音或不同乐器的声音*/ ShortMessage b = new ShortMessage(); b.setMessage(128, 1, 44, 100); MidiEvent noteOff = new MidiEvent(b, 16); track.add(noteOff);//4、填入MidiEvent //4、将Sequence送到Sequencer上 player.setSequence(seq); //5、开始播放 player.start(); } catch(Exception ex) { ex.printStackTrace(); } }//关闭播放器 }//关闭类
1、 Sequencer player = MidiSystem.getSequencer();
Sequencer是一个接口,MidiSystem是一个类,但是MidiSystem所有的方法都是静态的(API文档),只是方法调用,而不是实例化一个对象。
效果如下(例子是非静态方法):
interface Dog {}//定义一个接口 class Cat { public Dog createDog() { System.out.println("hello");//提示System.out.println()语句放在return语句后面会报错:无法访问的语句System.out.println() return null; } } class Test { public static void main(String[] args) { Cat c = new Cat(); Dog d = c.createDog();//c.createDog返回的是Dog类型,可以用Dog类型的d指向c.createDog();若c.createDog返回的不是Dog类型,则不兼容,无法指向 } //对象赋值!!!!! }
2 Sequence seq = new Sequence(Sequence.PPQ,4);
Sequence是一个类,构造方法参数看API文档
3 Track track = seq.createTrack();
引用指向了方法返回的对象:
public class Test { public static void main(String[] args) { Cat c = new Cat(); Dog d = c.CreateDog();//解释 Track track = seq.createTrack(); } } class Dog { // } class Cat { public Dog CreateDog() { return null; } }