2015/6/17
注意:
1、设置每分钟的节拍数量,BPM节拍数
sequencer.setTempoInBPM(220);
2、ControllerEventListener 接口应由一个其实例需要在 Sequencer 处理了请求的 MIDI 控制更改事件类型时接收通知的类实现。
需要实现public void controlChange(ShortMessage event)方法
3、a.setMessage(command,channel,one,two)
command - 此消息所表示的 MIDI 命令 channel - 与此消息关联的通道 data1 - 第一个数据字节 data2 - 第二个数据字节
4、
向sequencer注册事件,注册的方法取用监听者与代表想要聆听的事件的int数组,我们只需要127事件
第二个输入的值是用来监控特定的事件的。
int[] eventsIWant={127};
sequencer.addControllerEventListener(ml,eventsIWant);
5、插入事件编号为176的自定义ControllerEvent(176),它不会做任何事情,只是让我们知道有音符被播放,因为它的tick跟NoteOn是同时进行的。
track.add(makeEvent(176,1,127,0,i));
第一版:
package MiDiMusic;
import javax.sound.midi.*;
public class MiniMusicPlayer1 {
public static void main(String[] args){
try{
//创建节拍的序列
Sequencer sequencer=MidiSystem.getSequencer();
sequencer.open();
Sequence seq=new Sequence(Sequence.PPQ,4);
//创建音轨
Track track=seq.createTrack();
for(int i=5;i<61;i+=4){
//向音轨上添加节拍
//音符的开始
track.add(makeEvent(144,1,i,100,i));
//音符的结束
track.add(makeEvent(128,1,i,100,i+2));
}
//将音轨设置进拍序器
sequencer.setSequence(seq);
//设置每分钟的节拍数量,BPM节拍数
sequencer.setTempoInBPM(220);
sequencer.start();
}catch(Exception ex){ex.printStackTrace();}
}
//静态方法,用来生成MidiEvent对象
//不用静态方法,创建一个类对象,然后调用也可以,但这样比较方便。
public static MidiEvent makeEvent(int comd,int chan, int one,int two,int tick){
MidiEvent event=null;
try{
ShortMessage a=new ShortMessage();
a.setMessage(comd,chan,one,two);
//将a设置在tick节拍处。
event=new MidiEvent(a,tick);
}catch(Exception e){}
return event;
}
}
第二版
package MiDiMusic;
import javax.sound.midi.*;
//ControllerEventListener 接口应由一个其实例需要在 Sequencer 处理了请求的 MIDI 控制更改事件类型时接收通知的类实现。
public class MiniMusicPlayer2 implements ControllerEventListener{
public static void main(String[] args){
MiniMusicPlayer2 mini=new MiniMusicPlayer2();
mini.go();
}
void go(){
try{
//创建节拍的序列
Sequencer sequencer=MidiSystem.getSequencer();
sequencer.open();
//向sequencer注册事件,注册的方法取用监听者与代表想要聆听的事件的int数组,我们只需要127事件
//第二个输入的值是用来监控特定的事件的。
int[] eventsIWant={127};
sequencer.addControllerEventListener(this, eventsIWant);
Sequence seq=new Sequence(Sequence.PPQ,4);
//创建音轨
Track track=seq.createTrack();
for(int i=5;i<61;i+=4){
//向音轨上添加节拍
//音符的开始
track.add(makeEvent(144,1,i,100,i));
//插入事件编号为176的自定义ControllerEvent(176),它不会做任何事情,只是让我们知道有音符被播放,因为它的tick跟NoteOn是同时进行的。
track.add(makeEvent(176,1,127,0,i));
//音符的结束
track.add(makeEvent(128,1,i,100,i+2));
}
//将音轨设置进拍序器
sequencer.setSequence(seq);
//设置每分钟的节拍数量,BPM节拍数
sequencer.setTempoInBPM(220);
sequencer.start();
}catch(Exception ex){ex.printStackTrace();}
}
//静态方法,用来生成MidiEvent对象
//command - 此消息所表示的 MIDI 命令 channel - 与此消息关联的通道 data1 - 第一个数据字节 data2 - 第二个数据字节
public static MidiEvent makeEvent(int comd,int chan, int one,int two,int tick){
MidiEvent event=null;
try{
ShortMessage a=new ShortMessage();
a.setMessage(comd,chan,one,two);
//将a设置在tick节拍处。
event=new MidiEvent(a,tick);
}catch(Exception e){}
return event;
}
@Override
//当音符发出时,即事件触发时,输出。
public void controlChange(ShortMessage event) {
System.out.println("la");
// TODO 自动生成的方法存根
}
}
第三版:
package MiDiMusic;
import javax.sound.midi.*;
import javax.swing.*;
public class MiniMusicPlayer3{
static JFrame f=new JFrame();
static MyDrawPanel ml;
public static void main(String[] args){
MiniMusicPlayer3 mini=new MiniMusicPlayer3();
mini.go();
}
void setUpGui(){
ml=new MyDrawPanel();
f.getContentPane().add(ml);
f.setBounds(30, 30, 300, 300);
f.setVisible(true);
}
void go(){
setUpGui();
try{
//创建节拍的序列
Sequencer sequencer=MidiSystem.getSequencer();
sequencer.open();
//向sequencer注册事件,注册的方法取用监听者与代表想要聆听的事件的int数组,我们只需要127事件
//第二个输入的值是用来监控特定的事件的。
int[] eventsIWant={127};
sequencer.addControllerEventListener(ml,eventsIWant);
Sequence seq=new Sequence(Sequence.PPQ,4);
//创建音轨
Track track=seq.createTrack();
int r=0;
for(int i=5;i<61;i+=4){
//向音轨上添加节拍
//音符的开始
r=(int)((Math.random()*50)+1);
track.add(makeEvent(144,1,r,100,i));
//插入事件编号为176的自定义ControllerEvent(176),它不会做任何事情,只是让我们知道有音符被播放,因为它的tick跟NoteOn是同时进行的。
track.add(makeEvent(176,1,127,0,i));
//音符的结束
track.add(makeEvent(128,1,r,100,i+2));
}
//将音轨设置进拍序器
sequencer.setSequence(seq);
//设置每分钟的节拍数量,BPM节拍数
sequencer.setTempoInBPM(120);
sequencer.start();
}catch(Exception ex){ex.printStackTrace();}
}
//静态方法,用来生成MidiEvent对象
//command - 此消息所表示的 MIDI 命令 channel - 与此消息关联的通道 data1 - 第一个数据字节 data2 - 第二个数据字节
public static MidiEvent makeEvent(int comd,int chan, int one,int two,int tick){
MidiEvent event=null;
try{
ShortMessage a=new ShortMessage();
a.setMessage(comd,chan,one,two);
//将a设置在tick节拍处。
event=new MidiEvent(a,tick);
}catch(Exception e){}
return event;
}
}
package MiDiMusic;
import java.awt.*;
import javax.sound.midi.*;
import javax.swing.*;
public class MyDrawPanel extends JPanel implements ControllerEventListener{
boolean msg=false;//
public void paintComponent(Graphics g){
if(msg){
//Graphics2D g2=(Graphics2D)g;
int r=(int)(Math.random()*255);
int gr=(int)(Math.random()*255);
int b=(int)(Math.random()*255);
g.setColor(new Color(r,gr,b));
int ht=(int)((Math.random()*120)+10);
int width=(int)((Math.random()*120)+10);
int x=(int)((Math.random()*40)+10);
int y=(int)((Math.random()*40)+10);
g.fillRect(x, y, width, ht);
msg=false;
}
}
public void controlChange(ShortMessage event) {
msg=true;
repaint();
}
}