使用javax.sound.midi接收midi输入 [英] Receive midi input with javax.sound.midi

查看:155
本文介绍了使用javax.sound.midi接收midi输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望有一个程序可以在收到midi输入时执行某些操作.

I would like to have a program that could do something when it gets a midi input.

例如,当我单击控制器上的按钮1时,应打印您单击了btn 1",当我单击按钮2时应显示您单击了btn 2".

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".

我尝试使用javax.sound.midi库,但论坛或youtube上的所有示例均无法使用.

I tried using the javax.sound.midi library but all the examples in forums or on youtube didn't work for.

这对我来说最有效.它打印了我PC的所有Midi设备,但没有收到任何信息.有人可以帮忙吗?

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");
        }
}

现在我有

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输入?如果没有,我必须更改什么?

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?

推荐答案

解决方案是:

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设备并打印其速度,音符值和状态(是否单击)

It's 2 threads solutions combined to open all midi devices and print their velocity, note value and status (clicked or not)

别忘了!

您必须致电

Main main = new Main();
main.Main();

在单独的类中启动Main类中的Main方法.

in a seperate class to start the method Main in the class Main.

这篇关于使用javax.sound.midi接收midi输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆