Jon*_*han 11 java keyboard midi input javasound
我在java中设计了自己的合成器,现在我想用midi键盘连接它.我的下面的课程搜索所有具有发射器的midi设备.它成功找到我的midi键盘.我为每个设备添加了自己的接收器到每个发射器,以便它可以拾取所有可能的东西.通过阅读所有帮助文档和java doc,我知道Transmitter将MidiEvents发送给Receiver,然后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() {}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:我已经看过:Java MIDI - 从钢琴获取数据?.
这个:http://www.jsresources.org/examples/MidiInDump.html
接口Sequencer看起来很复杂,我也想要.
小智 15
我发现,在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() {}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的硬件上(我插入了一个简单的USB MIDI控制器),代码在创建MidiHandler实例后正确打印出"midi received".
希望这可以帮助!