Shipping 175 ms as the built-in mic delay was wrong on principle, not just in value: it shifts every creator's voice to correct one camera on one desk, and it hides whether a desync is theirs or ours. A correction has to be something the creator turned on. So DefaultMicSyncOffsetMs is 0. The control stays (slider 0..500, off/175/350 presets, applied value logged) for anyone whose camera needs it; it is simply no longer pre-applied. The global offset was already 0. AudioSyncSettingsTests pins the rule: a fresh profile reads 0 for both, the mic delay refuses a negative (advancing is the global offset's job) and clamps above 500, and set values round-trip. 676 pass, 0 warnings. Scope justification: Assets/starting-background.jpg is outside this unit — the creator's replacement art, still awaiting their visual check.
48 lines
1.7 KiB
C#
48 lines
1.7 KiB
C#
using System;
|
|
using System.IO;
|
|
using Microsoft.Data.Sqlite;
|
|
using Xunit;
|
|
using ytLive.Services;
|
|
|
|
namespace ytLive.Tests;
|
|
|
|
/// <summary>
|
|
/// Sync offsets ship at zero. A correction belongs to one camera on one desk, so a fresh profile must
|
|
/// not arrive with audio already shifted — a non-zero default would move every creator's voice to fix
|
|
/// one machine and would hide whether the fault is theirs or ours.
|
|
/// </summary>
|
|
public sealed class AudioSyncSettingsTests : IDisposable
|
|
{
|
|
private readonly string _db = Path.Combine(Path.GetTempPath(), $"ytLlive-syncsettings-{Guid.NewGuid():N}.db");
|
|
|
|
public void Dispose()
|
|
{
|
|
SqliteConnection.ClearAllPools();
|
|
try { File.Delete(_db); } catch (IOException) { /* best effort */ }
|
|
}
|
|
|
|
[Fact]
|
|
public void Both_offsets_start_at_zero_and_only_then_take_a_value()
|
|
{
|
|
using (var store = new LayoutStore(_db))
|
|
{
|
|
Assert.Equal(0, store.LoadMicSyncOffsetMs()); // opt-in, not pre-applied
|
|
Assert.Equal(0, store.LoadAudioSyncOffsetMs());
|
|
|
|
// A mic delay cannot be negative — advancing is the global offset's job.
|
|
store.SaveMicSyncOffsetMs(-120);
|
|
Assert.Equal(0, store.LoadMicSyncOffsetMs());
|
|
|
|
store.SaveMicSyncOffsetMs(600); // beyond the slider's range
|
|
Assert.Equal(500, store.LoadMicSyncOffsetMs());
|
|
|
|
store.SaveMicSyncOffsetMs(240);
|
|
store.SaveAudioSyncOffsetMs(-130);
|
|
}
|
|
|
|
using var reopened = new LayoutStore(_db);
|
|
Assert.Equal(240, reopened.LoadMicSyncOffsetMs());
|
|
Assert.Equal(-130, reopened.LoadAudioSyncOffsetMs());
|
|
}
|
|
}
|