まぁ、何か作ってますよ程度のもの。Java FXとJava Sound APIを使って遊んでるだけです
import javafx.stage.Stage; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.BorderPane; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.animation.Animation; import javafx.util.Duration; import java.io.File; import java.util.List; import javax.xml.bind.JAXB; import javax.sound.midi.Receiver; import javax.sound.midi.MidiSystem; import javax.sound.midi.ShortMessage; import net.d_kami.midi.data.MidiNote; import net.d_kami.midi.data.MidiTrack; import net.d_kami.midi.data.MidiMusic; import javax.sound.midi.InvalidMidiDataException; public class MidiTest extends Application { private Receiver receiver; private Timeline timer; private int timerCount = 0; private int bassIndex = 0; private int drumIndex = 0; private MidiMusic music; public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { receiver = MidiSystem.getReceiver(); music = JAXB.unmarshal(new File("midi.xml"), MidiMusic.class); Button button = createMidiButton("8ビート!"); BorderPane pane = new BorderPane(); pane.setCenter(button); Scene scene = new Scene(pane, 320, 120); stage.setScene(scene); stage.show(); } private Button createMidiButton(String text){ loadProgram(); setTempo(120); return createButton(text); } private Button createButton(String text){ Button button = new Button(text); button.setOnAction(e -> { if(timer.getStatus() == Animation.Status.STOPPED){ timer.setCycleCount(160); timer.play(); } }); return button; } private void setTempo(int bpm){ int duration = 60000 / bpm * 4 / 128; setTimer(duration); } private void setTimer(int duration){ List<MidiTrack> tracks = music.getTracks(); int[] indices = new int[tracks.size()]; timer = new Timeline(new KeyFrame(Duration.millis(duration), event -> { try{ for(int i = 0; i < tracks.size(); i++){ MidiTrack track = tracks.get(i); midiEvent(track, duration, indices, i); } }catch(InvalidMidiDataException ex){ ex.printStackTrace(); } timerCount++; })); } private void loadProgram(){ music.getTracks().forEach(track -> { try{ programChange(track.getNumber(), track.getProgram()); }catch(InvalidMidiDataException e){ e.printStackTrace(); } }); } private void programChange(int trackNumber, int program) throws InvalidMidiDataException{ ShortMessage message = new ShortMessage(); message.setMessage(ShortMessage.PROGRAM_CHANGE, trackNumber, program, 0); receiver.send(message, -1); } private void midiEvent(MidiTrack track, int duration, int[] indices, int i) throws InvalidMidiDataException{ List<MidiNote> notes = track.getNotes(); if(indices[i] < notes.size()){ MidiNote note = notes.get(indices[i]); if(duration * timerCount > note.getPosition()){ note(track.getNumber(), note.getType(), note.getNote(), note.getVelocity()); indices[i]++; } } } private void note(int trackNumber, int type, int note, int velocity) throws InvalidMidiDataException{ ShortMessage message = new ShortMessage(); message.setMessage(type, trackNumber, note, velocity); receiver.send(message, -1); } }