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;
}