2009-09-28 19 views
7

Ich habe ein Java-Projekt geerbt, das an old C++ dll to receive MIDI data von einem mit dem Computer verbundenen Klavier verwendete.Java MIDI - Daten vom Piano holen?

Jetzt, da Java integrierte Unterstützung für MIDI-Geräte hat, möchte ich die alte C++ - DLL loswerden und nur reines Java verwenden. Unterstützt Java das Empfangen von Daten von einem an den Computer angeschlossenen Piano? Ich habe Google vergeblich nach Beispielen gesucht.

Antwort

4

Ja, die JavaSound-API kann zum Lesen von MIDI-Daten von einem MIDI-Gerät verwendet werden.

JFugue ist eine Java-API für die Musikprogrammierung, die die JavaSound-API verwendet und die Interaktion mit JavaSound vereinfachen kann. In JFugue 5.x Codebeispiel 10 Sekunden von MIDI-Daten zu erfassen, von einem MIDI-Gerät wie folgt:

MidiDevice device = /* specify a MIDI device */ 
MusicTransmitterToSequence transmitter = new MusicTransmitterToSequence(device); 
transmitter.listenForMillis(10000); 
Sequence music = transmitter.getSequence(); 

Sie auch eine Vorrichtung zu hören beginnen und beenden:

MidiDevice device = /* specify a MIDI device */ 
MusicTransmitterToSequence transmitter = new MusicTransmitterToSequence(device); 
transmitter.startListening(); 
// Do stuff 
transmitter.stopListening(); 
Sequence music = transmitter.getSequence(); 
13

Wenn Sie Ich möchte mit nur der MIDI-API von Java (javax.sound.midi. *) aufnehmen, dies ist sehr einfach. Dies ist kein Code zum Kopieren und Einfügen, aber es sollte Ihnen helfen, mit der Programmierung Ihres eigenen MIDI-Recorders zu beginnen, was eigentlich ziemlich einfach ist.

Der erste Schritt besteht darin, Ihre Eingabe und Ausgabe MidiDevice zu definieren. Zuerst müssen Sie eine Liste von IO-Möglichkeiten finden und eine GUI erstellen, in der Sie das Ein- und Ausgabegerät für Ihre MIDI-Aufnahme und -Wiedergabe auswählen können.

Info[] infos = MidiSystem.getMidiDeviceInfo(); 
for(int i=0;i<infos.length;i++) 
{ 
    System.out.println(infos[i].getName() + " - " + infos[i].getDescription()); 
} 

Es gibt also eine Liste Ihrer MIDI-Geräte. Als nächstes möchten Sie ein MIDI-Gerät auswählen, zum Beispiel können Sie die Indizes im infos-Array auswählen.

MidiDevice inputDevice = MidiSystem.getMidiDevice(infos[x]); 
MidiDevice outputDevice = MidiSystem.getMidiDevice(infos[y]); 

Sie werden auch einige Globals angeben wollen: Sequenzer, Sender und Empfänger.

Sequencer sequencer = MidiSystem.getSequencer(); 
Transmitter transmitter; 
Receiver receiver; 

Jetzt gibt es eine Record-Taste, die Sie verwenden möchten.

// Open a connection to your input device 
inputDevice.open(); 
// Open a connection to the default sequencer (as specified by MidiSystem) 
sequencer.open(); 
// Get the transmitter class from your input device 
transmitter = inputDevice.getTransmitter(); 
// Get the receiver class from your sequencer 
receiver = sequencer.getReceiver(); 
// Bind the transmitter to the receiver so the receiver gets input from the transmitter 
transmitter.setReceiver(receiver); 

// Create a new sequence 
Sequence seq = new Sequence(Sequence.PPQ, 24); 
// And of course a track to record the input on 
Track currentTrack = seq.createTrack(); 
// Do some sequencer settings 
sequencer.setSequence(seq); 
sequencer.setTickPosition(0); 
sequencer.recordEnable(currentTrack, -1); 
// And start recording 
sequencer.startRecording(); 

Vorsicht, kann dieser Code MidiUnavailableExceptions werfen und Sie sollten die Nähe Methoden auf all die Dinge, rufen Sie in einer finally-Anweisung geöffnet haben.

Aber das ist nur der Kern dessen, wie der Code aussehen sollte. Es zeichnet alles auf die Sequenz seq auf, sobald Sie die Methode sequencer.startRecording() aufrufen.

Dann möchten Sie die Aufnahme stoppen und in der Lage sein, die Sequenz als MIDI in eine Datei zu speichern oder eine Wiedergabe zu machen. Dies könnte zum Beispiel Code sein, wenn Sie die Schaltfläche Aufnahme stoppen oder etwas drücken.

// Stop recording 
if(sequencer.isRecording()) 
{ 
    // Tell sequencer to stop recording 
    sequencer.stopRecording(); 

    // Retrieve the sequence containing the stuff you played on the MIDI instrument 
    Sequence tmp = sequencer.getSequence(); 

    // Save to file 
    MidiSystem.write(tmp, 0, new File("MyMidiFile.mid")); 
} 

Auch die Track-Klasse (eine Folge mehrere Spuren haben kann) enthält die eigentlichen Eingangsdaten, die Sie leicht durch eine get-Methode zugreifen können. Die Track-Klasse besteht aus MidiEvents.Zum Beispiel die Strecke ist:

MidiEvent 0: The C key is pressed 
MidiEvent 1: The D key is pressed 
MidiEvent 2: The C key of MidiEvent 0 is released 
MidiEvent 3: The sustain pedal is pressed 
etc... 

Und jedes Midievent hat einen gewissen Zeitstempel, die in MIDI Ticks ausgedrückt wird, so können Sie einfach das Tempo ändern, durch Erhöhen oder die Anzahl der Ticks pro Sekunde abnimmt.

Das schwierigste Problem hier ist, dass MidiEvents in Byte-Code ausgedrückt werden, daher müssen Sie ein Referenz-Byte-Codeblatt verwenden, das Ihnen sagt, welches Byte welche Aktion darstellt. Dies sollte Sie damit beginnen: http://www.onicos.com/staff/iz/formats/midi-event.html

+0

Können Sie auch den Code zur Verwendung der Track-Klasse bereitstellen? Vielen Dank. –

+1

@AliSharabiani Sie können "Track" als "Liste " sehen. Es gibt nicht viel mehr, [siehe auch dieses Oracle Java-Dokument auf javax.sound.midi.Track] (https://docs.oracle.com/javase/7/docs/api/javax/sound/midi/Track. html). – Yeti