iOS 1.0 RC 1: battery and heat work, version label, web player redraw tweaks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-11-06 08:31:00 -08:00
1 parent 0fc35b13e8
commit c0e33b5e3e
18 files changed
+143 -36

No files matched your search

+28 -10
View File
@@ -102,12 +102,17 @@ const Wave = {
return;
}
const names = Object.keys(this.peaks), n = this.peaks[names[0]].length;
const full = new Float32Array(n), mixed = new Float32Array(n);
for (const nm of names) {
const g = stemGain(nm, names);
this.peaks[nm].forEach((p, i) => { const v = p / 1000; full[i] += v * v; mixed[i] += v * v * g * g; });
// The envelope only changes with the song or the mix, not every redraw.
const gains = names.map(nm => stemGain(nm, names)), gk = gains.join();
if (this.env?.peaks !== this.peaks || this.env.gk !== gk) {
const full = new Float32Array(n), mixed = new Float32Array(n);
names.forEach((nm, k) => {
const g = gains[k];
this.peaks[nm].forEach((p, i) => { const v = p / 1000; full[i] += v * v; mixed[i] += v * v * g * g; });
});
this.env = { peaks: this.peaks, gk, full, mixed, max: Math.sqrt(Math.max(...full)) || 1 };
}
const max = Math.sqrt(Math.max(...full)) || 1;
const { full, mixed, max } = this.env;
const bars = Math.max(20, Math.floor(w / 3)), bw = w / bars;
for (let b = 0; b < bars; b++) {
const i = Math.floor(b / bars * n);
@@ -117,6 +122,15 @@ const Wave = {
x.fillStyle = b / bars < frac ? this.c.accent : this.c.bar; x.fillRect(b * bw, (h - bh) / 2, bw - 1, bh);
}
},
// Redraws during playback only when the played part has grown by a bar (or a pixel without peaks).
follow() {
const w = this.canvas.clientWidth, dur = E.duration();
const steps = this.peaks ? Math.max(20, Math.floor(w / 3)) : w;
const at = dur ? Math.floor(Math.min(1, E.position() / dur) * steps) : 0;
if (at === this.at) return;
this.at = at;
this.draw();
},
};
{
let drag = false;
@@ -387,10 +401,14 @@ document.addEventListener("keydown", ev => {
else if (k === "]" || k === "[") { const i = SPEEDS.indexOf(S.speed) + (k === "]" ? 1 : -1); if (SPEEDS[i]) setSpeed(SPEEDS[i]); }
});
(function frame() {
if (E.playing && !E.loading) { $("#t-pos").textContent = fmtTime(E.position()); Wave.draw(); tickLyrics(); }
requestAnimationFrame(frame);
})();
// The clock, waveform and lyrics follow playback 5 times a second instead of every frame:
// none of them change faster than that, and a 120 Hz loop keeps phones warm.
setInterval(() => {
if (document.hidden || !E.playing || E.loading) return;
const t = fmtTime(E.position()), el = $("#t-pos");
if (el.textContent !== t) el.textContent = t;
Wave.follow(); tickLyrics();
}, 200);
setInterval(() => { if (E.playing) { UI.progress(); saveQueue(); } }, 5000);
on("track", () => { UI.track(); UI.transport(); UI.progress(); Wave.load(Q.cur()); marks(); if (drawer) UI.drawer(); });
@@ -1154,5 +1172,5 @@ async function connect() {
UI.all();
route();
Live.poll();
setInterval(() => Stems.refresh(), 5 * 60 * 1000);
setInterval(() => { if (!document.hidden) Stems.refresh(); }, 5 * 60 * 1000);
})();