使用 javax.sound.midi 接收 midi 输入
Receive midi input with javax.sound.midi
我想要一个程序,当它获得 MIDI 输入时可以做一些事情。
例如,当我点击控制器上的按钮 1 时,它应该打印 "You clicked btn 1",而当我点击按钮 2 时,它应该打印 "You clicked btn 2".
我尝试使用 javax.sound.midi 库,但论坛或 youtube 上的所有示例均无效。
这对我来说最有效。它打印了我 PC 的所有 Midi 设备,但没有收到任何东西。有人可以帮忙吗?
package de.snke.dev;
import javax.sound.midi.*;;
public class Main extends Object implements Receiver{
static MidiClass myMidi;
public static void main(String[] args) throws Exception {
MidiDevice.Info[] info =
MidiSystem.getMidiDeviceInfo();
for (int i=0; i < info.length; i++) {
System.out.println(i + ") " + info[i]);
System.out.println("Name: " + info[i].getName());
System.out.println("Description: " +
info[i].getDescription());
MidiDevice device =
MidiSystem.getMidiDevice(info[i]);
System.out.println("Device: " + device);
}
}
public void send(MidiMessage msg,
long time) {
System.out.println("Received message " + msg);
}
public void close() {
System.out.println("Closing");
}
}
编辑:现在我有
Sequencer seq;
Transmitter seqTrans;
Synthesizer synth;
Receiver synthRcvr;
try {
seq = MidiSystem.getSequencer();
seqTrans = seq.getTransmitter();
synth = MidiSystem.getSynthesizer();
synthRcvr = synth.getReceiver();
seqTrans.setReceiver(synthRcvr);
} catch (MidiUnavailableException e) {
// handle or throw exception
}
我现在连接到我的 APC Mini 了吗?对不起我是初学者...
如果是,我现在如何读取 MIDI 输入?如果否,我需要更改什么?
解决方法是:
package de.snke.dev;
import javax.sound.midi.*;
import java.util.ArrayList;
import java.util.List;
import java.io.*;
public class Main
{
public void Main()
{
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) {
byte[] aMsg = msg.getMessage();
// take the MidiMessage msg and store it in a byte array
// msg.getLength() returns the length of the message in bytes
for(int i=0;i<msg.getLength();i++){
System.out.println(aMsg[i]);
// aMsg[0] is something, velocity maybe? Not 100% sure.
// aMsg[1] is the note value as an int. This is the important one.
// aMsg[2] is pressed or not (0/100), it sends 100 when they key goes down,
// and 0 when the key is back up again. With a better keyboard it could maybe
// send continuous values between then for how quickly it's pressed?
// I'm only using VMPK for testing on the go, so it's either
// clicked or not.
}
System.out.println();
}
public void close() {}
}
}
它是 2 线程解决方案,可以打开所有 MIDI 设备并打印它们的速度、音符值和状态(是否被点击)
别忘了!
你必须打电话给
Main main = new Main();
main.Main();
在单独的 class 中启动 class Main 中的 Main 方法。
我想要一个程序,当它获得 MIDI 输入时可以做一些事情。
例如,当我点击控制器上的按钮 1 时,它应该打印 "You clicked btn 1",而当我点击按钮 2 时,它应该打印 "You clicked btn 2".
我尝试使用 javax.sound.midi 库,但论坛或 youtube 上的所有示例均无效。
这对我来说最有效。它打印了我 PC 的所有 Midi 设备,但没有收到任何东西。有人可以帮忙吗?
package de.snke.dev;
import javax.sound.midi.*;;
public class Main extends Object implements Receiver{
static MidiClass myMidi;
public static void main(String[] args) throws Exception {
MidiDevice.Info[] info =
MidiSystem.getMidiDeviceInfo();
for (int i=0; i < info.length; i++) {
System.out.println(i + ") " + info[i]);
System.out.println("Name: " + info[i].getName());
System.out.println("Description: " +
info[i].getDescription());
MidiDevice device =
MidiSystem.getMidiDevice(info[i]);
System.out.println("Device: " + device);
}
}
public void send(MidiMessage msg,
long time) {
System.out.println("Received message " + msg);
}
public void close() {
System.out.println("Closing");
}
}
编辑:现在我有
Sequencer seq;
Transmitter seqTrans;
Synthesizer synth;
Receiver synthRcvr;
try {
seq = MidiSystem.getSequencer();
seqTrans = seq.getTransmitter();
synth = MidiSystem.getSynthesizer();
synthRcvr = synth.getReceiver();
seqTrans.setReceiver(synthRcvr);
} catch (MidiUnavailableException e) {
// handle or throw exception
}
我现在连接到我的 APC Mini 了吗?对不起我是初学者... 如果是,我现在如何读取 MIDI 输入?如果否,我需要更改什么?
解决方法是:
package de.snke.dev;
import javax.sound.midi.*;
import java.util.ArrayList;
import java.util.List;
import java.io.*;
public class Main
{
public void Main()
{
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) {
byte[] aMsg = msg.getMessage();
// take the MidiMessage msg and store it in a byte array
// msg.getLength() returns the length of the message in bytes
for(int i=0;i<msg.getLength();i++){
System.out.println(aMsg[i]);
// aMsg[0] is something, velocity maybe? Not 100% sure.
// aMsg[1] is the note value as an int. This is the important one.
// aMsg[2] is pressed or not (0/100), it sends 100 when they key goes down,
// and 0 when the key is back up again. With a better keyboard it could maybe
// send continuous values between then for how quickly it's pressed?
// I'm only using VMPK for testing on the go, so it's either
// clicked or not.
}
System.out.println();
}
public void close() {}
}
}
它是 2 线程解决方案,可以打开所有 MIDI 设备并打印它们的速度、音符值和状态(是否被点击)
别忘了!
你必须打电话给
Main main = new Main();
main.Main();
在单独的 class 中启动 class Main 中的 Main 方法。