also ich habe eine eigene Classe für Midi erzeut und hier mal der gesamte code:
Java:
public class MidiPort {
private MidiDevice.Info[] infos;
private MidiDevice midiIO;
private Receiver midiRcvr, seqRcvr;
private Transmitter midiTrans;
private Sequencer seqdev;
private int messinx;
Sequence mySeq;
Track seqspur;
boolean[] runLevel = { false, false, false, false, false, false };
// 0 Port Offen, 1 Sequnzer init, 2 Sequenz vorhanden, 3 Track vorhanden, 4 Record möglich, 5 aufzeichnen
String[] getMidiPorts() {
String[] sdev;
//MIDI:
infos = MidiSystem.getMidiDeviceInfo();
sdev = new String[infos.length];
for (int loo = 0; loo < infos.length; loo++) {
sdev[loo] = infos[loo].getName();
}
return sdev;
}
void openMidi(int devindex) {
if (devindex >= 0) {
// midiStatus = infos[devindex].getName();
// Midi Device öffnen
try {
midiIO = MidiSystem.getMidiDevice( infos[devindex] );
midiIO.open();
midiTrans = midiIO.getTransmitter();
runLevel[0]= true;
// midi port ok
} catch (MidiUnavailableException e1) {
//midiStatus = midiStatus + "Device Fehler /n" ;
//System.out.println("MIDI Geräte - Fehler!");
//e1.printStackTrace();
}
// sequencer einrichten
try {
seqdev = MidiSystem.getSequencer();
seqdev.open();
seqdev.setTempoInBPM(90);
seqRcvr = seqdev.getReceiver();
midiTrans.setReceiver(seqRcvr);
runLevel[1] = true;
// sequenzer ok
}
catch (MidiUnavailableException e1) {
// midiStatus = midiStatus + ("Sequenzer Error /n");
}
// sequence mit einem Track erzeugen
try {
mySeq = new Sequence(Sequence.PPQ, 8);
seqspur = mySeq.createTrack();
runLevel[2] = true;
runLevel[3] = true;
// sequenz und Track ok
} catch (Exception e1) {
//midiStatus = midiStatus + "Fehler beim anlegen von Squenz oder Track /n";
}
try {
seqdev.setSequence(mySeq);
// runLevel = runLevel | 8;
// squenzer hat sequenze
} catch (Exception e1) {
//midiStatus = midiStatus + ("kein Sequenze für Sequenzer /n");
}
// aufzeichen möglich machen
seqdev.recordEnable(seqspur, -1);
runLevel[4] = true;
} else { // none angewählt
if (runLevel[0]) {
midiTrans.close();
runLevel[0] = false;
}
} // end if
}
void recOnOff() {
if ( runLevel[4] ) {
if ( seqdev.isRecording() ) {
seqdev.stopRecording();
//seqdev.recordDisable(track);
runLevel[5] = false;
makeTestTrack();
File midfile = new File("my.mid");
try {
MidiSystem.write(mySeq, 2, midfile);
}
catch (IOException e ) {
}
} else {
seqdev.startRecording();
runLevel[5] = true;
messinx = 1;
}
}
}
String midiAsString() {
String zeile = "\n";
MidiEvent mereignis;
MidiMessage mmess;
byte[] datafeld;
int zwert;
if (messinx < seqspur.size()) {
zeile = zeile + Integer.toString(messinx) + ":";
mereignis = seqspur.get(messinx);
mmess = mereignis.getMessage();
datafeld = mmess.getMessage();
for (int loo = 0; loo < mmess.getLength(); loo++) {
zwert = (int) (datafeld[loo] & 0xff);
zeile = zeile + Integer.toHexString( zwert ) + " ";
// zeile = zeile + Byte.toString(datafeld[loo]) + " ";
}
zeile = zeile + Long.toString(mereignis.getTick());
messinx++;
}
return zeile;
}
boolean midiDatacomein() {
return (messinx < seqspur.size());
}
String getStatusAsTxt() {
String gszeile ;
gszeile = "MIDI Port Open " + Boolean.toString(runLevel[0]) + "\n";
gszeile = gszeile + "Sequenzer ON " + Boolean.toString(runLevel[1]) + "\n";
gszeile = gszeile + "Sequenze verfügbar " + Boolean.toString(runLevel[2]) + "\n";
gszeile = gszeile + "Track vorhandem " + Boolean.toString(runLevel[3]) + "\n";
gszeile = gszeile + "Record Enable " + Boolean.toString(runLevel[4]) + "\n";
gszeile = gszeile + "Recording " + Boolean.toString(runLevel[5]);
return gszeile;
}
void makeTestTrack() {
long tpos = 8;
seqspur = mySeq.createTrack();
ShortMessage msg ;
for (int tonleiter = 60; tonleiter < 70; tonleiter++) {
try {
msg = new ShortMessage();
msg.setMessage(ShortMessage.NOTE_ON, 0, tonleiter , 64);
seqspur.add(new MidiEvent(msg, tpos));
tpos = tpos + 8;
msg = new ShortMessage();
msg.setMessage(ShortMessage.NOTE_ON, 0, tonleiter, 0);
seqspur.add(new MidiEvent(msg, tpos));
tpos = tpos + 8;
} catch (Exception e) {
}
}
}
}
und in hier passiert der wichtige aufruf
ich starte die aufzeichnung über ein Event
Java:
private void jRadioRecordActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here: Record on / off
exmidi.recOnOff();
if (exmidi.runLevel[5]) {
// zeit.start();
} else {
zeit.stop();
}
jRadioRecord.setSelected( exmidi.runLevel[5] );
}
und dort erzeuge ich eine mididatei - ein track durch tastendruck und ein track zu kontrolle
und in dem midifile solle dann die MIDI daten autauchen wie z.b 0x90 0x3C 0x64
erste zahl bedeutet ton (90) an zweite bedeutet ton höhe (C) 3. zahl bedeutet die stärke
beschreibung aufbau MIDI Datei
http://www.larsrichter-online.de/lmids/midformat.htm
und hier der hexdump der datei
00000000 4d 54 68 64 00 00 00 06 00 01 00 02 00 08 4d 54 |MThd..........MT|
00000010 72 6b 00 00 00 2f 48 90 3c 73 02 3c 00 04 3e 66 |rk.../H.<s.<..>f|
00000020 02 3e 00 04 40 76 02 40 00 03 41 7b 02 41 00 04 |.>..@v.@..A{.A..|
00000030 43 7c 02 43 00 03 45 7b 02 45 00 04 47 7d 02 47 |C|.C..E{.E..G}.G|
00000040 00 00 ff 2f 00 4d 54 72 6b 00 00 00 41 08 90 3c |.../.MTrk...A..<|
00000050 40 08 3c 00 08 3d 40 08 3d 00 08 3e 40 08 3e 00 |@.<..=@.=..>@.>.|
00000060 08 3f 40 08 3f 00 08 40 40 08 40 00 08 41 40 08 |.?@.?..@@.@..A@.|
00000070 41 00 08 42 40 08 42 00 08 43 40 08 43 00 08 44 |A..B@.B..C@.C..D|
00000080 40 08 44 00 08 45 40 08 45 00 00 ff 2f 00 |@.D..E@.E.../.|
ab adresse 17 ist der erste Ton vorhanden und ab adresse x4E sollte der 2. track losgehen
soweit der wichtige teil
zum verständnis ich habe auf der Swing oberfläche eine Combo box die mir die verfügbaren MIDI Geräte anzeigt und ein Button um diese Liste neu auzubauen , dann gibt es noch ein Texfeld zur anzeige von ergebnissen (Jtextausgabe) und ein radiobutton zum starten der aufzeichnung und beenden.
dann gibts noch ein timer in dem ich einfach nachkucke ob was eingegangen ist
Java:
// eingefügt by susanne
MidiPort exmidi = new MidiPort();
javax.swing.Timer zeit = new javax.swing.Timer(83, new ClockListener());
// 83 ms = takt 90 8 tiks per takt
class ClockListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
// zeit abgelaufen
if (exmidi.midiDatacomein() ) {
jTextAusgabe.append( exmidi.midiAsString());
}
}
}
// ende
private void jComboMidiActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here: Midi Devices anzeigen
int pinx = jComboMidi.getSelectedIndex();
// achtung bei der übergabe minus eins da erster eintrag none
if (pinx > 0 ) {
exmidi.openMidi(pinx - 1);
}
jTextAusgabe.setText("Zeile " + Integer.toString(pinx)) ;
jTextAusgabe.append( exmidi.getStatusAsTxt());
}
private void jButtonMidiPortActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here: update Midi Devicelist in jComboMidi
String[] devl;
jComboMidi.removeAllItems();
jComboMidi.addItem("none");
devl = exmidi.getMidiPorts();
for (int loo=0 ; loo < devl.length; loo++ ) {
jComboMidi.addItem(devl[loo]);
}
}
damit sind alle codeteile online