在www.jsresources.org中是示例,但仍然存在问题: 什么是速度?每分钟节拍?为什么不是120而是64?为什么刻度不是指1.3毫秒间隔而是0.5秒?如何放短记? 如何从文件中读取文书? 我的示例代码
Synthesizer synthesizer;
synthesizer = MidiSystem.getSynthesizer();
synthesizer.open();
MidiChannel chan = synthesizer.getChannels()[0];
chan.programChange(1152, 14);
从系统读取MidiChannel(全局?)而不是从文件读取。
答案 0 :(得分:1)
速度是音符的音量或增益。它从0到127 - 数字越高,音符越大。
选择64可能是因为它是中等水平(不太大声)。为了能够使用较短的音符,您必须更改序列的分辨率 - 这是基于"速度的"分辨率和每季度刻度的工作说明:
sequence = new Sequence(Sequence.PPQ, 1);
增加第二个参数,每季度音符会有更多的刻度,因此会有更短的音符。
你也可以使用:
sequence = new Sequence(Sequence.SMPTE_30, 1);
这将为您提供每秒30帧的分割类型。第二个参数是每帧最大分辨率为1个音符。
全部在documentation。
这是一个示例 - 从示例链接修改 - 它应该在桌面上保存文件。您可能需要将其更改为其他位置:
import java.io.File;
import java.io.IOException;
import javax.sound.midi.Sequence;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;
import javax.sound.midi.InvalidMidiDataException;
public class CreateSequence {
private static final int VELOCITY = 64;
public static void main(String[] args) {
File outputFile = new File(System.getProperty("user.home")
+ "//Desktop//file.midi");
Sequence sequence = null;
try {
sequence = new Sequence(Sequence.SMPTE_30, 2);
} catch (InvalidMidiDataException e) {
e.printStackTrace();
System.exit(1);
}
Track track = sequence.createTrack();
int note = 40;
for (int tick = 0; tick < 215;) {
track.add(createNoteEvent(ShortMessage.NOTE_ON, ++note, VELOCITY,
tick));
track.add(createNoteEvent(ShortMessage.NOTE_OFF, note, VELOCITY,
tick += 3));
}
try {
MidiSystem.write(sequence, 0, outputFile);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
private static MidiEvent createNoteEvent(int nCommand, int nKey,
int nVelocity, long lTick) {
ShortMessage message = new ShortMessage();
try {
message.setMessage(nCommand, 0, nKey, nVelocity);
} catch (InvalidMidiDataException e) {
e.printStackTrace();
System.exit(1);
}
MidiEvent event = new MidiEvent(message, lTick);
return event;
}
}
从文件中读取是一个全新的问题。检查文档!