首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用javax.sound.midi接收midi输入

用javax.sound.midi接收midi输入
EN

Stack Overflow用户
提问于 2018-06-24 20:00:34
回答 1查看 1.3K关注 0票数 2

我希望有一个程序,可以做一些事情,当它得到一个midi输入。

例如,当我单击我的控制器上的按钮1,它应该打印“您单击btn 1”,当我单击按钮2,它应该打印“您单击btn 2”。

我试过使用javax.sound.midi库,但论坛或youtube上的所有示例都不适用。

这对我最有效。它打印了我的个人电脑的所有Midi设备,但是它没有收到任何东西。有人能帮忙吗?

代码语言:javascript
复制
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");
        }
}

编辑:现在我有了

代码语言:javascript
复制
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
}

我现在已经连接到我的装甲运兵车迷你了吗?抱歉我是初学者..。如果是,我现在如何读取midi输入?如果没有,我需要改变什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-25 15:19:10

解决办法是:

代码语言:javascript
复制
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() {}
}
}

它是两个线程组合的解决方案,用于打开所有midi设备并打印它们的速度、注释值和状态(单击与否)。

,别忘了!

你得打电话

代码语言:javascript
复制
Main main = new Main();
main.Main();

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51013510

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档