2009-09-28 19 views

Respuesta

4

Sí, la API de JavaSound se puede utilizar para leer datos MIDI desde un dispositivo MIDI.

JFugue es una API de Java para programación de música que utiliza la API de JavaSound, y puede ayudar a simplificar su interacción con JavaSound. En JFugue 5.x, código de ejemplo para capturar 10 segundos de datos MIDI desde un dispositivo MIDI es el siguiente:

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

También puede iniciar y detener la escucha de un dispositivo:

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

Si desea grabar con solo la API MIDI de Java (javax.sound.midi. *) esto se hace muy fácilmente. Este no es un código para copiar y pegar, pero debería ayudarlo a comenzar a programar su propia grabadora MIDI, lo cual es bastante fácil en realidad.

El primer paso es definir su MidiDevice de entrada y salida. Entonces, primero deberá encontrar una lista de posibilidades IO y hacer una GUI en la que pueda seleccionar el dispositivo de entrada y salida para su grabación y reproducción MIDI.

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

Así que hay una lista de sus dispositivos MIDI. A continuación, quiere seleccionar un dispositivo MIDI, por ejemplo, puede elegir los índices en la matriz de información.

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

También querrá especificar algunos globales: secuenciador, transmisor y receptor.

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

Ahora hay un botón de grabación que desea utilizar.

// 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(); 

Cuidado con, este código puede lanzar MidiUnavailableExceptions y debe llamar a los métodos de cerca todas las cosas que ha abierto finalmente en un comunicado.

Pero este es solo el núcleo de cómo debería ser el código. Registra todo en la secuencia seq tan pronto como llame al método sequencer.startRecording().

Luego desea detener la grabación y guardar la secuencia como MIDI en un archivo o reproducir. Por ejemplo, esto podría ser código cuando presiona el botón Detener grabación o algo así.

// 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")); 
} 

también la clase de pista (una secuencia puede tener varias pistas) contiene los datos de entrada reales, que se puede acceder fácilmente por un método get. La clase Track consta de MidiEvents.Por ejemplo, la pista es:

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... 

Y cada MidiEvent tiene una cierta marca de tiempo, que se expresa en las garrapatas MIDI, así que puede cambiar fácilmente el tempo aumentando o disminuyendo el número de pulsaciones por segundo.

El problema más difícil aquí es que los MidiEvents se expresan en código de bytes, por lo tanto, tendrá que usar una hoja de códigos de bytes de referencia que le indique qué byte representa qué acción. Esto debería comenzar con eso: http://www.onicos.com/staff/iz/formats/midi-event.html

+0

¿También puede proporcionar el código para usar la clase Track? Gracias. –

+1

@AliSharabiani Puede ver 'Track' como' List '. No hay mucho más que eso, [consulte también este documento de Oracle Java en javax.sound.midi.Track] (https://docs.oracle.com/javase/7/docs/api/javax/sound/midi/Track. html). – Yeti