JAVA MIDI按顺序消除静音

JAVA MIDI eliminate silence in sequence

不久前我买了一个带MIDI输出的VDRUM套件。 我有一个 raspberry pi 以前的项目放在这里,我有一个想法用那台小电脑作为录音机。

所以我编写了一个在 PI 上运行并监听 VDRUM 套件的 MIDI 输出端口的无头应用程序。收到静音以外的输入后,我开始通过 jdk 库进行录制,并将其放置在带有时间戳的 samba 服务器上。

这样我就可以保存我玩过的所有东西。现在我已经设置了我的音频工作站以从 samba 共享中接收那些 MIDI 文件,我注意到,它们通常在 MIDI 文件的开头有一个很长的“无声”部分。

有没有办法以编程方式消除 MIDI 序列开头的静音?我是 MIDI 新手,还在学习中。

这是启动和停止录制的代码:

    public void send(MidiMessage message, long timeStamp) {
        if (message.getStatus() == 254) {
            if (isRecording && timestampOfLastAction.isBefore(LocalTime.now().minus(5, ChronoUnit.SECONDS))) {
                String userDirectory = "/home/pi/";
                DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss");
                LocalDateTime now = LocalDateTime.now();
                String fileName = dtf.format(now) + ".mid";
                sequencer.stopRecording();
                File midiFile = new File(userDirectory + "/MidiRecorder/" + fileName);
                try {
                    Sequence sequence = sequencer.getSequence();
                    MidiSystem.write(sequence, 0, midiFile);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Logger.getGlobal().info("STOPPED RECORDING: " + LocalTime.now().toString());
                isRecording = false;
            }

        } else {
            timestampOfLastAction = LocalTime.now();
            if (!isRecording) {
                isRecording = true;
                sequencer = null;
                try {
                    sequencer = MidiSystem.getSequencer();

                    Transmitter transmitter1;
                    Receiver receiver;
                    // Open a connection to the default sequencer (as specified by MidiSystem)
                    sequencer.open();
                    // Get the transmitter class from your input device
                    transmitter1 = this.midiDevice.getTransmitter();
                    // Get the receiver class from your sequencer
                    receiver = sequencer.getReceiver();
                    transmitter1.setReceiver(receiver);
                    Sequence seq = new Sequence(Sequence.PPQ, 24);
                    // And of course a track to record the input on
                    Track currentTrack = seq.createTrack();
                    // Do some sequencer settings
                    sequencer.setSequence(seq);
                    sequencer.setTickPosition(0);
                    sequencer.recordEnable(currentTrack, -1);

                    // And start recording
                    sequencer.startRecording();
                    Logger.getGlobal().info("STARTED RECORDING: " + LocalTime.now().toString());
                } catch (Exception e) {
                    // TODO: handle exception
                } finally {

                }
            }
        }
    }

您需要移动 Sequence 的所有 MidiEvents 以移除前导静音。

private void removeLeadingSilence(Sequence sequence)
{
    // Find first event
    long firstEventTick = Long.MAX_VALUE;
    for (Track track : sequence.getTracks())
    {
        if (track.size() > 0)
        {
            firstEventTick = Math.min(firstEventTick, track.get(0).getTick());
        }
    }

    // Shift all events
    for (Track track : sequence.getTracks())
    {
        for (int i = 0; i < track.size(); i++)
        {
            MidiEvent me = track.get(i);
            me.setTick(me.getTick() - firstEventTick);
        }
    }
}