private static List<Note> midiEventsToNotes(List<MidiEvent> midiEvents) {
List<Note> output = new ArrayList<>();
Predicate<MidiEvent> noteEvent = me -> me.getMessage().getStatus() >> REST_OF_STATUS_BYTE == NOTE_ON
|| me.getMessage().getStatus() >> REST_OF_STATUS_BYTE == NOTE_OFF;
List<MidiEvent> noteEvents = midiEvents.stream().filter(noteEvent).collect(Collectors.toList());
for (int i = 0; i < noteEvents.size(); i++) {
int eventType = noteEvents.get(i).getMessage().getStatus() >> REST_OF_STATUS_BYTE;
if (eventType == NOTE_ON) {
byte pitch = noteEvents.get(i).getMessage().getMessage()[1];
int startBeat = (int) (noteEvents.get(i).getTick() / ticksPerBeat);
for (MidiEvent ne: noteEvents) {
int pairType = ne.getMessage().getStatus() >> REST_OF_STATUS_BYTE;
byte pitch2 = ne.getMessage().getMessage()[1];
if (pairType == NOTE_OFF && pitch == pitch2) {
int value = (int) (ne.getTick() / ticksPerBeat - startBeat);
int pianoKey = pitch - MIDI_A0_VALUE;
output.add(new Note(startBeat, value, pianoKey));
break;
}
}
}
}
return output;
}
Я пытаюсь прочитать MIDI-файл (преобразовать данные в файле в данные, которые обрабатываются моделью моего приложения). Вот метод, о котором идет речь. Требуется список MidiEvent, который должен быть просто списком всех MidiEvent в последовательности файла. Метод должен вывести список Note, причем Note является классом в модели. Сначала метод отфильтровывает список только для событий заметок и заметок. Затем для каждого события, если событие является примечанием, оно пытается связать его с соответствующим примечанием и создать экземпляр примечания.
Я тестировал его с файлами midi, содержащими только одну примечание. , Как и ожидалось, отладчик сообщает мне, что в отфильтрованном списке есть два элемента noteEvents
, но они как-то оба являются событиями заметок (они имеют одинаковый байт состояния), и, очевидно, метод не работает из-за этого. Что-то не так с методом, или Java конвертирует файл в события, или MIDI-файлы просто плохи?