Java MIDI - 从钢琴获取数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1485307/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java MIDI - getting data from piano?
提问by Judah Gabriel Himango
I've inherited a Java project that used an old C++ dll to receive MIDI datafrom a piano connected to the computer.
我继承了一个 Java 项目,该项目使用旧的 C++ dll从连接到计算机的钢琴接收 MIDI 数据。
Now that Java has built-in support for MIDI devices, I want to get rid of the legacy C++ dll and just use pure Java. Does Java support receiving data from a piano connected to the computer?I've searched Google for examples to no avail.
既然 Java 内置了对 MIDI 设备的支持,我想摆脱遗留的 C++ dll 并只使用纯 Java。Java 是否支持从连接到计算机的钢琴接收数据?我已经在 Google 上搜索了示例,但无济于事。
采纳答案by David Koelle
Yes, the JavaSound API can be used to read MIDI data from a MIDI device.
是的,JavaSound API 可用于从 MIDI 设备读取 MIDI 数据。
JFugueis a Java API for music programming that uses the JavaSound API, and can help simplify your interaction with JavaSound. In JFugue 5.x, sample code to capture 10 seconds of MIDI data from a MIDI device is as follows:
JFugue是用于音乐编程的 Java API,它使用 JavaSound 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();
You can also start and stop listening to a device:
您还可以开始和停止收听设备:
MidiDevice device = /* specify a MIDI device */
MusicTransmitterToSequence transmitter = new MusicTransmitterToSequence(device);
transmitter.startListening();
// Do stuff
transmitter.stopListening();
Sequence music = transmitter.getSequence();
回答by Yeti
If you want to record with just the MIDI api by Java (javax.sound.midi.*) this is done very easily. This is not code to copy and paste, but it should help you to start programming your own MIDI recorder, which is quite easy actually.
如果您只想使用 Java (javax.sound.midi.*) 的 MIDI api 进行录音,这很容易完成。这不是复制和粘贴的代码,但它应该可以帮助您开始编写自己的 MIDI 录音机,这实际上很容易。
The first step is to define your input and output MidiDevice. So first you will have to find a list of IO possibilities and make a GUI in which you can select the input and output device for your MIDI recording and playback.
第一步是定义您的输入和输出 MidiDevice。因此,首先您必须找到一个 IO 可能性列表并制作一个 GUI,您可以在其中选择 MIDI 录音和播放的输入和输出设备。
Info[] infos = MidiSystem.getMidiDeviceInfo();
for(int i=0;i<infos.length;i++)
{
System.out.println(infos[i].getName() + " - " + infos[i].getDescription());
}
So there is a list of your MIDI devices. Next you want to select a MIDI device, for example you get to choose the indexes in the infos array.
所以有一个你的 MIDI 设备列表。接下来您要选择一个 MIDI 设备,例如您可以选择 infos 数组中的索引。
MidiDevice inputDevice = MidiSystem.getMidiDevice(infos[x]);
MidiDevice outputDevice = MidiSystem.getMidiDevice(infos[y]);
You also will want to specify some globals: sequencer, transmitter and receiver.
您还需要指定一些全局变量:音序器、发送器和接收器。
Sequencer sequencer = MidiSystem.getSequencer();
Transmitter transmitter;
Receiver receiver;
Now there is a record button you want to use.
现在有一个您要使用的录制按钮。
// 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();
Beware, this code can throw MidiUnavailableExceptions and you should call the close methods on all the things you've opened in a finally statement.
请注意,此代码可能会抛出 MidiUnavailableExceptions,您应该对在 finally 语句中打开的所有内容调用 close 方法。
But this is just the core of what the code should look like. It records everything to the Sequence seqas soon as you call the method sequencer.startRecording().
但这只是代码应该是什么样子的核心。seq只要您调用该方法,它就会将所有内容记录到 Sequence中sequencer.startRecording()。
Then you want to stop the recording, and be able to save the sequence as MIDI to a file, or do a playback. For example this could be code when you press the Stop record button or something.
然后您想停止录音,并能够将序列作为 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"));
}
Also the Track class (a sequence can have multiple tracks) contains the actual input data, which you can easily access by a get method. The Track class consists of MidiEvents. For example the Track is:
此外,Track 类(一个序列可以有多个轨道)包含实际的输入数据,您可以通过 get 方法轻松访问这些数据。Track 类由 MidiEvents 组成。例如轨道是:
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...
And every MidiEvent has a certain timestamp, which is expressed in MIDI Ticks, thus you can easily change the tempo by increasing or decreasing the number of ticks per second.
并且每个 MidiEvent 都有一个特定的时间戳,以 MIDI Ticks 表示,因此您可以通过增加或减少每秒的滴答数来轻松更改速度。
The hardest problem here is that MidiEvents are expressed in byte code, thus you will have to use a reference byte code sheet which tells you what byte represents what action. This should get you started with that: http://www.onicos.com/staff/iz/formats/midi-event.html
这里最难的问题是 MidiEvents 是用字节码表示的,因此你必须使用一个参考字节码表来告诉你什么字节代表什么动作。这应该让你开始:http: //www.onicos.com/staff/iz/formats/midi-event.html

