问题
I would like to have a program that could do something when it gets a midi input.
For instance when I click button 1 on my controller it should print "You clicked btn 1" and when I click button 2 it should print "You clicked btn 2".
I tried using the javax.sound.midi library but all the examples in forums or on youtube didn't work for.
This worked the most for me. It printed all of the Midi Devices of my PC but it didn't receive anything. Can anybody help?
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");
}
}
EDIT: Now I have
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
}
Have I now connected to my APC Mini? Sorry I'm a beginner... If Yes how can I now read the midi input? And if No what do I have to change?
回答1:
The solution is:
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() {}
}
}
It's 2 threads solutions combined to open all midi devices and print their velocity, note value and status (clicked or not)
And don't forget!
You have to call
Main main = new Main();
main.Main();
in a seperate class to start the method Main in the class Main.
来源:https://stackoverflow.com/questions/51013510/receive-midi-input-with-javax-sound-midi