using System; namespace ytLive.Helpers; /// The fader scale for the audio dock: the model stores LINEAR gain (0..1), the dock /// shows and edits DECIBELS, because "−6 dB" means something to a person and "0.50" does not. /// /// Range: −∞ (silence) to +6 dB of headroom above unity. 0 dB is unity gain, which is what /// the old 1.0 meant — so a persisted 0.8 comes back as ≈ −1.9 dB and nothing about the stored /// data changes. /// /// Creator context (2026-10-30): nearly deaf on the right, so the fader number is read, not /// heard. The scale therefore has to be the true one, not a cosmetic curve. public static class GainDb { /// Silence floor. Anything at or below this reads as −∞ and writes as 0 gain. public const double FloorDb = -60; public const double MaxDb = 6; /// Linear gain → dB, clamped to the fader's range. Zero becomes . public static double ToDb(double gain) { if (gain <= 0) return FloorDb; var db = 20 * Math.Log10(gain); return Math.Clamp(db, FloorDb, MaxDb); } /// dB → linear gain. At the floor the result is exactly 0 (true silence), so the /// bottom of the fader cannot leave a residue of noise. public static double FromDb(double db) { if (db <= FloorDb) return 0; return Math.Pow(10, Math.Clamp(db, FloorDb, MaxDb) / 20); } /// "−∞", "−6.0", "+1.5" — the label beside a fader. public static string Label(double db) => db <= FloorDb ? "−∞" : (db > 0 ? "+" : string.Empty) + db.ToString("0.0"); /// Mono fold: the accessible downmix. Averages the pair so hard-panned content is /// audible on both sides at half amplitude instead of absent from one. public static float MonoFold(float left, float right) => (left + right) * 0.5f; }