Java 中的 MIDI - 尝试从多个 CC 获取连续的控制器数据但只能获取 1 个

MIDI in Java - Trying to get continuous controller data from multiple CCs but only able to get 1

我有一个输出两组连续控制器数据的 Moog Theremini。 “音高”天线在 CC 20 上输出,“音量”天线在 CC2 上输出。

我可以毫无问题地提取 CC20 的轨道数据,但是在阅读了 MIDI 文档和文章一天之后,似乎无法找到任何方法来获取同一轨道上的其他 CC 数据。有没有人对此足够熟悉来帮助我?

下面的输出代码是我想要弄清楚的。我的意图是

  1. 将轨道(只有 1 个轨道)上的最后一条(或倒数第二条)消息转换为短消息
  2. 打印命令、状态、控制器#和控制器值
  3. 这是在循环中完成的,因此它会无限期地打印出曲目的最新部分。

下面的代码成功地实现了 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 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);

        }
    }

这里是显示事件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);
        }
    }

}

这里不需要音序器,除非你想记录接收到的事件之间的相对时间。

下面是一个示例,说明如何在自定义接收器中直接显示所有传入的 CC 消息。

...
Transmitter transmittero = INSTRUMENTO.getTransmitter(); 
Receiver receivero = new MyReceiver();   // Connect to your custom receiver
transmittero.setReceiver(receivero);
...

class MyReceiver implements Receiver
{

    @Override
    public void send(MidiMessage mm, long timeStamp)
    {
        if (mm instanceof ShortMessage)
        {
            ShortMessage sm = (ShortMessage) mm;
            if (sm.getCommand() == ShortMessage.CONTROL_CHANGE)
            {
                int cc = sm.getData1();
                // Do something quick, filter ignored CCs etc.
                System.out.println("cc=" + cc);    
            }
        }
    }

    @Override
    public void close()
    {
    }

}