微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JAVA MIDI 按顺序消除静音

如何解决JAVA MIDI 按顺序消除静音

不久前我买了一个带有 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,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 {

                }
            }
        }
    }

解决方法

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

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);
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。