java - JAVA MIDI 按顺序消除静音
问题描述
不久前我买了一个带有 MIDI 输出的 VDRUM 套件。我以前的项目中有一个树莓派,我想用那台小型计算机作为记录器。
所以我编写了一个在 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 {
}
}
}
}
解决方案
您需要移动所有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);
}
}
}
推荐阅读
- xcode - 在 Xcode 12 中运行签名后脚本
- javascript - 获取相对于旋转 div 上 div 浏览器窗口的 x 和 y
- java - java.lang.Error:从 assets 文件夹中复制 SQLite 数据库中的数据库时出错
- java - 在 Eclipse 插件中加密敏感数据
- salesforce - Salesforce 沙盒中不提供社区选项
- javascript - 在 json api 请求中附加我自己的 json
- sql - IN SQL INNER JOIN 可以添加两个不同列的表吗?
- android - 为什么我在 ArrayAdapter 中遇到此错误?
- javascript - 组件返回未在父组件内呈现的 div 数组
- json - React:如何从以下 json 创建表