home | suche | kontakt/johner | institut studierende | tech-docs | mindmailer |
![]() |
Ein erster Versuch: StartMidi
package midi;
import java.io.IOException;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Sequence;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;
/**
* Diese Klasse erstellt eigene Midi-Sequence uns spielt sie ab.
*/
public class MidiStart {
private final static int PPQS = 16; // Auflösung pro Viertelnote
private final static int STAKKATO = 8; //Abkürzung einer Stakkatonote in PPQS
public static void main(String[] args) throws InvalidMidiDataException, MidiUnavailableException, IOException{
MidiStart start = new MidiStart();
Sequence sequence = start.generateSequence();
SequencePlayer.playSequence(sequence);
}
private Sequence generateSequence() throws InvalidMidiDataException {
// MIDI-Daten-Organisation (Sequence, Track) erstellen
Sequence seq = new Sequence(Sequence.PPQ, PPQS);
Track track = seq.createTrack();
long currentTick = 0; // Aktuelle Zeitposition in PPQS
//Kanal 0 auf "EnsembleStrings" umschalten
ShortMessage msg = new ShortMessage();
msg.setMessage(ShortMessage.PROGRAM_CHANGE, 8, 48, 0);
track.add(new MidiEvent(msg, currentTick));
//Partiturdaten hinzufügen
currentTick = generateTone(track, currentTick, 60, 1, 64, 1);
currentTick = generateTone(track, currentTick, 60, 1, 64, 5);
currentTick = generateTone(track, currentTick, 60, 1, 64, 7);
currentTick = generateTone(track, currentTick, 60, 1, 64, 8);
currentTick = generateTone(track, currentTick, 16, 1, 64, 10);
currentTick = generateTone(track, currentTick, 60, 1, 64, 12);
currentTick = generateTone(track, currentTick, 62, 2, 127, 7);
currentTick = generateTone(track, currentTick, 60, 1, 32, 3);
return seq;
}
/**
*
* @param track: Instrument/Stimme
* @param currentTick aktuelle Position
* @param ton Tonhöhe (C entspricht 60, C# 61, D 62 usw.
* @param dauer: in Viertelnoten
* @param laut: Lautstärke (0-127)
* @param channel: Kanal (0-15) Spezialfall 10: Schlagzeug (Jede Tonhöhe = anderes Instrument)
* @return neue aktuelle Position
* @throws InvalidMidiDataException --
*/
private long generateTone(Track track, long currentTick, int ton, int dauer, int laut, int channel) throws InvalidMidiDataException {
ShortMessage msg = new ShortMessage();
// Note-On-Message generieren
msg.setMessage(ShortMessage.NOTE_ON, channel, ton, laut);//
track.add(new MidiEvent(msg, currentTick));
currentTick += PPQS * dauer - STAKKATO;
// Note-Off-Message generieren
msg = new ShortMessage();
msg.setMessage(ShortMessage.NOTE_OFF, channel, ton, 0);
track.add(new MidiEvent(msg, currentTick));
currentTick += STAKKATO;
return currentTick;
}
}
SequencePlayer
package midi;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.Synthesizer;
import javax.sound.midi.Track;
import javax.sound.midi.Transmitter;
/**
* Diese Klasse spielt existierende Midi-Datei und gibt Werte aus.
*/
public class SequencePlayer {
public static void playSequence(Sequence seq)
throws InvalidMidiDataException, MidiUnavailableException {
// Sequencer und Synthesizer initialisieren
Sequencer sequencer = MidiSystem.getSequencer();
Synthesizer synth = MidiSystem.getSynthesizer();
Transmitter trans = sequencer.getTransmitter();
Receiver rcvr = synth.getReceiver();
// Beide öffnen und verbinden
sequencer.open();
synth.open();
trans.setReceiver(rcvr);
// Sequence abspielen
sequencer.setSequence(seq);
sequencer.setTempoInBPM(120);
sequencer.start();
// Warten, bis der Sequencer seine Arbeit beendet hat...
while (true) {
try {
Thread.sleep(100);
} catch (Exception e) {
// nothing
}
if (!sequencer.isRunning()) {
break;
}
}
// Sequencer anhalten und Geräte schließen
sequencer.stop();
sequencer.close();
synth.close();
}
public static Sequence loadSequence(String fileName) throws IOException,
InvalidMidiDataException, MidiUnavailableException {
Sequencer sequencer = MidiSystem.getSequencer();
FileInputStream filestream = new FileInputStream(new File(fileName));
BufferedInputStream stream = new BufferedInputStream(filestream);
sequencer.setSequence(stream);
return sequencer.getSequence();
}
/**
* Gibt Midi-Daten der Sequenz aus
*
* @param seq
*/
public static void dumpSequence(Sequence seq) {
Track[] tracks = seq.getTracks();
for (int i = 0; i < tracks.length; i++) {
System.out.println("Dumping Track " + i);
Track track = tracks[i];
for (int j = 0; j < track.size(); j++) {
MidiEvent event = track.get(j);
MidiMessage message = event.getMessage();
long time = event.getTick();
byte[] part = message.getMessage();
System.out.print("Message " + j + " with time " + time + ": ");
for (int k = 0; k < part.length; k++) {
System.out.print("<" + part[k] + ">");
}
System.out.println();
}
}
}
}
Beispieldatei
Dieses Midifile kann man den SequencePlayer ausgeben lassen: Clocks von Coldplay