#! /usr/local/bin/pvtool

#define USAGE_MESSAGE "\
\tdenoise <pv input file> <pv output file> [<threshold scalar>]\n\
\n\
This program reduces components in each frame that are below a certain\n\
level. This level is the threshold_scalar multiplied by the maximum level\n\
in the entire sound file. The default threshold_scalar is 0.02\n"

#define DEFAULT_THRESHOLD_SCALAR 0.02

/*****************************************************************************/

int
pvaction (void)
{
  int i, j;
  float threshold_scalar, max, val, bin_thresh, bin_thresh2, frac;

  if (parameter_count >= 1)
    {
      threshold_scalar = fparameter[0];
      printf ("Using threshold value %f.\n", threshold_scalar);
    }
  else
    threshold_scalar = DEFAULT_THRESHOLD_SCALAR;

  max = 0;
  for (i = 0; i < OUTPUT_FRAMES; i++)
    for (j = 0; j < bins; j++)
      {
	val = INPUT1_MAG (i, j);
	if (val > max)
	  max = val;
      }
  bin_thresh = threshold_scalar * max;
  bin_thresh2 = threshold_scalar * max / 2;

  for (i = 0; i < OUTPUT_FRAMES; i++)
    for (j = 0; j < bins; j++)
      {
	if (INPUT1_MAG (i, j) > bin_thresh)
	  {
	    /* Loud, let through. */
	    OUTPUT_PHIDOT (i, j) = INPUT1_PHIDOT (i, j);
	    OUTPUT_MAG (i, j) = INPUT1_MAG (i, j);
	  }
	else if (INPUT1_MAG (i, j) > bin_thresh2)
	  {
	    /* Middling, reduce heavily. */
	    frac = (INPUT1_MAG (i, j) - bin_thresh2) / bin_thresh2;

	    OUTPUT_PHIDOT (i, j) = (INPUT1_PHIDOT (i, j) * frac +
				    bin_to_freq (j) * (1 - frac));
	    OUTPUT_MAG (i, j) = INPUT1_MAG (i, j) * frac;
	  }
	else
	  {
	    /* Low, remove. */
	    OUTPUT_PHIDOT (i, j) = bin_to_freq (j);
	    OUTPUT_MAG (i, j) = 0;
	  }
      }

  return (0);
}
