气死我了, 在此之前写了两个多小时的Ruby学习记录居然,没有提交上,丢了!
修改了一个BeatBox的网络版本, 觉得有点儿意思
可以保存并载入自己普的曲目
这个程序是通过调用midi发出声音的
而且做了网络功能来使得不同的客户端共享自己的创作.
Enjoy!
是HeadFirst Java中的BeatBox 的改进版
package practice;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class BeatBox {
private JPanel mainPanel;
private ArrayList<JCheckBox> checkBoxList;
private JFrame frame;
private File file;
private MidiPlayer midiPlayer;
private JButton sendButton;
private JButton start;
private JButton stop;
private JButton tempoUp;
private JButton tempoDown;
private JButton randomButton;
private JList incomingList;
private JTextField userMessage;
private Socket socket;
private ObjectOutputStream writer;
private ObjectInputStream reader;
private Vector<String> receivedKeyList = new Vector<String>();
private HashMap<String, boolean[]> receivedPlayList = new HashMap<String, boolean[]>();
private String[] instrumentNames = {"Bass Drum", "Closed Hi-Hat",
"Open Hi-Hat", "Acousetic Snare", "Crash Symble", "Hand Clap",
"High Tom", "Hi Bongo", "Maracas", "Whistle", "Low conga",
"Cow Bell", "Vibraslap", "Low-mid Tom", "High Agogo",
"Open Hi-Congo"};
private final int PORT=5000;
private String serverIp = "127.0.0.1";
public String getServerIp() {
return serverIp;
}

public void setServerIp(String serverIp) {
this.serverIp = serverIp;
}

public static void main(String[] args){
BeatBox beatBox = new BeatBox();
beatBox.buildGUI();
beatBox.initMidiSystem();
if(beatBox.setupSocketAndStream()){
beatBox.createLisnenerThread();
beatBox.enableSend();
}
}
private void initMidiSystem(){
// setup midi
midiPlayer = new MidiPlayer();
midiPlayer.setUpMidi();
}
private boolean setupSocketAndStream(){
try{
socket = new Socket(serverIp,PORT);
reader = new ObjectInputStream(socket.getInputStream());
writer = new ObjectOutputStream(socket.getOutputStream());
return true;
}catch(Exception e){
e.printStackTrace();
System.out.println("couldn't connect to server,you have to play alone.");
return false;
}
}
private void createLisnenerThread(){
Thread remote = new Thread(new RemoteReader());
remote.setName("reader");
remote.start();
}
class RemoteReader implements Runnable{
public void run(){
BeatBoxSendingData data = null;
try{
while((data = (BeatBoxSendingData)reader.readObject())!=null){
receivedPlayList.put(data.getName(), data.getBeatList());
receivedKeyList.add(data.getName());
incomingList.setListData(receivedKeyList);
}
}catch(Exception e){
e.printStackTrace();
System.out.print("Maybe Server is closeed.");
}
}
}
private void enableSend(){
sendButton.setEnabled(true);
}
private void buildGUI(){
frame = new JFrame("Cyber BeatBox");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BorderLayout layout = new BorderLayout();
JPanel background = new JPanel(layout);
background.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// create button
Box buttonBox = new Box(BoxLayout.Y_AXIS);
start = new JButton("Start");
start.addActionListener(new MyStartActionListener());
buttonBox.add(start);
stop = new JButton("Stop");
stop.addActionListener(new MyStopActionListener());
buttonBox.add(stop);
tempoUp = new JButton("Tempo Up");
tempoUp.addActionListener(new MyTempoUpActionListener());
buttonBox.add(tempoUp);
tempoDown = new JButton("Tempo Down");
tempoDown.addActionListener(new MyTempoDownActionListener());
buttonBox.add(tempoDown);
randomButton = new JButton("Random Create Music");
randomButton.addActionListener(new MyRandomActionListener());
buttonBox.add(randomButton);
JButton saveButton = new JButton("Save");
saveButton.addActionListener(new MySaveActionListener());
buttonBox.add(saveButton);
JButton loadButton = new JButton("Load");
loadButton.addActionListener(new MyLoadActionListener());
buttonBox.add(loadButton);
sendButton = new JButton("Send");
sendButton.addActionListener(new MySendActionListener());
sendButton.setEnabled(false);
buttonBox.add(sendButton);
userMessage = new JTextField();
buttonBox.add(userMessage);
incomingList = new JList();
incomingList.addListSelectionListener(new MyListSelectionListener());
incomingList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane scroller = new JScrollPane(incomingList);
buttonBox.add(scroller);
incomingList.setListData(receivedKeyList);
// create instruction
Box nameBox = new Box(BoxLayout.Y_AXIS);
Font font = new Font("Arial", Font.PLAIN, 18);
JLabel label = null;
for(int i=0; i<16; i++){
label = new JLabel(instrumentNames[i]);
label.setFont(font);
nameBox.add(label);
}
// create checkbox
checkBoxList = new ArrayList<JCheckBox>();
GridLayout grid = new GridLayout(16, 16);
grid.setHgap(2);
grid.setVgap(1);
mainPanel = new JPanel(grid);
for(int i=0;i<256;i++){
JCheckBox c = new JCheckBox();
c.setSelected(false);
mainPanel.add(c);
checkBoxList.add(c);
}// close loop
// add three parts
background.add(BorderLayout.EAST, buttonBox);
background.add(BorderLayout.WEST, nameBox);
background.add(BorderLayout.CENTER, mainPanel);
frame.getContentPane().add(background);
frame.setBounds(50,50,300,300);
frame.pack();
frame.setVisible(true);
makeStopingGUI();
}// close method
private void makeStopingGUI(){
start.setEnabled(true);
stop.setEnabled(false);
tempoUp.setEnabled(false);
tempoDown.setEnabled(false);
}
private void makeRunningGUI(){
start.setEnabled(false);
stop.setEnabled(true);
tempoUp.setEnabled(true);
tempoDown.setEnabled(true);
}
class MyStartActionListener implements ActionListener{
public void actionPerformed(ActionEvent event){
midiPlayer.buildTrackAndStart(checkBoxList);
makeRunningGUI();
}
}
class MyStopActionListener implements ActionListener{
public void actionPerformed(ActionEvent event){
midiPlayer.stop();
makeStopingGUI();
}
}
class MyTempoUpActionListener implements ActionListener{
public void actionPerformed(ActionEvent event){
midiPlayer.setTempoFactor((float)(midiPlayer.getTempoFactor()*1.03));
}
}
class MyTempoDownActionListener implements ActionListener{
public void actionPerformed(ActionEvent event){
midiPlayer.setTempoFactor((float)(midiPlayer.getTempoFactor()*0.97));
}
}
class MyRandomActionListener implements ActionListener{
public void actionPerformed(ActionEvent event){
updateGUI(getRandomMusicList());
}
}
private boolean[] getRandomMusicList(){
boolean[] list = new boolean[256];
int count = (int)(Math.random()*96);
for(int i=0; i< count; i++){
list[(int)(Math.random()*256)] = true;
}
return list;
}
class MySaveActionListener implements ActionListener{
public void actionPerformed(ActionEvent event){
boolean[] checkBoxState = getStateList();
file = getFile2Save();
if(file == null){
return;
}
serializeState(checkBoxState);
}
}
private boolean[] getStateList(){
boolean[] checkBoxState = new boolean[256];
for(int i=0; i<256; i++){
if(checkBoxList.get(i).isSelected()){
checkBoxState[i] = true;
}
}
return checkBoxState;
}
private File getFile2Save(){
JFileChooser chooser = new JFileChooser(file);
chooser.showSaveDialog(frame);
return chooser.getSelectedFile();
}
private void serializeState(boolean[] checkBoxState){
try{
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
objectOutputStream.writeObject(checkBoxState);
objectOutputStream.close();
}catch(Exception e){
e.printStackTrace();
}
}
class MyLoadActionListener implements ActionListener{
public void actionPerformed(ActionEvent event){
file = getSavedFile();
if(file == null){
return;
}
boolean[] checkBoxState = loadFile2List();
updateGUI(checkBoxState);
}
}
private File getSavedFile(){
JFileChooser chooser = new JFileChooser(file);
chooser.showOpenDialog(frame);
return chooser.getSelectedFile();
}
private boolean[] loadFile2List(){
boolean[] state = new boolean[256];
try{
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
state = (boolean[])objectInputStream.readObject();
objectInputStream.close();
}catch(Exception e){
e.printStackTrace();
}
return state;
}
private void updateGUI(boolean[] checkBoxState){
for(int i=0; i<256; i++){
checkBoxList.get(i).setSelected(checkBoxState[i]);
}
}
class MySendActionListener implements ActionListener{
public void actionPerformed(ActionEvent event){
try{
writer.writeObject(new BeatBoxSendingData(userMessage.getText(), getStateList()));
userMessage.setText("");
}catch(Exception e){
e.printStackTrace();
System.out.println("maybe connection crashed!");
}
}
}
class MyListSelectionListener implements ListSelectionListener{
public void valueChanged(ListSelectionEvent event){
if(event.getValueIsAdjusting()){
String selection = (String)incomingList.getSelectedValue();
if(selection != null){
updateGUI(receivedPlayList.get(selection));
midiPlayer.stop();
midiPlayer.buildTrackAndStart(checkBoxList);
makeRunningGUI();
}
}
}
}
}
package practice;

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.JCheckBox;

public class MidiPlayer {
private Sequencer sequencer;
private Sequence sequence;
private Track track;
private int[] instrument = {35,42,46,38,49,39,50,60,70,72,64,56,58,47,67,63};
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(ArrayList<JCheckBox> checkBoxList){
int[] trackList = null;
sequence.deleteTrack(track);
track = sequence.createTrack();
for(int i=0; i<16; i++){
trackList = new int[16];
int key = instrument[i];
for(int j=0;j<16;j++){
JCheckBox jc = checkBoxList.get(i*16+j);
if(jc.isSelected()){
trackList[j] = key;
}else{
trackList[j] = 0;
}
}// close inner loop
makeTracks(trackList);
track.add(makeEvent(176,1,127,0,16));
}// close outer loop
track.add(makeEvent(192,9,1,0,15));
try{
sequencer.setSequence(sequence);
sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
sequencer.start();
sequencer.setTempoInBPM(120);
}catch(Exception e){
e.printStackTrace();
}
}
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));
track.add(makeEvent(128,9,key,100,i+1));
}
}
}
public MidiEvent makeEvent(int command, int chanel, int one, int two, int ticks){
MidiEvent event = null;
try{
ShortMessage a = new ShortMessage();
a.setMessage(command, chanel, one, two);
event = new MidiEvent(a, ticks);
}catch(Exception e){
e.printStackTrace();
}
return event;
}
public void stop(){
sequencer.stop();
}
public double getTempoFactor(){
return sequencer.getTempoFactor();
}
public void setTempoFactor(float factor){
sequencer.setTempoFactor(factor);
}
public void start(){
sequencer.start();
}
}
package practice;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class MusicServer {
private ArrayList<MusicClientInfo> musicClientList;
private final int PORT=5000;
public static void main(String[] args){
(new MusicServer()).go();
}
private void go(){
musicClientList = new ArrayList<MusicClientInfo>();
try{
ServerSocket serverSocket = new ServerSocket(PORT);
while(true){
Socket socket = serverSocket.accept();
MusicClientInfo client = new MusicClientInfo(socket);
musicClientList.add(client);

Thread thread = new Thread(new Runner(client));
thread.start();
System.out.println("Got a new connection from: " + client.getClientInfo());
}
}catch(Exception e){
e.printStackTrace();
}
}
class Runner implements Runnable{
MusicClientInfo client;
public Runner(MusicClientInfo client){
this.client = client;
try{
this.client = client;
}catch(Exception e){
e.printStackTrace();
}
}
public void run(){
BeatBoxSendingData data = null;
try{
while((data = (BeatBoxSendingData)client.getReader().readObject()) != null){
System.out.println("Get data: " + data.getName() +" from " + client.getClientInfo());
tellEveryOne(data);
}
}catch(Exception e){
//e.printStackTrace();
System.out.println("Maybe this client off: " + client.getClientInfo());
client.closeSocket();
musicClientList.remove(client);
}
}
public void tellEveryOne(BeatBoxSendingData data){
try{
for(MusicClientInfo client : musicClientList){
client.getWriter().writeObject(data);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}
package practice;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class MusicClientInfo {
private Socket socket;
private ObjectOutputStream writer;
private ObjectInputStream reader;
private String clientIp;
private int clientPort;
public MusicClientInfo(Socket socket){
this.socket = socket;
clientIp = socket.getInetAddress().getHostAddress();
clientPort = socket.getPort();
try{
/*must be first writer then reader*/
writer = new ObjectOutputStream(socket.getOutputStream());
reader = new ObjectInputStream(socket.getInputStream());
}catch(Exception e){
e.printStackTrace();
}
}
public String getClientIp() {
return clientIp;
}
public void setClientIp(String clientIp) {
this.clientIp = clientIp;
}
public int getClientPort() {
return clientPort;
}
public void setClientPort(int clientPort) {
this.clientPort = clientPort;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
public ObjectInputStream getReader() {
return reader;
}
public void setReader(ObjectInputStream reader) {
this.reader = reader;
}
public ObjectOutputStream getWriter() {
return writer;
}
public void setWriter(ObjectOutputStream writer) {
this.writer = writer;
}
public void closeSocket(){
try{
reader.close();
writer.close();
socket.close();
}catch(Exception e){
e.printStackTrace();
}
}
public String getClientInfo(){
return getClientIp() + ":" + getClientPort();
}
}
修改了一个BeatBox的网络版本, 觉得有点儿意思
可以保存并载入自己普的曲目
这个程序是通过调用midi发出声音的
而且做了网络功能来使得不同的客户端共享自己的创作.
Enjoy!
是HeadFirst Java中的BeatBox 的改进版








































































































































































































































































































































































































































































































































































































































