Posted at

ポケット・ミクをJava/Clojureから操作してみる

More than 5 years have passed since last update.

ポケット・ミクはMIDIデバイスだということで、Javaからならjavax.sound.midiパッケージを使えばわりと簡単に操作できるようです。

Javaのサンプルはこんな感じです。


PokeMikuSample.java

package pokemiku;

import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.SysexMessage;
import javax.xml.bind.DatatypeConverter;

public class PokeMikuSample {
public static void main(String... args) throws Exception{
try(MidiDevice d = getDevice()){
d.open();
Receiver r = d.getReceiver();

byte[] data = DatatypeConverter.parseHexBinary("F0437909110A00"+ 21 +"F7");
r.send(new SysexMessage(data, data.length), -1);
r.send(new ShortMessage(ShortMessage.NOTE_ON, 80, 127), -1);
Thread.sleep(2000);
}
}
static MidiDevice getDevice() throws Exception{
for(MidiDevice.Info i : MidiSystem.getMidiDeviceInfo()){
if(i.getName().startsWith("NSX-39") && i.getDescription().startsWith("External")){
return MidiSystem.getMidiDevice(i);
}
}
throw new RuntimeException();
}
}


"NSX-39 "(最後にスペースがある)名前のデバイスが私の環境だと2つありました。そのうち、descriptionにExternal MIDI Portとある方が使えます。

SysexMessageで発音する文字を(マニュアル裏に書いてあるものに)変えられます。

ShortMessageで音程と音量(0~127)を指定できるようです。

Clojureのサンプルはこんな感じです。Javaとほとんど同じですね。


pokemiku_core.clj

(ns pokemiku.core

(:import [javax.sound.midi MidiSystem ShortMessage SysexMessage MidiDevice]
[javax.xml.bind DatatypeConverter]))

(def dev
(->> (seq (MidiSystem/getMidiDeviceInfo))
(filter #(re-find #"NSX-39" (:name (bean %))))
(filter #(re-find #"External" (:description (bean %))))
first
(MidiSystem/getMidiDevice)))

(with-open [dev dev]
(.open dev)
(let [r (.getReceiver dev)
data (DatatypeConverter/parseHexBinary (str "F0437909110A00" 37 "F7"))]
(.send r (SysexMessage. data (count data)) -1)
(.send r (ShortMessage. ShortMessage/NOTE_ON 72 127) -1)
(Thread/sleep 2000)))


わりと簡単にできました。

MIDIのことがまだよくわかってないですが、他にもいろいろできるようです。