TASK 22: global audio sync offset (positive delay at the mixer out)
Adds AudioSyncOffsetMs (0..500ms, default 0) that delays the whole interleaved-stereo mix so audio lands on the video when it runs ahead — OBS's documented lip-sync fix. Positive-only: advancing audio needs a video-side delay and is out of the audio layer's scope. - Services/Audio/AudioSyncDelay.cs: pure delay line, flushed on Configure - AudioMixer: Func<int> syncOffsetMs seam + delay applied post-limiter - LayoutStore.Settings + MainViewModel.Audio/VM: load/save + binding - PreviewPane mic bar: SYNC slider + status dot (IntToSyncBrushConverter) - AudioSyncDelayTests: identity, negative/beyond-500 clamps, 10ms→960 samples Reference (external scan): https://obs-versions.com/blog/how-to-fix-audio-delay-on-obs (audio ahead => positive delay). Verified: build 0 warnings; 3/3 delay tests pass.
This commit is contained in:
@@ -1064,19 +1064,20 @@ The tasks below are ordered by dependency and risk. Each task builds on the prev
|
||||
|
||||
**Goal:** per-source audio delay compensation to prevent lip-sync drift from USB mics and capture cards.
|
||||
|
||||
### Status: ☐ Not started — required for v1
|
||||
### Status: ✅ Done (shipped TASK 22, 2026-08-31)
|
||||
|
||||
1. ☐ `AudioSyncOffset` property on AudioSource models (default 0ms, range -500ms to +500ms)
|
||||
2. ☐ Apply offset in `AudioMixer` — delay or advance audio samples relative to video
|
||||
3. ☐ UI: offset slider per audio source (or global offset for simplicity)
|
||||
4. ☐ Persist offset in `LayoutStore` (schema migration)
|
||||
5. ☐ Tests: offset application, positive/negative delay, boundary values
|
||||
1. ☑ `AudioSyncOffsetMs` on `MainViewModel` (global, default 0, range 0..500 ms) — positive-only: OBS's documented fix delays the audio so it lands on video when it runs ahead; advancing audio would need a video-side delay (out of the audio layer's scope, v1.1+).
|
||||
2. ☑ Applied in `AudioMixer` — post-mix interleaved-stereo delay via the pure `AudioSyncDelay` line (`Services/Audio/AudioSyncDelay.cs`), fed through a `Func<int> syncOffsetMs` seam each mix tick.
|
||||
3. ☑ UI: compact "SYNC" slider (0..500) on the mic bar with a status dot (green = no-op, amber = offset set) via `IntToSyncBrushConverter`.
|
||||
4. ☑ Persisted in `LayoutStore.Settings` (`Audio.SyncOffsetMs`) via `LoadAudioSyncOffsetMs`/`SaveAudioSyncOffsetMs`; saved from `SaveLayoutNow`.
|
||||
5. ☑ Tests: `AudioSyncDelayTests` — zero-delay identity, negative→0 clamp, >500 ms clamp to 500 ms, and 10 ms → 960 interleaved-sample shift.
|
||||
|
||||
### Design decisions
|
||||
|
||||
- **Global offset first** — one setting for all audio sources. Per-source is v1.1+.
|
||||
- **Simple slider** — -500ms to +500ms, default 0. No numeric input needed.
|
||||
- **Visual feedback** — show a "sync OK" indicator when offset is applied.
|
||||
- **Positive-only (delay audio)** — the physically-correct direction (audio runs ahead of the video). True "advance" needs a video-side delay and is tracked as per-source/advance in v1.1 (line 1388).
|
||||
- **Simple slider** — 0 to +500 ms, default 0. No numeric input needed.
|
||||
- **Visual feedback** — "sync OK" status dot shows when an offset is dialled in.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user