Java MIDI – 从钢琴获取数据?

我inheritance了一个Java项目, 该项目使用旧的C ++ dll从连接到计算机的钢琴接收MIDI数据 。

现在Java已经内置了对MIDI设备的支持,我想摆脱传统的C ++ DLL并且只使用纯Java。 Java是否支持从连接到计算机的钢琴接收数据? 我搜索谷歌的例子无济于事。

是的,JavaSound API可用于从MIDI设备读取MIDI数据。

JFugue是一个使用JavaSound API的音乐编程Java API,可以帮助简化与JavaSound的交互。 在JFugue 5.x中,从MIDI设备捕获10秒MIDI数据的示例代码如下:

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

您也可以开始和停止收听设备:

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

如果你想用Java(javax.sound.midi。*)只用MIDI api录音,这很容易完成。 这不是复制和粘贴的代码,但它应该可以帮助您开始编程自己的MIDI录音机,这实际上非常简单。

第一步是定义输入和输出MidiDevice。 因此,首先您必须找到IO可能性列表并制作一个GUI,您可以在其中选择用于MIDI录制和播放的输入和输出设备。

 Info[] infos = MidiSystem.getMidiDeviceInfo(); for(int i=0;i 

所以有一个MIDI设备列表。 接下来,您要选择MIDI设备,例如,您可以选择信息数组中的索引。

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

您还需要指定一些全局变量:音序器,发送器和接收器。

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

现在有一个你想要使用的记录按钮。

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

请注意 ,此代码可以抛出MidiUnavailableExceptions,您应该在finally语句中打开的所有内容上调用close方法。

但这只是代码应该是什么样子的核心。 一旦调用方法sequencer.startRecording()它就会将所有内容记录到Sequence seq中。

然后,您想要停止录制,并能够将序列作为MIDI保存到文件中,或者进行播放。 例如,当您按下“停止记录”按钮或其他内容时,这可能是代码。

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

Track类(一个序列可以有多个轨道)也包含实际的输入数据,您可以通过get方法轻松访问这些数据。 Track类由MidiEvents组成。 例如,Track是:

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

每个MidiEvent都有一个特定的时间戳,用MIDI Ticks表示,因此你可以通过增加或减少每秒的滴答数来轻松改变速度。

这里最难的问题是MidiEvents用字节代码表示,因此你必须使用一个参考字节代码表来告诉你哪个字节代表什么动作。 这应该可以帮助您: http : //www.onicos.com/staff/iz/formats/midi-event.html