Upload 4 files
Browse files- app.js +18 -1
- index.html +8 -0
- worker.js +4 -2
app.js
CHANGED
|
@@ -119,8 +119,11 @@ const midiFileStatsEl = document.querySelector("#midiFileStats");
|
|
| 119 |
const midiStartBarInput = document.querySelector("#midiStartBar");
|
| 120 |
const midiStartBarValue = document.querySelector("#midiStartBarValue");
|
| 121 |
const midiStartBarTimeEl = document.querySelector("#midiStartBarTime");
|
|
|
|
|
|
|
| 122 |
|
| 123 |
let midiSeedActive = false;
|
|
|
|
| 124 |
let midiTokens = [];
|
| 125 |
let midiStartBar = 0;
|
| 126 |
let midiFileName = "";
|
|
@@ -777,7 +780,8 @@ async function start() {
|
|
| 777 |
bpm: Number(tempoEl.textContent || 120),
|
| 778 |
midiSeedActive: midiSeedActive,
|
| 779 |
midiTokens: midiSeedActive ? midiTokens : [],
|
| 780 |
-
midiStartBar: midiStartBar
|
|
|
|
| 781 |
});
|
| 782 |
});
|
| 783 |
|
|
@@ -788,6 +792,7 @@ async function start() {
|
|
| 788 |
if (modelFileInput) modelFileInput.disabled = true;
|
| 789 |
if (vocabFileInput) vocabFileInput.disabled = true;
|
| 790 |
toggleButtons.forEach(btn => btn.disabled = true);
|
|
|
|
| 791 |
midiFileInput.disabled = true;
|
| 792 |
midiStartBarInput.disabled = true;
|
| 793 |
|
|
@@ -815,6 +820,7 @@ function stop() {
|
|
| 815 |
if (modelFileInput) modelFileInput.disabled = false;
|
| 816 |
if (vocabFileInput) vocabFileInput.disabled = false;
|
| 817 |
toggleButtons.forEach(btn => btn.disabled = false);
|
|
|
|
| 818 |
midiFileInput.disabled = false;
|
| 819 |
midiStartBarInput.disabled = false;
|
| 820 |
if (synth) {
|
|
@@ -1488,6 +1494,17 @@ toggleButtons.forEach(btn => {
|
|
| 1488 |
});
|
| 1489 |
});
|
| 1490 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1491 |
midiFileInput.addEventListener("change", async (e) => {
|
| 1492 |
const file = e.target.files?.[0];
|
| 1493 |
if (!file) return;
|
|
|
|
| 119 |
const midiStartBarInput = document.querySelector("#midiStartBar");
|
| 120 |
const midiStartBarValue = document.querySelector("#midiStartBarValue");
|
| 121 |
const midiStartBarTimeEl = document.querySelector("#midiStartBarTime");
|
| 122 |
+
const midiBpmModeGroup = document.querySelector("#midiBpmModeGroup");
|
| 123 |
+
const midiBpmModeButtons = midiBpmModeGroup ? midiBpmModeGroup.querySelectorAll(".toggle-btn") : [];
|
| 124 |
|
| 125 |
let midiSeedActive = false;
|
| 126 |
+
let midiBpmMode = "lock";
|
| 127 |
let midiTokens = [];
|
| 128 |
let midiStartBar = 0;
|
| 129 |
let midiFileName = "";
|
|
|
|
| 780 |
bpm: Number(tempoEl.textContent || 120),
|
| 781 |
midiSeedActive: midiSeedActive,
|
| 782 |
midiTokens: midiSeedActive ? midiTokens : [],
|
| 783 |
+
midiStartBar: midiStartBar,
|
| 784 |
+
midiBpmMode: midiBpmMode
|
| 785 |
});
|
| 786 |
});
|
| 787 |
|
|
|
|
| 792 |
if (modelFileInput) modelFileInput.disabled = true;
|
| 793 |
if (vocabFileInput) vocabFileInput.disabled = true;
|
| 794 |
toggleButtons.forEach(btn => btn.disabled = true);
|
| 795 |
+
midiBpmModeButtons.forEach(btn => btn.disabled = true);
|
| 796 |
midiFileInput.disabled = true;
|
| 797 |
midiStartBarInput.disabled = true;
|
| 798 |
|
|
|
|
| 820 |
if (modelFileInput) modelFileInput.disabled = false;
|
| 821 |
if (vocabFileInput) vocabFileInput.disabled = false;
|
| 822 |
toggleButtons.forEach(btn => btn.disabled = false);
|
| 823 |
+
midiBpmModeButtons.forEach(btn => btn.disabled = false);
|
| 824 |
midiFileInput.disabled = false;
|
| 825 |
midiStartBarInput.disabled = false;
|
| 826 |
if (synth) {
|
|
|
|
| 1494 |
});
|
| 1495 |
});
|
| 1496 |
|
| 1497 |
+
midiBpmModeButtons.forEach(btn => {
|
| 1498 |
+
btn.addEventListener("click", () => {
|
| 1499 |
+
if (btn.disabled) return;
|
| 1500 |
+
|
| 1501 |
+
midiBpmModeButtons.forEach(b => b.classList.remove("active"));
|
| 1502 |
+
btn.classList.add("active");
|
| 1503 |
+
|
| 1504 |
+
midiBpmMode = btn.dataset.value;
|
| 1505 |
+
});
|
| 1506 |
+
});
|
| 1507 |
+
|
| 1508 |
midiFileInput.addEventListener("change", async (e) => {
|
| 1509 |
const file = e.target.files?.[0];
|
| 1510 |
if (!file) return;
|
index.html
CHANGED
|
@@ -149,6 +149,14 @@
|
|
| 149 |
<input id="midiStartBar" type="range" min="0" max="0" step="1" value="0" />
|
| 150 |
</div>
|
| 151 |
<p id="midiStartBarTime" class="midi-info-subtext"></p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
</div>
|
| 153 |
</div>
|
| 154 |
</section>
|
|
|
|
| 149 |
<input id="midiStartBar" type="range" min="0" max="0" step="1" value="0" />
|
| 150 |
</div>
|
| 151 |
<p id="midiStartBarTime" class="midi-info-subtext"></p>
|
| 152 |
+
|
| 153 |
+
<div class="toggle-group-container" style="margin-top: 14px;">
|
| 154 |
+
<span class="toggle-group-label" style="font-size: 0.72rem; margin-bottom: 6px; display: block; color: var(--color-text-muted);">MIDI Playback Tempo Mode</span>
|
| 155 |
+
<div class="toggle-group" id="midiBpmModeGroup">
|
| 156 |
+
<button type="button" class="toggle-btn active" data-value="lock">Lock MIDI BPM</button>
|
| 157 |
+
<button type="button" class="toggle-btn" data-value="model">Follow Model BPM</button>
|
| 158 |
+
</div>
|
| 159 |
+
</div>
|
| 160 |
</div>
|
| 161 |
</div>
|
| 162 |
</section>
|
worker.js
CHANGED
|
@@ -25,6 +25,7 @@ let numLayers = 2;
|
|
| 25 |
let temperature = 0.85;
|
| 26 |
let topK = 40;
|
| 27 |
let currentBpm = 120;
|
|
|
|
| 28 |
|
| 29 |
// Seeding settings
|
| 30 |
let midiSeedActive = false;
|
|
@@ -194,7 +195,7 @@ function makeAbcParser() {
|
|
| 194 |
if (this.pending?.type === "tempoHeader") {
|
| 195 |
const bpm = Number(String(token).split("=").pop());
|
| 196 |
if (Number.isFinite(bpm) && bpm >= 40 && bpm <= 220) {
|
| 197 |
-
if (!midiSeedActive || isWarmingUp) {
|
| 198 |
currentBpm = bpm;
|
| 199 |
self.postMessage({ action: "tempo", bpm: bpm });
|
| 200 |
}
|
|
@@ -263,7 +264,7 @@ function makeEventParser() {
|
|
| 263 |
if (token.startsWith("BPM_")) {
|
| 264 |
const bpm = Number(token.slice(4));
|
| 265 |
if (Number.isFinite(bpm) && bpm >= 40 && bpm <= 220) {
|
| 266 |
-
if (!midiSeedActive || isWarmingUp) {
|
| 267 |
currentBpm = bpm;
|
| 268 |
self.postMessage({ action: "tempo", bpm: bpm });
|
| 269 |
}
|
|
@@ -428,6 +429,7 @@ self.onmessage = async function (e) {
|
|
| 428 |
midiSeedActive = data.midiSeedActive;
|
| 429 |
midiTokens = data.midiTokens;
|
| 430 |
midiStartBar = data.midiStartBar;
|
|
|
|
| 431 |
|
| 432 |
parser = makeParser();
|
| 433 |
parser.reset();
|
|
|
|
| 25 |
let temperature = 0.85;
|
| 26 |
let topK = 40;
|
| 27 |
let currentBpm = 120;
|
| 28 |
+
let midiBpmMode = "lock";
|
| 29 |
|
| 30 |
// Seeding settings
|
| 31 |
let midiSeedActive = false;
|
|
|
|
| 195 |
if (this.pending?.type === "tempoHeader") {
|
| 196 |
const bpm = Number(String(token).split("=").pop());
|
| 197 |
if (Number.isFinite(bpm) && bpm >= 40 && bpm <= 220) {
|
| 198 |
+
if (!midiSeedActive || isWarmingUp || midiBpmMode === "model") {
|
| 199 |
currentBpm = bpm;
|
| 200 |
self.postMessage({ action: "tempo", bpm: bpm });
|
| 201 |
}
|
|
|
|
| 264 |
if (token.startsWith("BPM_")) {
|
| 265 |
const bpm = Number(token.slice(4));
|
| 266 |
if (Number.isFinite(bpm) && bpm >= 40 && bpm <= 220) {
|
| 267 |
+
if (!midiSeedActive || isWarmingUp || midiBpmMode === "model") {
|
| 268 |
currentBpm = bpm;
|
| 269 |
self.postMessage({ action: "tempo", bpm: bpm });
|
| 270 |
}
|
|
|
|
| 429 |
midiSeedActive = data.midiSeedActive;
|
| 430 |
midiTokens = data.midiTokens;
|
| 431 |
midiStartBar = data.midiStartBar;
|
| 432 |
+
midiBpmMode = data.midiBpmMode || "lock";
|
| 433 |
|
| 434 |
parser = makeParser();
|
| 435 |
parser.reset();
|