diff --git a/celt/celt_encoder.c b/celt/celt_encoder.c index c5fb96ebad071c9d51c39d1ed87df4451d8bb307..8b92811bc532a048d770287d833806935f0dd4e4 100644 --- a/celt/celt_encoder.c +++ b/celt/celt_encoder.c @@ -238,6 +238,7 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int opus_val32 mean; opus_int32 unmask=0; opus_val32 norm; + opus_val16 maxE; mem0=0; mem1=0; /* High-pass filter: (1 - 2*z^-1 + z^-2) / (1 - z^-1 + .5*z^-2) */ @@ -276,7 +277,7 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int mean=0; mem0=0; - /* Grouping by two to reduce complexity */ + /* Grouping by two to reduce complexity */ /* Forward pass to compute the post-echo threshold*/ for (i=0;i<len2;i++) { @@ -292,6 +293,7 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int } mem0=0; + maxE=0; /* Backward pass to compute the pre-echo threshold */ for (i=len2-1;i>=0;i--) { @@ -302,13 +304,22 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int tmp[i] = mem0 + MULT16_16_P15(QCONST16(0.125f,15),tmp[i]-mem0); #endif mem0 = tmp[i]; + maxE = MAX16(maxE, mem0); } - /*for (i=0;i<len;i++)printf("%f ", tmp[i]/mean);printf("\n");*/ + /*for (i=0;i<len2;i++)printf("%f ", tmp[i]/mean);printf("\n");*/ - /* Compute the ratio of the mean energy over the harmonic mean of the energy. + /* Compute the ratio of the "frame energy" over the harmonic mean of the energy. This essentially corresponds to a bitrate-normalized temporal noise-to-mask ratio */ + /* As a compromise with the old transient detector, frame energy is the + geometric mean of the energy and half the max */ +#ifdef FIXED_POINT + /* Costs two sqrt() to avoid overflows */ + mean = MULT16_16(celt_sqrt(mean), celt_sqrt(MULT16_16(maxE,len2>>1))); +#else + mean = sqrt(mean * maxE*.5*len2); +#endif /* Inverse of the mean energy in Q15+6 */ norm = SHL32(EXTEND32(len2),6+14)/ADD32(EPSILON,SHR32(mean,1)); /* Compute harmonic mean discarding the unreliable boundaries @@ -333,10 +344,10 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int mask_metric = unmask; } } - is_transient = mask_metric>141; + is_transient = mask_metric>200; /* Arbitrary metric for VBR boost */ - tf_max = MAX16(0,celt_sqrt(64*mask_metric)-64); + tf_max = MAX16(0,celt_sqrt(27*mask_metric)-42); /* *tf_estimate = 1 + MIN16(1, sqrt(MAX16(0, tf_max-30))/20); */ *tf_estimate = QCONST16(1.f, 14) + celt_sqrt(MAX16(0, SHL32(MULT16_16(QCONST16(0.0069,14),IMIN(163,tf_max)),14)-QCONST32(0.139,28))); /*printf("%d %f\n", tf_max, mask_metric);*/