Java 中的 MIDI - 尝试从多个 CC 获取连续的控制器数据,但只能获取 1 个
我有一个 Moog Theremini,它输出两组连续控制器数据。 “俯仰”天线在 CC 20 上输出,“音量”天线在 CC2 上输出。
我可以毫无问题地提取 CC20 的轨道数据,但在阅读了一天的 MIDI 文档和文章后,似乎找不到任何方法来获取同一轨道上的其他 CC 数据。有没有对此很熟悉的人来帮助我?
下面的输出代码是我想要弄清楚的。我的目的是
- 将轨道(只有 1 个轨道)上的最后一条(或倒数第二条)消息转换为短消息
- 打印命令、状态、控制器# 和控制器值
- 这是在循环中完成的,因此它会无限期地继续打印曲目的最新部分。
下面的代码成功地实现了 CC 20 的上述目标,但我似乎不知道如何获取 CC 2 的数据。老实说,我什至不确定它为什么要打印 CC20。
try {
ShortMessage sm = (ShortMessage) sequencePass.getTracks()[0].get(sequencePass.getTracks()[0].size()-2).getMessage();
System.out.println("| comm " + sm.getCommand() + "| status " + sm.getStatus() + "| d1 (Controller#) " + sm.getData1() + "| d2 (Controller value) " + sm.getData2());
} catch (Exception e) {
System.out.println("blah blah" + e);
}
**此处编辑 1 是 MIDI 类:**
public MidiJunk() {
try {
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); //looking through all of my MIDI devices
for(int i=0;i<infos.length;i++)
{
System.out.println(infos[i].getName() + " - " + infos[i].getDescription());
}
System.out.println();
MidiDevice INSTRUMENTO = MidiSystem.getMidiDevice(infos[5]); //the plugged in Theremini is here, so assigning it as a MidiDevice
INSTRUMENTO.open(); //opening midi device
Sequencer sequencero = MidiSystem.getSequencer(); //default sequencer transmitter and receiver
sequencero.open(); //open sequencer
Transmitter transmittero = INSTRUMENTO.getTransmitter(); //linking transmitter to instrument?
Receiver receivero = sequencero.getReceiver(); //get reciever from sequencer
transmittero.setReceiver(receivero);
Sequence testseq; //test sequence
try {
testseq = new Sequence(Sequence.PPQ,24);
sequencero.setSequence(testseq);
sequencero.recordEnable(testseq.createTrack(),0);
sequencero.setTickPosition(0);
sequencero.startRecording();
Timer timeo = new Timer();
TimerTask timeoTaskeo = new displayMidiEventsOnTimer(testseq);
timeo.schedule(timeoTaskeo,400,400);
Scanno.nextLine();
sequencero.stopRecording();
MidiSystem.write(testseq,1,new File("miditest.mid"));
System.out.println("it's done");
} catch (Exception ene) {
System.out.println(ene);
}
} catch (Exception E) {
System.out.println(E);
}
}
这里是显示事件类
public class displayMidiEventsOnTimer extends TimerTask {
Sequence sequencePass;
public displayMidiEventsOnTimer(Sequence thisguy) {
sequencePass = thisguy;
}
@Override
public void run() {
try {
ShortMessage sm = (ShortMessage) sequencePass.getTracks()[0].get(sequencePass.getTracks()[0].size()-2).getMessage();
System.out.println("| comm " + sm.getCommand() + "| status " + sm.getStatus() + "| d1 (Controller#) " + sm.getData1() + "| d2 (Controller value) " + sm.getData2());
} catch (Exception e) {
System.out.println(e);
}
}
}
I have a Moog Theremini that outputs two sets of continuous controller data. The "pitch" antenna outputs on CC 20 and the "volume" antenna outputs on CC2.
I have no problem pulling up the track data for CC20, but after a day of reading MIDI docs and articles, can't seem to find any way to grab this other CC data on the same track. Is anyone familiar enough with this to help me out?
The output code below is what I'm trying to figure out. My intention with it is
- Convert the last (or second to last) message on the track (there's only 1 track) to a Short Message
- Print out the Command, Status, Controller # and Controller value
- This is done in a loop so it continues indefinitely printing out the latest part of the track.
The below code successfully achieves the above for CC 20, but I can't seem to figure out how to grab the data for CC 2. I'm not even sure why it's printing CC20 to be honest.
try {
ShortMessage sm = (ShortMessage) sequencePass.getTracks()[0].get(sequencePass.getTracks()[0].size()-2).getMessage();
System.out.println("| comm " + sm.getCommand() + "| status " + sm.getStatus() + "| d1 (Controller#) " + sm.getData1() + "| d2 (Controller value) " + sm.getData2());
} catch (Exception e) {
System.out.println("blah blah" + e);
}
**Edit 1 here is the MIDI class: **
public MidiJunk() {
try {
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); //looking through all of my MIDI devices
for(int i=0;i<infos.length;i++)
{
System.out.println(infos[i].getName() + " - " + infos[i].getDescription());
}
System.out.println();
MidiDevice INSTRUMENTO = MidiSystem.getMidiDevice(infos[5]); //the plugged in Theremini is here, so assigning it as a MidiDevice
INSTRUMENTO.open(); //opening midi device
Sequencer sequencero = MidiSystem.getSequencer(); //default sequencer transmitter and receiver
sequencero.open(); //open sequencer
Transmitter transmittero = INSTRUMENTO.getTransmitter(); //linking transmitter to instrument?
Receiver receivero = sequencero.getReceiver(); //get reciever from sequencer
transmittero.setReceiver(receivero);
Sequence testseq; //test sequence
try {
testseq = new Sequence(Sequence.PPQ,24);
sequencero.setSequence(testseq);
sequencero.recordEnable(testseq.createTrack(),0);
sequencero.setTickPosition(0);
sequencero.startRecording();
Timer timeo = new Timer();
TimerTask timeoTaskeo = new displayMidiEventsOnTimer(testseq);
timeo.schedule(timeoTaskeo,400,400);
Scanno.nextLine();
sequencero.stopRecording();
MidiSystem.write(testseq,1,new File("miditest.mid"));
System.out.println("it's done");
} catch (Exception ene) {
System.out.println(ene);
}
} catch (Exception E) {
System.out.println(E);
}
}
And here is the display events class
public class displayMidiEventsOnTimer extends TimerTask {
Sequence sequencePass;
public displayMidiEventsOnTimer(Sequence thisguy) {
sequencePass = thisguy;
}
@Override
public void run() {
try {
ShortMessage sm = (ShortMessage) sequencePass.getTracks()[0].get(sequencePass.getTracks()[0].size()-2).getMessage();
System.out.println("| comm " + sm.getCommand() + "| status " + sm.getStatus() + "| d1 (Controller#) " + sm.getData1() + "| d2 (Controller value) " + sm.getData2());
} catch (Exception e) {
System.out.println(e);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里不需要定序器,除非您想记录接收到的事件之间的相对时间。
以下是如何直接在自定义接收器中显示所有传入 CC 消息的示例。
You don't need a sequencer here, unless you want to record the relative timings between the received events.
Here is an example how to display all incoming CC messages directly in a custom Receiver.