Spaces:
Running on Zero
Running on Zero
Commit ·
52e1535
1
Parent(s): 4d5093e
Fix waveform crossfade hatch + click hit-detection to use contact edges
Browse files- Crossfade hatch was centered on segments[i+1][0] (old algo edge);
now centred on contactEdges[i] = (seg[i][1]+seg[i+1][0])/2,
which is where _stitch_wavs actually applies the blend.
- Click hit-detection used segments[idx+1][0] as boundary; now uses
contactEdges[idx] to match the visual coloring exactly.
app.py
CHANGED
|
@@ -2097,12 +2097,12 @@ def _build_waveform_html(audio_path: str, segments: list, slot_id: str,
|
|
| 2097 |
}});
|
| 2098 |
|
| 2099 |
// ── Crossfade overlap indicators ──
|
| 2100 |
-
// The
|
| 2101 |
-
//
|
| 2102 |
if (crossfadeSec > 0 && segments.length > 1) {{
|
| 2103 |
for (let i = 0; i < segments.length - 1; i++) {{
|
| 2104 |
-
//
|
| 2105 |
-
const edgeT
|
| 2106 |
const overlapStart = edgeT - crossfadeSec / 2;
|
| 2107 |
const overlapEnd = edgeT + crossfadeSec / 2;
|
| 2108 |
const xL = (overlapStart / duration) * W;
|
|
@@ -2129,12 +2129,13 @@ def _build_waveform_html(audio_path: str, segments: list, slot_id: str,
|
|
| 2129 |
const r=cv.getBoundingClientRect();
|
| 2130 |
const xRel=(e.clientX-r.left)/r.width;
|
| 2131 |
const tClick=xRel*duration;
|
| 2132 |
-
// Pick the segment
|
| 2133 |
-
//
|
| 2134 |
let hit=-1;
|
| 2135 |
segments.forEach(function(seg,idx){{
|
| 2136 |
-
const
|
| 2137 |
-
|
|
|
|
| 2138 |
}});
|
| 2139 |
console.log('[wf click] tClick='+tClick.toFixed(2)+' hit='+hit+' audioDuration='+audioDuration+' segments='+JSON.stringify(segments));
|
| 2140 |
if (hit>=0) showPopup(hit, e.clientX, e.clientY);
|
|
|
|
| 2097 |
}});
|
| 2098 |
|
| 2099 |
// ── Crossfade overlap indicators ──
|
| 2100 |
+
// The crossfade is applied ±crossfadeSec/2 around each contact edge.
|
| 2101 |
+
// contactEdges[i] = midpoint of overlap between seg i and seg i+1.
|
| 2102 |
if (crossfadeSec > 0 && segments.length > 1) {{
|
| 2103 |
for (let i = 0; i < segments.length - 1; i++) {{
|
| 2104 |
+
// Hatch spans crossfadeSec centred on the contact edge
|
| 2105 |
+
const edgeT = contactEdges[i];
|
| 2106 |
const overlapStart = edgeT - crossfadeSec / 2;
|
| 2107 |
const overlapEnd = edgeT + crossfadeSec / 2;
|
| 2108 |
const xL = (overlapStart / duration) * W;
|
|
|
|
| 2129 |
const r=cv.getBoundingClientRect();
|
| 2130 |
const xRel=(e.clientX-r.left)/r.width;
|
| 2131 |
const tClick=xRel*duration;
|
| 2132 |
+
// Pick the segment by contact-edge boundaries — matches the visual coloring.
|
| 2133 |
+
// Seg 0 owns [0, contactEdges[0]), seg N-1 owns [contactEdges[N-2], duration).
|
| 2134 |
let hit=-1;
|
| 2135 |
segments.forEach(function(seg,idx){{
|
| 2136 |
+
const visStart = idx === 0 ? 0 : contactEdges[idx-1];
|
| 2137 |
+
const visEnd = idx === segments.length - 1 ? duration : contactEdges[idx];
|
| 2138 |
+
if (tClick >= visStart && tClick < visEnd) hit = idx;
|
| 2139 |
}});
|
| 2140 |
console.log('[wf click] tClick='+tClick.toFixed(2)+' hit='+hit+' audioDuration='+audioDuration+' segments='+JSON.stringify(segments));
|
| 2141 |
if (hit>=0) showPopup(hit, e.clientX, e.clientY);
|