ERLEDIGT
JA
JA
ANTWORTEN
18
18
ZUGRIFFE
1165
1165
EMPFEHLEN
-
Also als Level in Java habe ich immer noch begeisterte Anfängerin

OK zum Problem / Frage
Ich habe ein MIDI Keyboard an USB angeschlossen und suche nun eine Möglichkeit die MIDI Ereignisse (Taste am Keyboard gedrückt) in Java einzulesen. Ausgabe dann etwa so : Taste C gedrückt ...
Ich habe mich schon durch ettliche Beschreibungen durchgelesen - Wie man eine Midinote im System erzeugt und dann ausgibt wird beschrieben - über new ShortMessage() und denn myMsg.setMessage(ShortMessage.NOTE_ON, 0, 60, 93); z.B.
Aber ich sehe keine Möglichkeit an eine MIDI Message heranzukommen die von extern kommt.
Geht das überhaupt mit Java ? MIDI einlesen ?
das einzige was ich gefunden habe ist in der Classe Track ein Get um an ein MIDi Event heranzukommen.
Ich denke mal das geht nur wenn ich in der Klasse Sequence eine MIDI File einlese.
Oder Lege ich eine leere Sequence an, dann ein neuen Track und starte recording und kann dann ein Midi event das vom Keyboard kommt einlesen ?
Ich glaubs ja nicht ...
Also Frage an die Leute die sich besser auskennen - kann ich ein Midi Event das über USB kommt einlesen - wenn wenn ja wie muss ich vorgehen - grobe Richtung reicht mir erstmal - ich will ja wat lernen
Zusatzfrage - Device auflisten habe ich hinbekommen aber mein USB Keyboard taucht 3 mal auf .. woher weiss ich welches ich als MIDI IN ansprechen muss ?
und warum 3 mal ? 2 mal hätte ich ja verstanden einmal IN einmal OUT aber Nummer 3 ?Geändert von melmager (01.10.11 um 17:28 Uhr)
-
01.10.11 17:54 #2
- Registriert seit
- Jun 2009
- Beiträge
- 870
Prinzipiell geht das schon. Da das Gerät per USB angeschlossen ist, brauchst du aber einen Treiber für das MIDI-Keyboard. Und einen Java-Wrapper für diesen Treiber.
Alternative wäre, vom MIDI Keyboard in Datei schreiben und diese dann per Java auszulesen – das ist zwar nicht so schön, aber deutlich einfacher.
Hast du Treiber für das Gerät? Hast du schon eine Java-Bibliothek im Auge? oder eine native Bibliothek?Code bitte so einfügen: [java]System.out.println("Hallo");[/java] (Analog für andere Programmiersprachen)
hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.Code java:1
System.out.println("Hallo");
___________
Ubuntu Bug #1: Microsoft has a majority market share
Casecon: Projekt leiser Käse
-
Also Treiber für das Keyboard gibt es nicht.
Und als Wrapper habe ich auf die Schnelle nur den jVSTwRapper gefunden - der setzt auf Java auf.
was ich schon vorher gefunden habe ist dat:
http://www.jsresources.org/examples/MidiInDump.html
soweit ich das Programm verstehe machen die das tatsächlich so, das die eine Sequenze anlegen eine Midi Datei anlegen und dann die Datei auslesen.
Ich glaube ich werde dann doch dort mal ansetzen - mal kucken ob ich es hinbekomme dann zeitgleich aus der Midi Datei wider auszulesen
sprich erst MIDI Devices anzeigen - den Receiver und Transmitter entsprechend setzen, dann eine leere Sequenze und leeren Track anlegen , aufzeichnen und das dann ausgeben. Wenn dat soweit geht mal kucken wie ich an die MIDI Daten sofort rankomme und nicht Zeitversetzt.
Komisch wenn ich mir ein Projekt aussuche wird das immer etwas komplexerGeändert von melmager (02.10.11 um 09:39 Uhr)
-
02.10.11 11:20 #4
- Registriert seit
- Jun 2009
- Beiträge
- 870
Welches Betriebssystem nutzt du?
Auf Unixen müsstest du eigentlich auch in Pipes schreiben können, damit kannst du vom Treiber/Wrapper aus in eine virtuelle Datei schreiben und der Inhalt wird sofort an ein beliebiges Programm weitergeleitet.
Windows müsste so was ähnliches (abgespeckt) können, aber damit kenn ich mich nicht so aus...Code bitte so einfügen: [java]System.out.println("Hallo");[/java] (Analog für andere Programmiersprachen)
hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.Code java:1
System.out.println("Hallo");
___________
Ubuntu Bug #1: Microsoft has a majority market share
Casecon: Projekt leiser Käse
-
Also MIDI ist schon eine Plattform Übergreifende Schnittstelle! Schließlich wird diese von diversen Elektronischen Musikinstrumenten benutzt und Java macht nichts anderes als die MIDI Bytes aus dem System zu lesen (oder zu schrieben) die in der Hardware rum düsen!!
Dein Ansatz mit der myMsg.setMessage(ShortMessage.NOTE_ON, 0, 60, 93) ist nicht verkehrt, aber schon mal daran gedacht das du das MIDI Signal nur lesen müsstest und die werte die du bekommst um zu formatieren. Schau mal in die Sourcen der Standard Java Bibliothek, du musst ja eigentlich nur auf dem System MIDI stream (in den Sourcen müsste man sehen können welcher das ist) Lauschen und die Hex werte Korrekt Interpretieren, dann müsstest du dir die Umwege über die Sound Objekte in Java sparen.
Sounds mit Java, gerade wenn man so Hardware nahe ist wie hier, sind recht unterentwickelt. Das einzige was in Java richtig gut geht ist fertige Sound Formate.
-
Tja die Frage ist doch wie komme ich an den Stream dran
ich kenne stream von von Dateioperationen
Transmitter und Receiver kennen keine Function Stream
sprich ich wüsste nicht wie ich da auf die MIDI Functionen einen Stream draufsetzen soll -
http://download.oracle.com/javase/6/...ansmitter.htmlGeändert von melmager (05.10.11 um 13:25 Uhr)
-
Nö, ich meinte nicht den Stream von irgenwo holen sondern aus den Sourcen (QuellCode) raus lesen wie es in der Java Bib gemacht wird und selber erzeugen (und Werte auslesen).
In der java Bib wandeln die selber die werte die du rein gibst (und raus holst) irgendwo in Hex (von Hex zu java Repräsentation) Werte um und diese werden an die MIDI Komponente im Computer gesandt, diese stelle müsstest du dir mal anschauen und für deine Zwecke ab- und umschreiben.
Wenn du in deiner Entwiklungsumgebung das JDK hast ist das kein problem, ich habe nur leider keine zeit das für dich raus zu suchen
-
das ist mir zu komplex - dazu habe ich noch zu wenig ahnung von Java
Ich hatte mal vor Jahren ein Projekt mit JNI - und da war es nur ein Zugriff auf ein bestehenden Treiber der in C geschrieben war - da bin ich ja schon schier verzweifelt weil die damaligen Beschreibungen eher ungenau waren
Ich werde mich mal melden wenn ich das Problem gelöst habe - da ich aber auch in Swing einsteige mit dem Projekt kann dat etwas dauern - im moment habe ich auch ein paar Verständnisprobleme mit Swing
-
ich verstehe mal wider nix (ok das ist Dauerzustand
)
ich habe eine eigene Midi Classe erstellt
und da ist diese declaration drin:
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13
private MidiDevice.Info[] infos; String[] getMidiPorts() { //MIDI: infos = MidiSystem.getMidiDeviceInfo(); // hier ist das Array gefüllt und kann zugegriffen werden //...... code .... return sdev; } void openMidi(int devindex) { // und hier ist infos ungülig - bzw leer }
wenn ich aber in einer Function das Array nutze ist es in der nächsten Function leer
ich dachte immer Variablen sind innerhalb der Classe immer gültig ?Geändert von melmager (11.10.11 um 18:01 Uhr)
-
11.10.11 18:07 #10
- Registriert seit
- Jun 2009
- Beiträge
- 870
1. In welcher Reihenfolge die Methoden in einer Klasse stehen, ist völlig irrelevant! wahrscheinlich hast du die Methode openMidi() vor der Methode getMidiPorts() aufgerufen. Das ist so weit auch ok.
2. Du solltest eine Methode erstellen, die den Midi-Zugriff initialisiert. In diese Methode gehört dann so was wie die Zuweisung. Dazu gibt es 4 Wege:Code java:1
infos = MidiSystem.getMidiDeviceInfo();
a) Initialisierung in einem static-Block (nicht empfehlenswert, verzögert den Start der Anwendung unnötig
b) Initialisierung im Constructor
c) Initialisierung per init-Methode (nicht empfehlenswert da fehleranfällig wenn diese init-Methode nicht aufgerufen wurde
d) Initialisierung beim ersten mal, wenn eine Methode aufgerufen wird, die diese Daten braucht (umständlich)Code bitte so einfügen: [java]System.out.println("Hallo");[/java] (Analog für andere Programmiersprachen)
hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.Code java:1
System.out.println("Hallo");
___________
Ubuntu Bug #1: Microsoft has a majority market share
Casecon: Projekt leiser Käse
-
Jepp ich habe die Stelle gefunden wo openMidi aufgerufen wurde -
ich glaube ich muss im Programm anders vorgehen
kann man eine Comobox neu aufbauen wenn man sie angeklickt hat ?
also mit
Code java:1 2
jComboMidi.removeAllItems(); jComboMidi.addItem("none");
arbeiten wenn man da drin ist :
private void jComboMidiActionPerformed(java.awt.event.ActionEvent evt) { }
?
im Moment habe ich ein Button der dafür sorgt das die Liste der MidiPorts neu eingelesen wird - währe natürlich eleganter wenn ich das in einem Aufwasch machen könnte
Nachtrag:
ich glaube ich habe ein BUG in swing Combobox gefunden - COOL
ich habe zwei identische Einträge in Position 2 und 3 - aber ich bekomme es nicht hin das er sagt es wurde Eintrag 3 angesprochen - er sagt immer 2
scheinbar wird bei jComboMidi.getSelectedIndex(); über den String im Eintrag gearbeitet und wenn zwei identische gibt gibt er immer die erste Position anGeändert von melmager (11.10.11 um 18:59 Uhr)
-
11.10.11 22:02 #12
- Registriert seit
- Jun 2009
- Beiträge
- 870
Natürlich geht das.
zum Nachtrag: man kann sich darüber streiten, ob das ein Bug ist. Meiner Meinung nach ist es keiner, weil man sowieso keine 2 identischen Elemente in eine Combobox hinzufügt
Code bitte so einfügen: [java]System.out.println("Hallo");[/java] (Analog für andere Programmiersprachen)
hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.Code java:1
System.out.println("Hallo");
___________
Ubuntu Bug #1: Microsoft has a majority market share
Casecon: Projekt leiser Käse
-
Tja mittlerweile bin ich soweit das mein Programm erkennt das eine Taste am Keyboard gedrückt wurde.
Leider kommen nur blödsinnsdaten an
die frage ist - warum
im Moment habe ich keine Idee dazu
auch wenn ich das erzeugte MIDI File speichere und mir dann per hexdump den inhalt ansehe sieht das nicht so aus wie ein Midi File aussehen soll
Nachtrag:
Nu verstehe ich nix mehr
ich füge in einem zweiten Track daten direkt über shortmessage ein und auch da sieht mein MIDI File nicht so aus wie es sein sollte
Geändert von melmager (20.10.11 um 22:15 Uhr)
-
Drei fragen,
wie sieht dein file aus? und wie sollte es aussehen?
Und wie sieht der Code aus mit dem du deine Message erzeugst?
Es kann keiner helfen wenn er das Problem nicht sehen kann
-
also ich habe eine eigene Classe für Midi erzeut und hier mal der gesamte code:
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
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
Code java:1 2 3 4 5 6 7 8 9 10
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
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
// 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
Geändert von melmager (21.10.11 um 19:45 Uhr)
Ähnliche Themen
-
Java und Sound
Von wakoz im Forum JavaAntworten: 0Letzter Beitrag: 07.07.10, 01:24 -
Tasten eines Midi-Keyboard mit einzelnen Sound belegen
Von Topfi im Forum Audiotechnik, Recording & Audio-SoftwareAntworten: 5Letzter Beitrag: 04.03.10, 18:33 -
MIDI-Daten an virtuelles MIDI-Interface übergeben
Von zionse im Forum Coders TalkAntworten: 0Letzter Beitrag: 30.06.09, 17:03 -
Java Sound
Von Nick0110 im Forum Swing, Java2D/3D, SWT, JFaceAntworten: 2Letzter Beitrag: 02.03.07, 17:42 -
Sound und Midi Programierung in C++
Von sonixs im Forum C/C++Antworten: 1Letzter Beitrag: 22.02.03, 17:33





Zitieren
Login





