今回はJavaのプログラミングネタです。


最近再び触り始めたmidiキーボードの「AKAI MPK mini mk3」なのですが、
これPCにUSB接続した際の情報を取得できないかなと調べてみました。


調査したところ、いくつかの言語でmidi機器を操作することが可能なことが判明。

pythonの場合は「mido」というライブラリ。
C#の場合は和製PJの「Next Midi Project」あたり。(Windows)
Objective-CやSwiftなら「CoreMIDI」(Apple macOSX、iPadOS、iOS)
C、C++のMFC標準ライブラリ(Windows)
Javaの標準ライブラリ「javax.sound.midi」(macOSX、Linux、Windows)

Apple好きな筆者ではありますが、やはりクロスプラットフォームである言語が良いと思うのです。

そこで今回はクロスプラットフォームな言語であるJavaでmidiデバイスの情報を取得することにしました。

筆者のようにWindowsだけじゃなく、macOSXやLinuxなどの複数OS環境がある場合、
やはりクロスプラットフォームであることがありがたいですね。

そこでJavaのコードで参考になるものがないかをネットで検索したところ、
以下のコードを発見しました。

参考にさせていただきました。
海外サイトで「Returns an array of MidiDevice.Info for MIDI input device. – Java javax.sound.midi」です。

URLはこちらです。

MIDIデバイス情報を取得するJavaコード

上記のサイトから借用したコードにmain関数を加えて以下のようにしました。


//
import javax.sound.midi.*;
import java.util.*;
//
class MidiKeyBoardChk{
//* Midi Detect
    private final static boolean EMULATE_NO_MIDI_IN = false;
    private static MidiDevice.Info[] createInputMidiDeviceInfo()
            throws MidiUnavailableException {
        ArrayList list = new ArrayList();

        MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
        for (int i = 0; i < infos.length; i++) {
            // throws MidiUnavailableException
            MidiDevice device = MidiSystem.getMidiDevice(infos[i]);
            if (device.getMaxTransmitters() != 0
                    && !(device instanceof Synthesizer)
                    && !(device instanceof Sequencer)
                    && !EMULATE_NO_MIDI_IN)
                list.add(infos[i]);
        }
        return (MidiDevice.Info[]) list.toArray(new MidiDevice.Info[0]);
    }
//
    public static void main(String[] args) {
//* Main
        MidiDevice.Info[] info=MidiSystem.getMidiDeviceInfo();
        for(int i = 0 ; i < info.length; i++){
                System.out.println(info[i]);
        }
    }
}

それでは上記コードを「MidiKeyBoardChk.java」とファイル名で保存します。
以下で実行となります。

$ java MidiKeyBoardChk.java

以下の警告が出ますが、とりあえず今回は無視。

ノート:MidiKeyBoardChk.javaの操作は、未チェックまたは安全ではありません。
ノート:詳細は、-Xlint:uncheckedオプションを指定して再コンパイルしてください。

実行結果

1)macOSX上で何もmidi機器を接続せずに実行した結果

Gervill
Real Time Sequencer

2)macOSX上でAKAI MPK mini mk3をUSB接続して実行した結果

Gervill
Real Time Sequencer
MPK mini 3
MPK mini 3

3)Linux(GarudaLinux)上で何もmidi機器を接続せずに実行した結果

Gervill
Real Time Sequencer

4)Linux(GarudaLinux)上でAKAI MPK mini mk3をUSB接続して実行した結果

Gervill
Real Time Sequencer
M3 [hw:1,0,0]
M3 [hw:1,0,0]

配列の中身が若干違いますが、LinuxでもmidiデバイスをUSB接続することで、
情報を取得できることがわかりました。

5)Windows11上で何もmidi機器を接続せずに実行した結果

Gervill
Real Time Sequencer
Microsoft MIDI mapper
Microsoft GS Wavetable Synth

6)Windows11上でAKAI MPK mini mk3をUSB接続して実行した結果

Gervill
Real Time Sequencer
Microsoft MIDI mapper
Microsoft GS Wavetable Synth
MPK mini 3
MPK mini 3

Windowsの場合、Microsoft謹製のMapperとSynthが含まれていました。


尚、上記のコードのmain関数に以下を加えるとOSの情報も追加で表示させるようにできます。

        String osname = System.getProperty("os.name");
        String osver = System.getProperty("os.version");
        String osarch = System.getProperty("os.arch");
        System.out.println(osname + " " + osver +"("+ osarch +")");

まとめるとこうなります。

//
import javax.sound.midi.*;
import java.util.*;
//
class MidiKeyBoardChk{
//* Midi Detect
    private final static boolean EMULATE_NO_MIDI_IN = false;
    private static MidiDevice.Info[] createInputMidiDeviceInfo()
            throws MidiUnavailableException {
        ArrayList list = new ArrayList();

        MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
        for (int i = 0; i < infos.length; i++) {
            // throws MidiUnavailableException
            MidiDevice device = MidiSystem.getMidiDevice(infos[i]);
            if (device.getMaxTransmitters() != 0
                    && !(device instanceof Synthesizer)
                    && !(device instanceof Sequencer)
                    && !EMULATE_NO_MIDI_IN)
                list.add(infos[i]);
        }
        return (MidiDevice.Info[]) list.toArray(new MidiDevice.Info[0]);
    }
//
    public static void main(String[] args) {
//* Main
//* OS Info
        String osname = System.getProperty("os.name");
        String osver = System.getProperty("os.version");
        String osarch = System.getProperty("os.arch");
        System.out.println(osname + " " + osver +"("+ osarch +")");
//* Device Info
        MidiDevice.Info[] info=MidiSystem.getMidiDeviceInfo();
        for(int i = 0 ; i < info.length; i++){
                System.out.println(info[i]);
        }
    }
}

まとめ

というわけで、今回はクロスプラットフォームな開発言語であるJavaで
MIDIデバイスの情報を取得する方法について、紹介しました。

何かの参考になれば幸いです。