Tweaks to the new transient detector
authorJean-Marc Valin <jmvalin@jmvalin.ca>
Mon, 19 Nov 2012 21:36:22 +0000 (16:36 -0500)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Mon, 19 Nov 2012 21:41:14 +0000 (16:41 -0500)
Instead of using the average energy over the frame, we use a half-way
point between the average energy and the max energy.

celt/celt_encoder.c

index c5fb96e..8b92811 100644 (file)
@@ -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);*/