feat: signed A/V sync offset (−500..+500), negative advances by eating live stream head (OBS eat-head semantics)
Positive offsets still delay the whole mix via the delay line (lip-sync fix); negative offsets now ARM once at StartLive and drop |N| ms off the pipe's write head so audio events land earlier when audio runs BEHIND video. Slider relabeled AUDIO SYNC, Min −500, locked while live/recording (IsEditMode). LayoutStore and VM clamp to −500..500. OBS reference for eat-the-head negative sync: https://obsproject.com/kb/obs-studio/buffering-time (negative sync values pull audio earlier by discarding buffered player audio). Test: StartLive_NegativeOffset_AdvancesAudio_ByDroppingTheStreamHead (6x0.9 head must be eaten before 0.2 bed reaches the wire).
This commit is contained in:
@@ -29,17 +29,19 @@ public partial class LayoutStore : IDisposable
|
||||
insert.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
/// <summary>The global audio-sync delay in milliseconds (TASK 22), 0..500,
|
||||
/// default 0. Restored at startup so the mixer starts on the user's offset.</summary>
|
||||
/// <summary>The global audio-sync offset in milliseconds (TASK 22), −500..500,
|
||||
/// default 0: positive delays the mix (audio ahead of video), negative
|
||||
/// advances it (audio behind video). Restored at startup so the mixer starts
|
||||
/// on the user's offset.</summary>
|
||||
public int LoadAudioSyncOffsetMs()
|
||||
{
|
||||
var value = GetSetting("Audio.SyncOffsetMs");
|
||||
return int.TryParse(value, out var ms) ? Math.Clamp(ms, 0, 500) : 0;
|
||||
return int.TryParse(value, out var ms) ? Math.Clamp(ms, -500, 500) : 0;
|
||||
}
|
||||
|
||||
public void SaveAudioSyncOffsetMs(int ms)
|
||||
{
|
||||
UpsertSetting("Audio.SyncOffsetMs", Math.Clamp(ms, 0, 500).ToString());
|
||||
UpsertSetting("Audio.SyncOffsetMs", Math.Clamp(ms, -500, 500).ToString());
|
||||
}
|
||||
|
||||
/// <summary>The user's chosen record output folder (TASK 18), or null to use the
|
||||
|
||||
Reference in New Issue
Block a user