[英]Java getting input from MIDI keyboard
我已經用 Java 設計了自己的合成器,現在想將它與 MIDI 鍵盤連接。 我下面的班級搜索所有帶有發射器的MIDI設備。 它成功找到了我的 MIDI 鍵盤。 我將自己的接收器添加到每個設備的每個發射器中,以便它可以接收所有可能的信息。 通過閱讀所有幫助文檔和 java 文檔,我知道 Transmitter 將 MidiEvents 發送到 Receiver,然后使用 send 方法處理它們。 因此,我編寫了自己的內部類實現 Receiver,並僅使用 println 語句來檢查 send 方法中是否檢測到任何內容。 然而,什么都沒有被拾取。 做這么簡單的事情似乎沒有什么幫助,我已經查看了每個幫助文件、javadoc 和論壇。 我敢肯定它一定是我不知何故錯過的非常明顯的東西。
我的合成器不應該與界面合成器混淆,它不是 MIDI 樂器。 它使用合成算法並具有播放方法。 基本上我只需要讓 MIDI 鍵盤發送一個關於事件的注釋,該事件將調用播放方法。
import javax.sound.midi.*;
import java.util.ArrayList;
import java.util.List;
import java.io.*;
public class MidiHandler
{
//ArrayList of MidiDevices
private ArrayList<MidiDevice> devices = new ArrayList<MidiDevice>();
public MidiHandler()
{
MidiDevice device;
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
for (int i = 0; i < infos.length; i++) {
try {
device = MidiSystem.getMidiDevice(infos[i]);
//does the device have any transmitters?
if (device.getTransmitters().size() > 0) {
//if it does, add it to the device list
System.out.println(infos[i] + ": " + device.getTransmitters().size());
devices.add(device);
}
} catch (MidiUnavailableException e) {}
}
//if any transmitting devices were found
if(devices.size()>0) {
//for each device
for(int i = 0; i<devices.size(); i++) {
try {
//get all transmitters
List<Transmitter> transmitters = devices.get(i).getTransmitters();
//and for each transmitter
for(int j = 0; j<transmitters.size();j++) {
//create a new receiver
transmitters.get(i).setReceiver(
//using my own MidiInputReceiver
new MidiInputReceiver(devices.get(i).getDeviceInfo().toString())
);
}
//open each device
devices.get(i).open();
//if code gets this far without throwing an exception
//print a success message
System.out.println(devices.get(i).getDeviceInfo()+" Was Opened");
} catch (MidiUnavailableException e) {}
}
}
}
//tried to write my own class. I thought the send method handles an MidiEvents sent to it
public class MidiInputReceiver implements Receiver {
public String name;
public MidiInputReceiver(String name) {
this.name = name;
}
public void send(MidiMessage msg, long timeStamp) {
System.out.println("midi received");
}
public void close() {}
}
}
注意:我已經看過這個: Java MIDI - 從鋼琴獲取數據? .
和這個: http : //www.jsresources.org/examples/MidiInDump.html
界面 Sequencer 對於我想要的東西看起來也很復雜。
我發現,在MidiDevice的getTransmitters()似乎返回當前已經打開發射器,而不是發射了可被打開的列表。 我相信打開新發射器的方法是通過 getTransmitter() 方法。 我已經修改了你的代碼來做到這一點:
import javax.sound.midi.*;
import java.util.ArrayList;
import java.util.List;
import java.io.*;
public class MidiHandler
{
public MidiHandler()
{
MidiDevice device;
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
for (int i = 0; i < infos.length; i++) {
try {
device = MidiSystem.getMidiDevice(infos[i]);
//does the device have any transmitters?
//if it does, add it to the device list
System.out.println(infos[i]);
//get all transmitters
List<Transmitter> transmitters = device.getTransmitters();
//and for each transmitter
for(int j = 0; j<transmitters.size();j++) {
//create a new receiver
transmitters.get(j).setReceiver(
//using my own MidiInputReceiver
new MidiInputReceiver(device.getDeviceInfo().toString())
);
}
Transmitter trans = device.getTransmitter();
trans.setReceiver(new MidiInputReceiver(device.getDeviceInfo().toString()));
//open each device
device.open();
//if code gets this far without throwing an exception
//print a success message
System.out.println(device.getDeviceInfo()+" Was Opened");
} catch (MidiUnavailableException e) {}
}
}
//tried to write my own class. I thought the send method handles an MidiEvents sent to it
public class MidiInputReceiver implements Receiver {
public String name;
public MidiInputReceiver(String name) {
this.name = name;
}
public void send(MidiMessage msg, long timeStamp) {
System.out.println("midi received");
}
public void close() {}
}
}
在我的硬件上(我插入了一個簡單的 USB MIDI 控制器),在創建 MidiHandler 實例后,代碼正確打印出“midi received”。
希望這可以幫助!
我發現您必須在調用 setRecceiver() 之前打開設備,否則接收器的 send() 方法會被調用上次運行應用程序時的垃圾 MIDI 數據。
device.open();
Transmitter trans = device.getTransmitter();
// set new receiver after opening so that the input buffer will be flushed
trans.setReceiver(new MidiInputReceiver(device.getDeviceInfo().toString()));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.