From 96f94c61fb8bb1184fd289bd180194c476ea9dcc Mon Sep 17 00:00:00 2001 From: Emmett Date: Sun, 12 May 2024 00:41:46 -0400 Subject: [PATCH 1/4] respect tempo changes --- src/midiToNotes.js | 89 +++++++++++++++++++++++---------------------- test/bpmtest.mid | Bin 0 -> 645 bytes 2 files changed, 45 insertions(+), 44 deletions(-) create mode 100644 test/bpmtest.mid diff --git a/src/midiToNotes.js b/src/midiToNotes.js index 2378a47..9f91ccb 100644 --- a/src/midiToNotes.js +++ b/src/midiToNotes.js @@ -16,8 +16,8 @@ const MidiToNotes = (function () { /** All the events in the midi file, sorted by time */ const sortedMidiEvents = getSortedMidiEvents(midi); - collectPitchBendEvents(sortedMidiEvents, timeDivision); - generateWarnings(sortedMidiEvents, timeDivision); + collectPitchBendEvents(sortedMidiEvents); + adjustForTempoChanges(sortedMidiEvents); // Calculate endpoint for (let i = sortedMidiEvents.length - 1; i >= 0; i--) { @@ -86,6 +86,13 @@ const MidiToNotes = (function () { let bPriority = 0; const aType = getEventType(a); const bType = getEventType(b); + // tempo change events have priority + if (aType === "meta" && a.metaType == 81) { + return -1; + } + if (bType === "meta" && b.metaType == 81) { + return 1; + } if ( (aType === "noteOn" || aType === "noteOff") && (bType === "noteOn" || bType === "noteOff") @@ -110,6 +117,17 @@ const MidiToNotes = (function () { return allMidiEvents; } + function pushNote(startTime, timeDivision, length, tcStartPitch, tcEndPitch) { + const tcPitchDelta = tcEndPitch - tcStartPitch; + MidiToNotes.notes.push([ + startTime / timeDivision, + length > 0 ? length / timeDivision : defaultNoteLength, + tcStartPitch, + tcPitchDelta, + tcEndPitch, + ]); + } + function generateNotesMidi2Tc(sortedMidiEvents, timeDivision) { /** Note that we're currently creating */ let currentNote; @@ -128,15 +146,7 @@ const MidiToNotes = (function () { convertPitch(startPitch, startPitchBend, startTime, timeDivision); const tcEndPitch = convertPitch(pitch, endPitchBend, event.time, timeDivision); - const tcPitchDelta = tcEndPitch - tcStartPitch; - - MidiToNotes.notes.push([ - startTime / timeDivision, - length > 0 ? length / timeDivision : defaultNoteLength, - tcStartPitch, - tcPitchDelta, - tcEndPitch, - ]); + pushNote(startTime, timeDivision, length, tcStartPitch, tcEndPitch); currentNote = undefined; } @@ -151,15 +161,7 @@ const MidiToNotes = (function () { convertPitch(startPitch, startPitchBend, startTime, timeDivision); const tcEndPitch = convertPitch(pitch, pitchBend, event.time, timeDivision); - const tcPitchDelta = tcEndPitch - tcStartPitch; - - MidiToNotes.notes.push([ - startTime / timeDivision, - length > 0 ? length / timeDivision : defaultNoteLength, - tcStartPitch, - tcPitchDelta, - tcEndPitch, - ]); + pushNote(startTime, timeDivision, length, tcStartPitch, tcEndPitch); } currentNote = { @@ -189,15 +191,7 @@ const MidiToNotes = (function () { convertPitch(startPitch, startPitchBend, startTime, timeDivision); const tcEndPitch = convertPitch(endPitch, endPitchBend, event.time, timeDivision); - const tcPitchDelta = tcEndPitch - tcStartPitch; - - MidiToNotes.notes.push([ - startTime / timeDivision, - length > 0 ? length / timeDivision : defaultNoteLength, - tcStartPitch, - tcPitchDelta, - tcEndPitch, - ]); + pushNote(startTime, timeDivision, length, tcStartPitch, tcEndPitch); currentNote = undefined; } @@ -238,8 +232,29 @@ const MidiToNotes = (function () { value: midiPitchBend * Settings.getSetting("pitchbendrange") }; - MidiToNotes.pitchBendEvents.push(pitchEvent) + MidiToNotes.pitchBendEvents.push(pitchEvent); + } + } + } + + /** + * Adjust time based on tempo changes + */ + function adjustForTempoChanges(sortedMidiEvents) { + if (getEventType(sortedMidiEvents[0]) !== "meta" || sortedMidiEvents[0].metaType !== 81) { + return; + } + const baseTempo = sortedMidiEvents[0].data; + let currTempo = sortedMidiEvents[0].data; + let currTime = 0; + for (let i = 1; i < sortedMidiEvents.length - 1; i++) { + let event = sortedMidiEvents[i]; + if (getEventType(event) === "meta" && event.metaType === 81) { + currTempo = event.data; } + let adjustedTime = event.deltaTime * currTempo / baseTempo; + currTime += adjustedTime; + event.time = currTime; } } @@ -303,20 +318,6 @@ const MidiToNotes = (function () { } } - function generateWarnings(sortedMidiEvents, timeDivision) { - for (const event of sortedMidiEvents) { - const eventType = getEventType(event); - if (eventType === "meta") { - if (event.metaType === 81 && event.time !== 0) { - // tempo change - midiWarnings.add("Tempo change (unsupported)", { - beat: Math.floor(event.time / timeDivision), - }); - } - } - } - } - /** Returns whether a note is snapped (quantized) */ function warnIfUnsnapped(eventTime, timeDivision, snaps) { for (const snap of snaps) { diff --git a/test/bpmtest.mid b/test/bpmtest.mid new file mode 100644 index 0000000000000000000000000000000000000000..9aa0489b5cf5f40c330d2e0f2e361b51af37173c GIT binary patch literal 645 zcmeYb$w*;fU|<7cM&<*)Aw}5?3{3e9|07sfm?StD{s%I%FI1SvFu|s#qQQotDPxc@ nfbL@5abqw#i@R_G)tm+NC8zoUY8nTOOsW}2out6 Date: Sun, 12 May 2024 00:46:04 -0400 Subject: [PATCH 2/4] update default form inputs and changelog --- index.html | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 4ee2a56..1117afd 100644 --- a/index.html +++ b/index.html @@ -35,11 +35,11 @@

Slide mode
- + - +
@@ -104,7 +104,7 @@

- Song info -

- Chart info -

- i + i @@ -144,7 +144,7 @@

- Other -

i - + i @@ -280,6 +280,10 @@

Examples

Version history

+

+ v1.9
+ Added support for tempo changes +

v1.8a:
Changed "Song Folder" to "trackRef" @@ -379,7 +383,7 @@

Version history