namespace TIASshot {
/// <summary>
/// ゲイン更新比率の計算ロジック(ピュアロジック層).
/// ハードウェアに依存しない純粋な計算のみを担う.
/// </summary>
internal static class GainCalc {
/// <summary>
/// ゲイン値の更新比率を計算する.
/// value が 255.0f のときは updateRate によらず係数を 1.0 として比率を求める.
/// </summary>
/// <param name="value">現在の計測値</param>
/// <param name="target">目標値</param>
/// <param name="updateRate">更新レート(0 より大きい値を想定)</param>
/// <returns>更新比率</returns>
internal static float CalcRatio(float value, float target, float updateRate) {
float ratio = target / value;
ratio = (ratio - 1.0f) * (value == 255.0f ? 1.0f : updateRate) + 1.0f;
return ratio;
}
/// <summary>
/// 現在のゲイン値に更新比率を掛けた新しいゲイン設定値を求める.
/// ハードウェアが受け付ける範囲 [rangeMin, rangeMax] に収めて返す.
/// </summary>
/// <param name="currentValue">現在のゲイン設定値</param>
/// <param name="ratio">更新比率(<see cref="CalcRatio"/> の戻り値)</param>
/// <param name="rangeMin">設定可能な最小値</param>
/// <param name="rangeMax">設定可能な最大値</param>
/// <returns>範囲内に収めた新しいゲイン設定値</returns>
internal static int CalcGainValue(int currentValue, float ratio, int rangeMin, int rangeMax) {
// 計測値・目標値がともに 0 のとき比率は NaN になり更新量を決められないため現在値を維持する
if (float.IsNaN(ratio)) return currentValue;
// float→int キャストは範囲外・非有限値(Infinity)で未定義値になるため,
// キャスト前に double のまま範囲判定する
double value = 0.5 + (double)(currentValue * ratio);
if (value < rangeMin) return rangeMin;
if (value > rangeMax) return rangeMax;
return (int)value;
}
}
}