
Я просто хочу определить длину в миллисекундах для этих двух нот. В реальном времени первая нота длится меньше секунды, а вторая — около 2 секунд.
Когда я повторяю MIDI-события, каждый раз, когда я получаю событие включения или выключения ноты, я извлекаю оттуда дельта-тики. Я на 100% уверен, что эти дельта-тики верны, потому что я сравнил их с алгоритмом, который работает правильно.
Насколько я понимаю, если клавиша F5 в этом файле нажмет на включение ноты за время X, то снятие ноты этого события произойдет после количества дельта-тиков события снятия ноты. Это означает, что для того, чтобы определить, какова в миллисекундах длина клавиши F5, все, что мне нужно сделать, это преобразовать дельта-такты события отключения банкноты в миллисекунды. (Я прав?)
Я проанализировал MIDI-файл, получил темп и PPQ, много искал по этому поводу и нашел следующую формулу:
Код: Выделить всё
double bpm = (60000000 / mTempo);
deltaTimesInMilliseconds = deltaTicks * (60000 / (bpm * division));
Спасибо за любую помощь!
Дополнительная часть файла:
Код: Выделить всё
public class MidiParserN {
private static double mTempo;
private static short division;
...
...
private static TrackChunkEvent
parseMTrkEvent() throws Exception {
int deltaTicks = Math.abs(calculateDeltaTicks(getVariableLengthQuantity()));
double deltaTimesInMilliseconds = 0;
int eventType = parseEventType();
int eventNum = -1;
String eventName = "";
if (eventType == EventTypes.MIDI_EVENT.ordinal()) {
eventNum = parseMidiMessage();
eventName = midiEventsTypes[eventNum].toString();
} else if (eventType == EventTypes.SYSEX_EVENT.ordinal()) {
parseSysexEvent();
} else {
eventNum = parseAndExecuteMetaEvent();
eventName = metaEventsTypes[eventNum].toString();
}
if (eventName.equals("NOTE_ON_EVENT") && deltaTimes != 0 && mTempo != 0) {
double bpm = (60000000 / mTempo);
deltaTimesInMilliseconds = deltaTicks * (60000 / (bpm * division));
log("DELTA_TIMES_MILLISECONDS", Double.toString(deltaTimesInMilliseconds));
}
else if (eventName.equals("NOTE_OFF_EVENT") && deltaTimes != 0 && mTempo != 0) {
double bpm = (60000000 / mTempo);
deltaTimesInMilliseconds = deltaTicks * (60000 / (bpm * division));
log("DELTA_TIMES_MILISECONDS", Double.toString(deltaTimesInMilliseconds));
}
return new TrackChunkEvent(eventNum, eventName);
}
...
...
}
Код: Выделить всё
if (firstByteOfMetaEvent == 0x51 && secondByteOfMetaEvent == 3) {
int tempo = byteArrayToInt(parseMetaEventSetTempo());
mTempo = tempo;
return MetaEventsTypes.SET_TEMPO.ordinal();
}
4d 54 68 64 00 00 00 06 00 01 00 02 01 80 4d 54 72 6b 00 00 00 13 00 ff 58 04 04 02 18 08 00 ff 51 03 08 52 ae 00 ff 2f 00 4d 54 72 6b 00 00 00 33 00 ff 03 15 45 6c 65 63 2e 20 50 69 61 6e 6f 20 28 43 6c 61 73 73 69 63 29 00 c0 00 82 20 90 3c 32 60 80 3c 00 83 00 90 41 32 8d 40 80 41 00 00 ff 2f 00
Как изображение:

Подробнее здесь: https://stackoverflow.com/questions/719 ... lliseconds
Мобильная версия