最近受人启发做了个小程序,是用java写的。 其中的关键部分就是对MIDI文件的内容进行解析。
由于之前没有经验,因此我到网上查了一下,java自带了一个叫javax.sound.midi的包。提供了比较方便的MIDI处理,以下是我查阅过的部分资料:
MIDI是Musical Instrument Digital Interface的简写,翻译过来就是“乐器数字化接口”。
当然,如果对于MIDI的知识缺乏基础的了解,可以看看这里:
这上面有不少关于MIDI标准的文档。
下面我们顺着javax.sound.midi包里的类来理一理mid文件的大概结构:
首先是javax.midi.Sequence ,这个类代表一个midi序列(同时也代表一个mid文件里的所有内容),是一个mid文件中所有数据的实体化表现。
我们可以以这样的方式从文件系统中读取一个mid:
try {
Sequence sequence = MidiSystem.getSequence(new File("C:\\C5.mid"));
} catch (InvalidMidiDataException | IOException e) {
e.printStackTrace();
}以上的代码将指定mid文件中的内容通过
javax.sound.midi.MidiSystem类读入为一个midi序列。注意在此处可能会抛出两种异常。
通过一个Sequence对象,我们可以获取关于这个midi序列的所有信息:
long length = sequence.getMicrosecondLength(); // 获取序列的总时间(微秒)
int trackCount = sequence.getTracks().length; // 获取序列的音轨数
float divType = sequence.getDivisionType(); // 获取序列的(计时方式?)
// 原文 : Obtains the timing division type for this sequence.
int resolution = sequence.getResolution(); // 获取序列的时间解析度
获得了一个序列的时间信息,我们先看看如何对一个midi序列进行播放。关于具体的midi数据解析,我们放到下一篇讲。
之前有提到过MidiSystem这个类,作为整个javax.sound.midi包中最重要的类,它还提供了几个对于midi播放至关重要的方法:
Info[] infos = MidiSystem.getMidiDeviceInfo(); // 获取所有 midi 设备的信息
Sequencer sequencer = MidiSystem.getSequencer(); // 获取默认的音序器
Synthesizer synthsizer = MidiSystem.getSynthesizer(); // 获取默认的合成器
Receiver receiver = MidiSystem.getReceiver(); // 获取默认的接收器
Transmitter transmitter = MidiSystem.getTransmitter(); // 获取默认的传输器要实现简单的midi播放的话,只需要用到音序器(
javax.sound.midi.Sequencer)就可以了,以下就是一段简单的播放代码:
try {
Sequence sequence = MidiSystem.getSequence(new File("C:\\C5.mid"));
Sequencer sequencer = MidiSystem.getSequencer();
if(sequencer == null){
throw new IOException("未找到可用音序器!");
}
sequencer.setSequence(sequence);
sequencer.start();
} catch (InvalidMidiDataException | IOException | MidiUnavailableException e) {
e.printStackTrace();
}
以下列出了Sequencer的部分主要方法:
Sequencer.setSequence(Sequence sequence); // 设置midi序列
Sequencer.start(); // 开始播放当前序列
Sequencer.stop(); // 停止播放当前序列
Sequencer.setTempoFactor(float factor); // 设置速度比率 (1.0f 为原速)
Sequencer.setMicrosecondPosition(long microseconds); // 设置播放位置到指定微秒
Sequencer.setTrackMute(int track, boolean mute); // 开启或关闭一条音轨的静音模式
Sequencer.setTrackSolo(int track, boolean solo); // 开启或关闭一条音轨的独奏模式
一般来说的话,在进行简单的midi播放时只要用到Sequencer就可以了。关于如何具体对midi声音信号进行解析和处理,在下一篇会进行讲解。
本文介绍了使用Java的javax.sound.midi包解析和处理MIDI文件的基础知识,包括Sequence类的使用,MidiSystem的重要功能以及Sequencer的主要方法。
1526

被折叠的 条评论
为什么被折叠?



