[FFmpeg-soc] [soc]: r5030 - in amr: amr-ffmpeg.diff amrnbdec.c

cmcq subversion at mplayerhq.hu
Mon Aug 10 22:23:57 CEST 2009


Author: cmcq
Date: Mon Aug 10 22:23:57 2009
New Revision: 5030

Log:
Update AGC functions after ffmpeg-devel discussion
ff_energyf is redundant
Avoid the name "energy" because it is not mathematically precise
Avoid the name "length" because it is ambiguous for vectors
qcelpdec changes should be included

Modified:
   amr/amr-ffmpeg.diff
   amr/amrnbdec.c

Modified: amr/amr-ffmpeg.diff
==============================================================================
--- amr/amr-ffmpeg.diff	Mon Aug 10 22:02:51 2009	(r5029)
+++ amr/amr-ffmpeg.diff	Mon Aug 10 22:23:57 2009	(r5030)
@@ -147,65 +147,99 @@ Index: libavcodec/acelp_vectors.c
  #include "acelp_vectors.h"
  
  const uint8_t ff_fc_2pulses_9bits_track1[16] =
-@@ -155,3 +156,25 @@
+@@ -155,3 +156,13 @@
          out[i] = weight_coeff_a * in_a[i]
                 + weight_coeff_b * in_b[i];
  }
 +
-+float ff_energyf(const float *v, int length)
-+{
-+    float sum = 0;
-+    int i;
-+
-+    for (i = 0; i < length; i++)
-+        sum += v[i] * v[i];
-+
-+    return sum;
-+}
-+
-+void ff_set_energyf(float *v_out, const float *v_in, float energy,
-+                    const int length)
++void ff_scale_to(float *out, const float *in, float norm_squared, const int n)
 +{
 +    int i;
-+    float scalefactor = ff_energyf(v_in, length);
++    float scalefactor = ff_dot_productf(in, in, n);
 +    if (scalefactor)
-+        scalefactor = sqrt(energy / scalefactor);
-+    for (i = 0; i < length; i++)
-+        v_out[i] = v_in[i] * scalefactor;
++        scalefactor = sqrt(norm_squared / scalefactor);
++    for (i = 0; i < n; i++)
++        out[i] = in[i] * scalefactor;
 +}
 Index: libavcodec/acelp_vectors.h
 ===================================================================
 --- libavcodec/acelp_vectors.h	(revision 19613)
 +++ libavcodec/acelp_vectors.h	(working copy)
-@@ -164,4 +164,31 @@
+@@ -164,4 +164,21 @@
  void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
                               float weight_coeff_a, float weight_coeff_b, int length);
  
 +/**
-+ * returns the energy
-+ * @param in input data array
-+ * @param length number of elements
-+ *
-+ * @return energy = sum of squares
-+ */
-+float ff_energyf(const float *in, int length);
-+
-+/**
-+ * Set the energy of a vector by scaling
++ * Set the sum of squares of a signal by scaling
 + *
-+ * @param v_out output vector
-+ * @param v_in vector to set energy of
-+ * @param energy new energy
-+ * @param length vectors length
++ * @param out output samples
++ * @param in input samples
++ * @param norm_squared new sum of squares
++ * @param n number of samples
 + *
-+ * @note If v is zero (or its energy underflows), the output is zero.
++ * @note If the input is zero (or its energy underflows), the output is zero.
 + *       This is the behavior of AGC in the AMR reference decoder. The QCELP
 + *       reference decoder seems to have undefined behavior.
 + *
 + * TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6
 + * 3GPP TS 26.090 6.1 (6)
 + */
-+void ff_set_energyf(float *v_out, const float *v_in, float energy,
-+                    const int length);
++void ff_scale_to(float *out, const float *in, float norm_squared, const int n);
 +
  #endif /* AVCODEC_ACELP_VECTORS_H */
+Index: libavcodec/qcelpdec.c
+===================================================================
+--- libavcodec/qcelpdec.c	(revision 19613)
++++ libavcodec/qcelpdec.c	(working copy)
+@@ -406,31 +406,6 @@
+ }
+ 
+ /**
+- * Compute the gain control
+- *
+- * @param v_in gain-controlled vector
+- * @param v_ref vector to control gain of
+- *
+- * @return gain control
+- *
+- * FIXME: If v_ref is a zero vector, it energy is zero
+- *        and the behavior of the gain control is
+- *        undefined in the specs.
+- *
+- * TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6
+- */
+-static float compute_gain_ctrl(const float *v_ref, const float *v_in, const int len)
+-{
+-    float scalefactor = ff_dot_productf(v_in, v_in, len);
+-
+-    if(scalefactor)
+-        scalefactor = sqrt(ff_dot_productf(v_ref, v_ref, len) / scalefactor);
+-    else
+-        av_log_missing_feature(NULL, "Zero energy for gain control", 1);
+-    return scalefactor;
+-}
+-
+-/**
+  * Apply generic gain control.
+  *
+  * @param v_out output vector
+@@ -442,15 +417,11 @@
+ static void apply_gain_ctrl(float *v_out, const float *v_ref,
+                             const float *v_in)
+ {
+-    int   i, j, len;
+-    float scalefactor;
++    int i;
+ 
+-    for(i=0, j=0; i<4; i++)
+-    {
+-        scalefactor = compute_gain_ctrl(v_ref + j, v_in + j, 40);
+-        for(len=j+40; j<len; j++)
+-            v_out[j] = scalefactor * v_in[j];
+-    }
++    for(i = 0; i < 160; i += 40)
++        ff_scale_to(v_out + i, v_in + i,
++                    ff_dot_productf(v_ref + i, v_ref + i, 40), 40);
+ }
+ 
+ /**

Modified: amr/amrnbdec.c
==============================================================================
--- amr/amrnbdec.c	Mon Aug 10 22:02:51 2009	(r5029)
+++ amr/amrnbdec.c	Mon Aug 10 22:23:57 2009	(r5030)
@@ -1010,7 +1010,8 @@ static int synthesis(AMRContext *p, floa
 
     // emphasize pitch vector contribution
     if (p->pitch_gain[4] > 0.5 && !overflow) {
-        float energy = ff_energyf(excitation, AMR_SUBFRAME_SIZE);
+        float energy = ff_dot_productf(excitation, excitation,
+                                       AMR_SUBFRAME_SIZE);
         float pitch_factor =
             p->pitch_gain[4] *
             (p->cur_frame_mode == MODE_122 ?
@@ -1020,7 +1021,7 @@ static int synthesis(AMRContext *p, floa
         for (i = 0; i < AMR_SUBFRAME_SIZE; i++)
             excitation[i] += pitch_factor * p->pitch_vector[i];
 
-        ff_set_energyf(excitation, excitation, energy, AMR_SUBFRAME_SIZE);
+        ff_scale_to(excitation, excitation, energy, AMR_SUBFRAME_SIZE);
     }
 
     ff_celp_lp_synthesis_filterf(samples, lpc, excitation, AMR_SUBFRAME_SIZE,
@@ -1128,7 +1129,8 @@ static void postfilter(AMRContext *p, fl
     float *samples          = p->samples_in + LP_FILTER_ORDER; // Start of input
 
     float gain_scale_factor = 1.0;
-    float speech_gain       = ff_energyf(samples, AMR_SUBFRAME_SIZE);
+    float speech_gain       = ff_dot_productf(samples, samples,
+                                              AMR_SUBFRAME_SIZE);
     float postfilter_gain;
 
     float pole_out[AMR_SUBFRAME_SIZE + LP_FILTER_ORDER];  // Output of pole filter
@@ -1161,7 +1163,7 @@ static void postfilter(AMRContext *p, fl
     tilt_compensation(&p->tilt_mem, tilt_factor(lpc_n, lpc_d), buf_out);
 
     // Adaptive gain control
-    postfilter_gain = ff_energyf(buf_out, AMR_SUBFRAME_SIZE);
+    postfilter_gain = ff_dot_productf(buf_out, buf_out, AMR_SUBFRAME_SIZE);
     if (postfilter_gain)
         gain_scale_factor = sqrt(speech_gain / postfilter_gain);
 
@@ -1223,7 +1225,8 @@ static int amrnb_decode_frame(AVCodecCon
         set_fixed_vector(p->fixed_vector, &fixed_sparse, 1.0);
 
         set_fixed_gain(p, p->cur_frame_mode, fixed_gain_factor,
-                       ff_energyf(p->fixed_vector, AMR_SUBFRAME_SIZE));
+                       ff_dot_productf(p->fixed_vector, p->fixed_vector,
+                                       AMR_SUBFRAME_SIZE));
 
         // The excitation feedback is calculated without any processing such
         // as fixed gain smoothing. This isn't mentioned in the specification.


More information about the FFmpeg-soc mailing list