public void comb_filter(final float[] exc,
                          final int esi,
                          final float[] new_exc,
                          final int nsi,
                          final int nsf,
                          final int pitch,
                          final float[] pitch_gain,
                          float comb_gain)
  {
    int i, j;
    float exc_energy = 0.0f;
    float new_exc_energy = 0.0f;
    float gain, step, fact, g=0.0f;

    /*Compute excitation energy prior to enhancement*/
    for (i = esi; i < esi + nsf; i++) {
      exc_energy += exc[i] * exc[i];
    }

    /* Some gain adjustment if pitch is too high or if unvoiced */
    g = .5f * Math.abs(pitch_gain[0] + pitch_gain[1] + pitch_gain[2] +
                       last_pitch_gain[0] + last_pitch_gain[1] +
                       last_pitch_gain[2]);
    if (g > 1.3f)
      comb_gain *= 1.3f / g;
    if (g < .5f)
      comb_gain *= 2.0f * g;
    
    step = 1.0f / nsf;
    fact = 0;

    /* Apply pitch comb-filter (filter out noise between pitch harmonics)*/
    for (i = 0, j = esi; i < nsf; i++, j++) {
      fact += step;
      new_exc[nsi+i] = exc[j] + comb_gain * fact *
                                (pitch_gain[0] * exc[j - pitch + 1] +
                                 pitch_gain[1] * exc[j - pitch] +
                                 pitch_gain[2] * exc[j - pitch - 1]) +
                                comb_gain * (1.0f - fact) *
                                (last_pitch_gain[0] * exc[j - last_pitch + 1] +
                                 last_pitch_gain[1] * exc[j - last_pitch] +
                                 last_pitch_gain[2] * exc[j - last_pitch - 1]);
    }

    last_pitch_gain[0] = pitch_gain[0];
    last_pitch_gain[1] = pitch_gain[1];
    last_pitch_gain[2] = pitch_gain[2];
    last_pitch = pitch;

    /* Gain after enhancement*/
    for (i = nsi; i < nsi + nsf; i++)
      new_exc_energy += new_exc[i] * new_exc[i];

    /* Compute scaling factor and normalize energy*/
    gain = (float) (Math.sqrt(exc_energy / (.1f + new_exc_energy)));
    if (gain < .5f) {
      gain = .5f;
    }
    if (gain > 1.0f) {
      gain = 1.0f;
    }

    for (i = nsi; i < nsi + nsf; i++) {
      smooth_gain = .96f * smooth_gain + .04f * gain;
      new_exc[i] *= smooth_gain;
    }
  }