当前位置: 首页 > 面试题库 >

Java从MIDI键盘获取输入

艾骏喆
2023-03-14
问题内容

我已经用Java设计了自己的合成器,现在我想将其与Midi键盘连接。我在下面的课程搜索所有带有发射器的Midi设备。它成功找到了我的Midi键盘。我将自己的接收器添加到每个设备的每个发送器中,以便它可以接收所有可能的信息。通过阅读所有帮助文档和Java文档,我知道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() {}
    }
}

注意:我已经看到了:Java MIDI-从钢琴获取数据吗?。

和这个:http :
//www.jsresources.org/examples/MidiInDump.html

接口Sequencer看起来也很复杂,我也想要。


问题答案:

我发现,在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() {}
    }
}

在我的硬件上(我插入了一个简单的USB MIDI控制器),在创建MidiHandler实例后,该代码可以正确打印出“ midi receive”。

希望这可以帮助!



 类似资料:
  • 问题内容: 我继承了一个Java项目,该项目使用旧的C ++ dll 从连接到计算机的钢琴接收MIDI数据。 既然Java内置了对MIDI设备的支持,我想摆脱旧的C ++ dll,而只使用纯Java。 Java是否支持从连接到计算机的钢琴接收数据? 我已经在Google上搜索了一些示例,但都无济于事。 问题答案: 是的,JavaSound API可用于从MIDI设备读取MIDI数据。 JFugue

  • Virtual MIDI Piano Keyboard is a MIDI event generator and receiver. It doesn't produce any sound by itself, but can be used to drive a MIDI synthesizer (either hardware or software, internal or extern

  • 我现在找了一段时间,想做什么都找不到答案。 我想播放一个midi文件,并在播放时在屏幕上显示音符。当一个音符停止播放时,它应该从屏幕上消失。 我可以用音序器播放midi,但不知道如何让音符播放,或者何时停止播放音符。 我研究过ControllerEventListeners和MetaEventListeners,但仍然不知道如何做到这一点。 任何帮助都将不胜感激。

  • 问题内容: 我正在研究“ less”实用程序的代码,特别是它如何获取键盘输入的代码。有趣的是,在ttyin.c的第80行,它将文件描述符设置为从以下文件读取: 文件描述符2不是stderr吗?如果是这样,是什么?我以为键盘输入是通过stdin发送的。 有趣的是,即使这样做,在文件加载完成后,您仍然可以使用键盘上下滚动,但是如果这样做,则vi会大吼大叫,因为它不会从stdin中读取。有什么大主意?我

  • 问题内容: 我写了这个简短的程序来学习javax.sound.midi系统。这是使用Java 6进行的。输出是预期的(由Sequencer事件触发的一系列System.out.println()字符串),但是问题是,在最后一次声音效果之后,程序停留在循环中并且没有t按预期终止。 谁能说出解决办法?谢谢你的帮助: 问题答案: 曲目播放完毕后,您需要调用seq.close()。这样做的方法是添加一个元

  • 主要内容:scanf()函数,连续输入,输入其它数据,scanf() 格式控制符汇总程序是人机交互的媒介,有输出必然也有输入,第三章我们讲解了如何将数据输出到显示器上,本章我们开始讲解如何从键盘输入数据。在C语言中,有多个函数可以从键盘获得用户输入: scanf():和 printf() 类似,scanf() 可以输入多种类型的数据。 getchar()、getche()、getch():这三个函数都用于输入单个字符。 gets():获取一行数据,并作为字符串处理。 scanf(