ref: 413caa00c5e2e90d405662335f88bbcdac64a8cc
parent: 14454c49a82a2ef5a1d0f429ab1907164384e141
author: Jean-Marc Valin <[email protected]>
date: Mon Nov 19 11:36:22 EST 2012
Tweaks to the new transient detector Instead of using the average energy over the frame, we use a half-way point between the average energy and the max energy.
--- a/celt/celt_encoder.c
+++ b/celt/celt_encoder.c
@@ -238,6 +238,7 @@
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 @@
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 @@
}
mem0=0;
+ maxE=0;
/* Backward pass to compute the pre-echo threshold */
for (i=len2-1;i>=0;i--)
{
@@ -302,13 +304,22 @@
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 @@
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);*/