第12章-图形用户接口(3)---动画-2-音乐播放器

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();
		
	}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值