fix(tools): avsync says "unmeasurable" instead of trusting a 0.08 correlation
On ty-20261112-1401-952-0000-2.mp4 the per-window estimates ranged from +400 to -370 ms and only one window cleared 0.35, yet the tool printed "-370 ms, adjust by +370" from an overall correlation of 0.08. A number that wrong is worse than no number: it invites another build. Now: windows above 0.35 must also agree within 150 ms, and anything weaker reports "unmeasurable" with the remedy — three claps with the hands in the webcam frame, two seconds apart, which gives a sharp visual and audio transient instead of a mouth-motion proxy. Also reverted an onset-based envelope tried on the same clip: it dropped the best window's correlation from 0.47 to 0.08, so the plain level envelope stays. What the run did establish: lengths match (15.555 s video against 15.601 s audio, 0.3%), and the log confirms "mic delay 350 ms" was applied — the drift fix and the delay wiring both hold.
This commit is contained in:
+15
-4
@@ -129,10 +129,16 @@ def offset_ms(audio: np.ndarray, motion: np.ndarray, fps: float, max_ms: float =
|
||||
lag, corr = best_for(m[start:start + seg], a[start:start + seg])
|
||||
windows.append((start / grid, lag, corr))
|
||||
strong = sorted(lag for _, lag, corr in windows if corr >= 0.35)
|
||||
if strong:
|
||||
if len(strong) >= 2:
|
||||
mid = len(strong) // 2
|
||||
robust = strong[mid] if len(strong) % 2 else (strong[mid - 1] + strong[mid]) / 2
|
||||
spread = strong[-1] - strong[0]
|
||||
if spread > 150:
|
||||
# Windows that disagree this much cannot be averaged into an answer. Say so.
|
||||
return float("nan"), max(corr for _, _, corr in windows), windows
|
||||
return robust, max(corr for _, _, corr in windows), windows
|
||||
if strong:
|
||||
return float("nan"), max(corr for _, _, corr in windows), windows
|
||||
return overall_lag, overall_corr, windows
|
||||
|
||||
|
||||
@@ -168,13 +174,18 @@ def main() -> int:
|
||||
print(f"delta {diff:+8.3f} s ({pct:+.2f}% of the video length)")
|
||||
verdict = "lengths match" if abs(diff) < 0.05 else "LENGTH MISMATCH — a clock problem"
|
||||
print(f" {verdict}")
|
||||
quality = "strong" if corr >= 0.35 else "weak — treat the offset as a hint only"
|
||||
for start, wlag, wcorr in windows:
|
||||
mark = "*" if wcorr >= 0.35 else " "
|
||||
print(f" {start:5.1f}s {wlag:+7.0f} ms corr {wcorr:.2f} {mark}")
|
||||
print(f"offset {lag:+8.0f} ms (correlation {corr:.2f}, {quality})")
|
||||
direction = "sound LATER than the lips" if lag > 0 else "sound EARLIER than the lips"
|
||||
|
||||
if lag != lag or corr < 0.35:
|
||||
print("offset unmeasurable — too little agreement between mouth motion and speech")
|
||||
print(" record 3 claps with your hands in the webcam frame, 2 s apart")
|
||||
return 0
|
||||
|
||||
print(f"offset {lag:+8.0f} ms (correlation {corr:.2f})")
|
||||
if abs(lag) >= 20:
|
||||
direction = "sound LATER than the lips" if lag > 0 else "sound EARLIER than the lips"
|
||||
print(f" {direction} — adjust the mic delay by {-lag:+.0f} ms")
|
||||
else:
|
||||
print(" within a frame or two — leave it alone")
|
||||
|
||||
Reference in New Issue
Block a user