我已經搜索了一段時間,並且找不到我想要做的答案。Java Midi - 如何從midi中彈出音符
我想播放MIDI文件,並在播放時在屏幕上顯示註釋。當一個音符停止播放時,它應該從屏幕上消失。
我可以用音序器演奏MIDI,但不知道如何獲得音符的演奏,或者當它停止演奏音符時。
我已經看着ControllerEventListeners和MetaEventListeners,但仍不知道如何做到這一點。
任何幫助,將不勝感激。
我已經搜索了一段時間,並且找不到我想要做的答案。Java Midi - 如何從midi中彈出音符
我想播放MIDI文件,並在播放時在屏幕上顯示註釋。當一個音符停止播放時,它應該從屏幕上消失。
我可以用音序器演奏MIDI,但不知道如何獲得音符的演奏,或者當它停止演奏音符時。
我已經看着ControllerEventListeners和MetaEventListeners,但仍不知道如何做到這一點。
任何幫助,將不勝感激。
這是一個FAQ。
將您自己的Receiver連接到音序器的變送器。
查看MidiPlayer中的DumpReceiver示例。
這已經證明是非常有用的,但你會知道如何獲得一個筆記的持續時間?我想製作一個基本的MIDI可視化工具,隨着筆記淡出,它將淡出一個正方形。 – user228856 2014-10-30 12:59:59
當您收到音符關閉事件時,音符停止。 – 2014-10-30 13:34:29
我不確定我是否清楚了我的觀點。此刻,當筆記播放時,我正在顯示彩色方塊。當我收到音符關閉事件時,我已使其消失。隨着鈔票消失,我想使彩色正方形慢慢淡出。我認爲接受者不知道一張音符將播放多久會是對的嗎?如果是這樣,我想我必須在播放之前以某種方式讀取MIDI文件,並使用它來計算時間。感謝你的幫助,你真的很有幫助。 – user228856 2014-10-30 16:10:25
這是你應該做的:
您必須實現Receiver
,然後
sequencer = MidiSystem.getSequencer();
sequencer.open();
transmitter = sequencer.getTransmitter();
transmitter.setReceiver(this);
,並在此之後,下一個方法將每一個事件發生時觸發:
@Override
public void send(MidiMessage message, long timeStamp) {
if(message instanceof ShortMessage) {
ShortMessage sm = (ShortMessage) message;
int channel = sm.getChannel();
if (sm.getCommand() == NOTE_ON) {
int key = sm.getData1();
int velocity = sm.getData2();
Note note = new Note(key);
System.out.println(note);
} else if (sm.getCommand() == NOTE_OFF) {
int key = sm.getData1();
int velocity = sm.getData2();
Note note = new Note(key);
System.out.println(note);
} else {
System.out.println("Command:" + sm.getCommand());
}
}
}
如果你願意,你也可以使用這個類:
public class Note {
private static final String[] NOTE_NAMES = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
private String name;
private int key;
private int octave;
public Note(int key) {
this.key = key;
this.octave = (key/12)-1;
int note = key % 12;
this.name = NOTE_NAMES[note];
}
@Override
public boolean equals(Object obj) {
return obj instanceof Note && this.key == ((Note) obj).key;
}
@Override
public String toString() {
return "Note -> " + this.name + this.octave + " key=" + this.key;
}
}
解決方案之一是讀取midi文件,獲取所有筆記及其持續時間,然後運行另一個線程來顯示筆記?如果有一些延遲,這會不會變得不同步? – user228856 2014-10-08 21:22:01