当前位置: 首页 > 工具软件 > Beatbox > 使用案例 >

BeatBox播放器

梁鸿风
2023-12-01
package book;

import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;

public class BeatBox {
	JPanel mainPanel;
	ArrayList<JCheckBox> checkboxsList;
	Sequencer sequencer;
	Sequence sequence;
	Track track;
	JFrame frame;
	//乐器的名称
	String[] instrumentNames = {"Bass Drum","Closed Hi-Hat","open Hi Hat"
			,"Acoustic Snare"," Crash Cymbal","Hand Clap","High Tom ","Hi Bonggo",
			"Maracas","Whistle","Low Conga","Cowbell","Vibraslap","Low-mid Tom","High Agogo",
			"open Hi Conga"};
	//乐器的关键词例如35是bass
	int [] instruments= {35,42,46,38,49,39,50,60,70,72,64,56,58,47,67,63};
	

	public static void main(String[] args) {
		new BeatBox().buildGUI();

	}
	public void buildGUI() {
		JFrame theFrame = new JFrame("Cyber BeatBox");
		theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口时关闭程序
		BorderLayout layout = new BorderLayout();
		JPanel background = new JPanel();
		background.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));//设定面板上摆设组件的空白边缘
		
		checkboxsList = new ArrayList<JCheckBox>();
		Box buttonBox = new Box(BoxLayout.Y_AXIS);
		
		JButton start = new JButton("start");
		start.addActionListener(new MyStartListener());
		buttonBox.add(start);
		
		JButton stop = new JButton("stop");
		stop.addActionListener(new MyStopListener());
		buttonBox.add(stop);
		
		JButton upTempo = new JButton("Tempo Up");
		upTempo.addActionListener(new MySUpTempoListener());
		buttonBox.add(upTempo);
		
		JButton downTempo = new JButton("Tempo Down");
		downTempo.addActionListener(new MyDownTempoListener());
		buttonBox.add(downTempo);
		
		Box nameBox = new Box(BoxLayout.Y_AXIS);
		for (int i=0; i<16;i++) {
			nameBox.add(new Label(instrumentNames[i]));
			
		}
		background.add(BorderLayout.EAST,buttonBox);
		background.add(BorderLayout.WEST,nameBox);
		
		theFrame.getContentPane().add(background);
		
		GridLayout grid = new GridLayout(16,16);//网格布局
		grid.setVgap(1);//设置组件之间的垂直距离
		grid.setVgap(2);
		mainPanel = new JPanel(grid);
		background.add(BorderLayout.CENTER,mainPanel);
		//创建checkbox组,设定为未勾选的为false并加到ArrayList和面板上
		for (int i=0;i<256;i++) {
			JCheckBox c = new JCheckBox();
			c.setSelected(false);
			checkboxsList.add(c);
			mainPanel.add(c);
		}//循环结束
		setUpMidi();
		theFrame.setBounds(50,50,300,300);
		theFrame.pack();
		theFrame.setVisible(true);
	}//关闭方法
	public void setUpMidi() {
		try {
			sequencer = MidiSystem.getSequencer();
			sequencer.open();
			sequence =new Sequence(Sequence.PPQ, 4);
			track =sequence.createTrack();
			sequencer.setTempoInBPM(120);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}//关闭方法
	public void buildTrackAndStart() {
		int [] trackList = null;//创建出16个元素的数组来存储一项乐器的值,如果要演奏,其值为关键字,否则为0
		
		sequence.deleteTrack(track);
		track = sequence.createTrack();//去掉旧的track 做一个新的
		
		for (int i=0;i<16; i++) {//对每个乐器都执行一次
			trackList = new int[16];
			
			int key = instruments[i];//代表乐器的关键字
			
			for(int j=0;j<16;j++) {//对每一拍执行一次
				JCheckBox jc = (JCheckBox)checkboxsList.get(j+(16*i));
				//如果有勾选,将关键字值放到数组得该位置上,不然补0
				if(jc.isSelected()) {
					trackList[j]=key;
				}else {
					trackList[j]=0;
				}
			}//关闭内部循环
			
			makeTracks(trackList);//创建此乐器的事件并加到track上
			track.add(makeEvent(176,1,127,0,16));
			
		}//关闭外部循环
		
		
		track.add(makeEvent(192,9,1,0,15));//确保16拍有事件,否则beatbox不会重复播放
		
		try {
			sequencer.setSequence(sequence);
			sequencer.setLoopCount(sequencer.LOOP_CONTINUOUSLY);//播放无数次
			sequencer.start();//开始播放
			sequencer.setTempoInBPM(120);
			
		}catch(Exception e)
		{
			e.printStackTrace();
		}
	}//关闭buildTrackAndStart方法
	
	
	
	
	public class MyStartListener implements ActionListener{
		public void actionPerformed(ActionEvent a) {
			buildTrackAndStart();
		}
	}//关闭内部类
	
	public class MyStopListener implements ActionListener{
		public void actionPerformed(ActionEvent a) {
			sequencer.stop();
		}
	}//关闭内部类
	
	public class MySUpTempoListener implements ActionListener{
		public void actionPerformed(ActionEvent a) {
			float tempoFactor = sequencer.getTempoFactor();
			sequencer.setTempoFactor((float)(tempoFactor*1.03));//节奏团子,每次调整0.03
		}
	}//关闭内部类
	
	public class MyDownTempoListener implements ActionListener{
		public void actionPerformed(ActionEvent a) {
			float tempoFactor = sequencer.getTempoFactor();
			sequencer.setTempoFactor((float)(tempoFactor*0.97));
		}
	}//关闭内部类
	
	
	
	public void makeTracks(int[] list) {
		
		for(int i=0;i<16;i++) {
			int key = list[i];
			if(key!=0) {
				track.add(makeEvent(144,9,key,100,i));//144表示开始
				track.add(makeEvent(128,9,key,100,i+1));//128表示结束
			}
		}
	}
	
	public 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);
			event = new MidiEvent(a,tick);
		}catch(Exception e) {
			e.printStackTrace();
		}
		return event;
		
	}
	

}//关闭类

 类似资料: