Audio Wave: segments = user splits only (721 groups are markers, not segments)
Per clarification: the 721 group lines are clip markers, NOT segments. Segments come ONLY from user split points, numbered globally from 1 — so the first split is seg1, not seg23. 0 splits = 0 segments; N splits = N segments (seg k = point k-1 .. split k, tail after the last split excluded). group lines still drawn (bold) + used for the group#. JS matches (segPoints/nSegs). Empty summary now prompts to add splits. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+12
-9
@@ -91,12 +91,12 @@ function setupWave(node) {
|
||||
for (let t = step; t < st.duration - 1e-6; t += step) arr.push(t);
|
||||
return arr;
|
||||
}
|
||||
function segStarts() { // union of 0 + user splits + group lines
|
||||
function segPoints() { // [0] + user splits (NOT the group lines)
|
||||
const set = new Set([0]);
|
||||
for (const s of st.splits) if (s > 0 && s < st.duration) set.add(Math.round(s * 100) / 100);
|
||||
for (const g of groupBounds()) set.add(Math.round(g * 100) / 100);
|
||||
return Array.from(set).sort((a, b) => a - b);
|
||||
}
|
||||
const nSegs = () => Math.max(0, segPoints().length - 1); // N splits -> N segments (tail excluded)
|
||||
|
||||
function serialize() { // write ONLY user splits (small + stable)
|
||||
const w = getW(node, "segments_json"); if (!w) return;
|
||||
@@ -111,7 +111,7 @@ function setupWave(node) {
|
||||
function syncNotesBox() { // one segN: line per segment, preserve notes
|
||||
const nw = getW(node, "notes"); if (!nw) return;
|
||||
const { seg, glob } = parseNotes(nw.value);
|
||||
const n = segStarts().length; const lines = [];
|
||||
const n = nSegs(); const lines = [];
|
||||
for (let i = 1; i <= n; i++) lines.push(`seg${i}: ${seg[i] !== undefined ? seg[i] : ""}`);
|
||||
const val = lines.concat(glob).join("\n");
|
||||
if (nw.value !== val) { nw.value = val; nw.callback?.(val); }
|
||||
@@ -127,10 +127,10 @@ function setupWave(node) {
|
||||
function draw() {
|
||||
ctx.fillStyle = "#141418"; ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
const H = canvas.height, mid = H / 2;
|
||||
const starts = segStarts();
|
||||
const pts = segPoints(); // [0, split1, split2, ...]; seg k = pts[k-1]..pts[k]
|
||||
const sel = selRange();
|
||||
if (sel) { // shade selected range
|
||||
const a = starts[sel[0] - 1], b = sel[1] < starts.length ? starts[sel[1]] : st.duration;
|
||||
if (sel) { // shade selected segment range
|
||||
const a = pts[sel[0] - 1], b = sel[1] < pts.length ? pts[sel[1]] : st.duration;
|
||||
if (a !== undefined) { ctx.fillStyle = "#26364f"; ctx.fillRect(t2x(a), 0, t2x(b) - t2x(a), H); }
|
||||
}
|
||||
if (st.peaks) { // mirrored waveform around centre
|
||||
@@ -144,11 +144,14 @@ function setupWave(node) {
|
||||
ctx.lineWidth = 1;
|
||||
const { seg } = parseNotes(getW(node, "notes")?.value);
|
||||
ctx.font = "10px monospace";
|
||||
starts.forEach((s, i) => { // segment line + label top + note bottom
|
||||
const nseg = nSegs();
|
||||
pts.forEach((s, i) => { // split line; label seg i+1 (skip tail)
|
||||
const x = t2x(s);
|
||||
ctx.strokeStyle = "#7ec8a0"; ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, H); ctx.stroke();
|
||||
ctx.fillStyle = "#fff"; ctx.fillText(`S${i + 1} ${s.toFixed(1)}s`, x + 3, 11);
|
||||
if (seg[i + 1]) { ctx.fillStyle = "#ffd27a"; ctx.fillText(seg[i + 1].slice(0, 22), x + 3, H - 4); }
|
||||
if (i < nseg) {
|
||||
ctx.fillStyle = "#fff"; ctx.fillText(`S${i + 1} ${s.toFixed(1)}s`, x + 3, 11);
|
||||
if (seg[i + 1]) { ctx.fillStyle = "#ffd27a"; ctx.fillText(seg[i + 1].slice(0, 22), x + 3, H - 4); }
|
||||
}
|
||||
});
|
||||
ctx.strokeStyle = "#ff5a3c"; const px = t2x(st.audio.currentTime || 0); // playhead
|
||||
ctx.beginPath(); ctx.moveTo(px, 0); ctx.lineTo(px, H); ctx.stroke();
|
||||
|
||||
Reference in New Issue
Block a user