Java MIDI - ottenere i dati dal pianoforte?
Domanda
Ho ereditato un progetto Java che utilizza una DLL vecchio C ++ per ricevere i dati MIDI da un pianoforte collegato al computer.
Ora che Java è dotato di supporto per i dispositivi MIDI, voglio sbarazzarsi dell'eredità C ++ dll e basta usare Java puro. Fa supporto Java che riceve i dati da un pianoforte collegato al computer? Ho cercato di Google per gli esempi senza alcun risultato.
Soluzione
Sì, l'API JavaSound può essere utilizzato per leggere i dati MIDI da un dispositivo MIDI.
JFugue è un'API Java per la programmazione musicale che utilizza l'API JavaSound, e possono contribuire a semplificare l'interazione con JavaSound. In JFugue 5.x, codice di esempio per catturare 10 secondi di dati MIDI da un dispositivo MIDI è la seguente:
MidiDevice device = /* specify a MIDI device */
MusicTransmitterToSequence transmitter = new MusicTransmitterToSequence(device);
transmitter.listenForMillis(10000);
Sequence music = transmitter.getSequence();
È inoltre possibile avviare e interrompere l'ascolto di un dispositivo:
MidiDevice device = /* specify a MIDI device */
MusicTransmitterToSequence transmitter = new MusicTransmitterToSequence(device);
transmitter.startListening();
// Do stuff
transmitter.stopListening();
Sequence music = transmitter.getSequence();
Altri suggerimenti
Se si desidera registrare con il solo api MIDI da Java (javax.sound.midi. *) Questo è fatto molto facilmente. Questo non è il codice da copiare e incollare, ma dovrebbe aiutare a iniziare a programmare il proprio registratore MIDI, che è abbastanza facile in realtà.
Il primo passo è quello di definire l'input e l'output MidiDevice. Quindi, prima si dovrà trovare un elenco di possibilità IO e fare una GUI in cui è possibile selezionare il dispositivo di input e di output per la registrazione e la riproduzione MIDI.
Info[] infos = MidiSystem.getMidiDeviceInfo();
for(int i=0;i<infos.length;i++)
{
System.out.println(infos[i].getName() + " - " + infos[i].getDescription());
}
Quindi non v'è un elenco dei dispositivi MIDI. Avanti si desidera selezionare un dispositivo MIDI, ad esempio, si arriva a scegliere gli indici nella matrice informazioni.
MidiDevice inputDevice = MidiSystem.getMidiDevice(infos[x]);
MidiDevice outputDevice = MidiSystem.getMidiDevice(infos[y]);
È inoltre vorranno specificare alcune variabili globali:. Sequencer, trasmettitore e ricevitore
Sequencer sequencer = MidiSystem.getSequencer();
Transmitter transmitter;
Receiver receiver;
Ora c'è un pulsante di registrazione che si desidera utilizzare.
// 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();
Attenzione , questo codice può buttare MidiUnavailableExceptions e si dovrebbe chiamare i metodi stretti su tutte le cose che hai aperto in finally.
Ma questo è solo il nucleo di ciò che il codice dovrebbe essere simile. Registra tutto il seq
sequenza non appena si chiama il metodo sequencer.startRecording()
.
Poi si desidera interrompere la registrazione, ed essere in grado di salvare la sequenza come MIDI in un file, o di fare una riproduzione. Per esempio, questo potrebbe essere il codice quando si preme il pulsante di registrazione Arresto o qualcosa del genere.
// 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"));
}
Anche la classe Track (una sequenza può avere più tracce) contiene i dati di input effettivi, che si può facilmente accedere con un metodo get. La classe Traccia è costituito da MidiEvents. Per esempio la traccia è:
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...
E ogni MIDIEVENT ha una certa data e ora, che si esprime in MIDI zecche, in tal modo è possibile modificare facilmente il tempo aumentando o diminuendo il numero di tick per secondo.
Il problema più difficile qui è che MidiEvents sono espressi in byte code, quindi si dovrà utilizzare un foglio di codice byte di riferimento che ti dice cosa byte rappresenta l'azione. Questo dovrebbe iniziare con questo: http://www.onicos.com /staff/iz/formats/midi-event.html