首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java :将MIDI键盘连接到默认合成器

Java :将MIDI键盘连接到默认合成器
EN

Stack Overflow用户
提问于 2016-06-01 02:19:16
回答 3查看 1.2K关注 0票数 1

我有个MIDI键盘。我想要的只是一个例子,说明我如何设置默认的软件合成器来播放声音,就像我玩键盘一样。

代码语言:javascript
复制
package cleffsgame;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;

public class CheckDevices {

    public static void main(String[] args) {
        MidiDevice device;
        // display each device's properties
        for (MidiDevice.Info info: MidiSystem.getMidiDeviceInfo()) {

            try {
                device = MidiSystem.getMidiDevice(info);

                System.out.println("\nDevice: ");
                System.out.println("Name: " + device.getDeviceInfo().getName());
                System.out.println("Vendor: " + device.getDeviceInfo().getVendor());
                System.out.println("Version: " + device.getDeviceInfo().getVersion());
                System.out.println("Description: " + device.getDeviceInfo().getDescription());
                System.out.println("Transmitters: " + device.getMaxTransmitters());
                System.out.println("Receivers: " + device.getMaxReceivers());

            } catch (MidiUnavailableException ex) {
                Logger.getLogger(CheckDevices.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

通过运行上面的代码,我得到了以下输出:

跑: 设备名称: Gervill Vendor: OpenJDK版本: 1.0描述:软件MIDI合成器发射机:0接收器:-1 设备名称:氧气49供应商:m-音频版本:未知版本描述:氧气49发射机:-1接收器:0 设备名称:氧气49供应商:m-音频版本:未知版本描述:氧气49发射机:0接收器:-1 设备名称:实时Sequencer : Oracle公司版本: 1.0版本:软件顺序发射器:-1接收器:-1成功构建(总时间:2秒)

但是当我运行下面的代码时,当我按下键时,没有声音被播放。

代码语言:javascript
复制
package cleffsgame;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.Synthesizer;
import javax.sound.midi.Transmitter;

/**
 *
 * @author umberto
 */
public class Test {

    public static void main(String[] args) {
        MidiDevice inputDevice = null, synthDevice = null;
        Transmitter transmitter = null;
        Synthesizer synthesizer = null;
        Receiver receiver = null;

        try {
            inputDevice = MidiSystem.getMidiDevice(MidiSystem.getMidiDeviceInfo()[1]);
            synthDevice = MidiSystem.getMidiDevice(MidiSystem.getMidiDeviceInfo()[0]);

        } catch (MidiUnavailableException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }

        // goodDevice must be Oxygen 49 transmitter (MIDI Input)
        if (inputDevice != null && synthDevice != null) {
            try {
                transmitter = inputDevice.getTransmitter();
                System.out.println("Transmitter: " + inputDevice.getDeviceInfo());
                System.out.println(String.format("T/R: %s/%s", inputDevice.getMaxTransmitters(), inputDevice.getMaxReceivers()));

                receiver = synthDevice.getReceiver();
                System.out.println("Receiver: " + synthDevice.getDeviceInfo());
                System.out.println(String.format("T/R: %s/%s", synthDevice.getMaxTransmitters(), synthDevice.getMaxReceivers()));

                transmitter.setReceiver(receiver);
                System.out.println("GoodDevice is open... check sound\n");
                inputDevice.open();
                synthDevice.open();

            } catch (Exception ex) {
                Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }


}

似乎有更多的工作要做,而不是像我从docs Synthesizer.receiver中获得的那样,将一个InputDevice.transmitter连接到一个https://docs.oracle.com/javase/tutorial/sound/MIDI-synth.html

EN

回答 3

Stack Overflow用户

发布于 2020-07-31 20:39:02

这个对我有用

代码语言:javascript
复制
transmitter.setReceiver(new Receiver() {
    @Override
    public void send(MidiMessage message, long timeStamp) {
        receiver.send(message, -1);
    }
    @Override
    public void close() {
        receiver.close();
    }
});
票数 1
EN

Stack Overflow用户

发布于 2016-06-01 06:36:15

在获得发射机/接收器之前打开设备可能是个好主意。

但实际的问题是,这个程序会立即退出,因此设备不会在有效的时间内打开。

票数 0
EN

Stack Overflow用户

发布于 2022-04-13 09:33:37

最近也想做同样的事。Java教程和堆栈溢出的答案不起作用。问题是,我把timestamp上的键盘注释传递给内部合成器。修复方法是将-1作为时间戳传递。

本例使用Kotlin调用。

JDK 17,MacOS 11.3,Kotlin 1.6

代码语言:javascript
复制
import javax.sound.midi.*

class ReceiverAdapter (val targetReceiver: Receiver) : Receiver {

    override fun send(midiMsg: MidiMessage, timeStamp: Long) {
        targetReceiver.send(midiMsg, -1); // only works for me when i pass -1 as timestamp instead of original value from keyboard
    }
    override fun close() {  }
}

class MidiKeyboardInternalSynthExample {

    companion object {

        fun doIt(keyboardDeviceName: String){

            // connect external keyboard to internal synth
            val midiTransmitter = find1stMidiTransmitterWithName(keyboardDeviceName)
            if(midiTransmitter != null) {
                val synth = MidiSystem.getSynthesizer()!!
                val midiReceiver = ReceiverAdapter(synth.receiver)
                midiTransmitter.transmitter.receiver = midiReceiver
                synth.open()
                midiTransmitter.open()
            }
            else {
                println("Didn't find MIDI transmitter named '$keyboardDeviceName'.")
            }
        }

        fun find1stMidiTransmitterWithName(deviceName: String): MidiDevice? =
            MidiSystem.getMidiDeviceInfo()
                ?.filter { info -> info.name == deviceName }
                ?.map { info -> MidiSystem.getMidiDevice(info) }
                ?.filter { device -> device.maxTransmitters == -1 }
                ?.first()
    }
}

fun main(args: Array<String>) {
    MidiKeyboardInternalSynthExample.doIt("LPK25")
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37558401

复制
相关文章

相似问题

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