namespace ytLive.Services.Audio;
///
/// Supplies the live-mix gain values (mic + loopback) as Func seams for
/// , sourced from the VM's volume/mute state. Read live
/// on every mix tick so slider drags and mutes take effect immediately on the
/// stream. Mute and zero volume can never disagree: 0 always reads as muted.
///
public sealed class AudioGainProvider
{
private readonly Func _micMuted;
private readonly Func _micVolume;
private readonly Func _gameMuted;
private readonly Func _gameVolume;
public AudioGainProvider(
Func micMuted,
Func micVolume,
Func gameMuted,
Func gameVolume)
{
_micMuted = micMuted;
_micVolume = micVolume;
_gameMuted = gameMuted;
_gameVolume = gameVolume;
}
/// Mic gain for the live mix (0 = muted).
public double MicGain() => _micMuted() ? 0 : _micVolume();
/// Loopback (desktop/game) gain for the live mix (0 = muted).
/// Honesty rule (2026-09-01): WASAPI loopback capture does NOT shrink with the
/// endpoint volume — the creator dropped system volume to 20% and the captured
/// level stayed pegged — so the mixer must multiply by GameAudioVolume itself
/// for the stream to follow the knob (the old unity assumption left the stream
/// at full desktop volume while the headphones went quiet; ai.md always
/// specified loopbackGain = GameAudioVolume — the code had drifted).
public double LoopbackGain() => _gameMuted() ? 0 : _gameVolume();
}