/*
The human ability to perceive changes in volume goes as the
logarithm of the stimulus (see: the Fechner-Weber Law), so a
linear increase in volume should cause an exponential increase
in volume.  Here we fit a function of the form:

audioVolume = a * exp(k * displayVolume) + b

where:

k is a free parameter (higher means more non-linear), and a and
b are fit in order to ensure f(0) = 0 and f(1) = 1.  k = 2 was
chosen by manual testing and gave reasonable results.
*/

const volumeCurveConstants = () => {
  const k = 2;
  const a = 1 / (Math.exp(k) - 1);
  const b = -a;
  return { k, a, b };
};

export const getAudioVolumeFromDisplayVolume = (
  displayVolume: number
): number => {
  const { k, a, b } = volumeCurveConstants();
  return a * Math.exp(k * displayVolume) + b;
};

export const getDisplayVolumeFromAudioVolume = (
  audioVolume: number
): number => {
  const { k, a, b } = volumeCurveConstants();
  return (1 / k) * Math.log((audioVolume - b) / a);
};
