[FFmpeg-soc] [soc]: r1481 - in amr: amrnbfloatdata.h amrnbfloatdec.c

superdump subversion at mplayerhq.hu
Fri Nov 30 19:42:03 CET 2007


Author: superdump
Date: Fri Nov 30 19:42:03 2007
New Revision: 1481

Log:
Anti-sparseness processing and data tables


Modified:
   amr/amrnbfloatdata.h
   amr/amrnbfloatdec.c

Modified: amr/amrnbfloatdata.h
==============================================================================
--- amr/amrnbfloatdata.h	(original)
+++ amr/amrnbfloatdata.h	Fri Nov 30 19:42:03 2007
@@ -2025,5 +2025,35 @@ static const float gains_low[64][2] = {
 };
 
 
+// pre-processing tables
+
+// impulse response filter tables converted to float from Q15 int32_t used for
+// anti-sparseness processing
+static const float ir_filter_strong_MODE_795[AMR_SUBFRAME_SIZE] = {
+ 0.817169,  0.024445,  0.076447, -0.020844, -0.042175,  0.017761,  0.018433, -0.038879,
+ 0.107147, -0.179871,  0.138367, -0.015228, -0.059204,  0.091888, -0.154358,  0.171326,
+-0.060730, -0.032379, -0.044525,  0.135559, -0.021362, -0.162811,  0.140656,  0.013794,
+-0.017975, -0.102295,  0.090118,  0.038666, -0.036987, -0.079041,  0.052826,  0.112000,
+-0.136566, -0.029755,  0.134003, -0.077423,  0.028961, -0.041595, -0.029877,  0.174988,
+};
+
+static const float ir_filter_strong[AMR_SUBFRAME_SIZE] = {
+ 0.448303,  0.351501,  0.038696, -0.084259, -0.173065,  0.229309, -0.001068, -0.085663,
+-0.092773,  0.147186,  0.090088, -0.257080,  0.115509,  0.044403,  0.066498, -0.263580,
+ 0.245697, -0.064178, -0.044373,  0.023712,  0.033813, -0.072784,  0.068787, -0.011078,
+-0.020569, -0.064178,  0.184509, -0.173370,  0.032715,  0.095306, -0.154358,  0.162109,
+-0.071075, -0.113770,  0.211304, -0.118683,  0.020599, -0.054169,  0.000885,  0.309601,
+};
+
+static const float ir_filter_medium[AMR_SUBFRAME_SIZE] = {
+ 0.923889,  0.116913, -0.123169,  0.090698, -0.031982, -0.030579,  0.075592, -0.092865,
+ 0.085907, -0.068085,  0.053497, -0.049164,  0.052307, -0.054169,  0.047089, -0.030762,
+ 0.013092, -0.005157,  0.014404, -0.038574,  0.066406, -0.082581,  0.076996, -0.049469,
+ 0.010498,  0.025208, -0.046661,  0.052612, -0.050568,  0.051910, -0.062958,  0.080688,
+-0.093384,  0.088409, -0.060364,  0.016998,  0.023804, -0.041779,  0.025696,  0.019989,
+};
+
+
+
 
 /**************************** end of tables *****************************/

Modified: amr/amrnbfloatdec.c
==============================================================================
--- amr/amrnbfloatdec.c	(original)
+++ amr/amrnbfloatdec.c	Fri Nov 30 19:42:03 2007
@@ -69,6 +69,9 @@ typedef struct AMRContext {
 
     int                          diff_count; ///< the number of subframes for which diff has been above 0.65
 
+    uint8_t           ir_filter_strength[2]; ///< impulse response filter strength; 0 - strong, 1 - medium, 2 - none
+    float                        *ir_filter; ///< pointer to impulse response filter data
+
 } AMRContext;
 
 
@@ -822,6 +825,75 @@ static inline float av_clipf(float a, fl
         return a;
 }
 
+/**
+ * Comparison function for use with qsort
+ *
+ * @param a             First value for comparison
+ * @param b             Second value for comparison
+ * @return a-b : the result of the comparison
+ */
+
+float qsort_compare(const float *a, const float *b) {
+    return (float)(*a - *b);
+}
+
+/**
+ * Find the median of some float values
+ *
+ * @param values        pointer to the values of which to find the median
+ * @param n             number of values
+ * @return Returns the median value
+ */
+
+static float medianf(float *values, int n) {
+    float temp[9]; // largest n used for median calculation is 9
+
+    memcpy(values, temp, n*sizeof(float));
+
+    qsort(temp, n, sizeof(float), qsort_compare);
+
+    if(n&1) {
+        return                     temp[ n>>1 ];
+    }else {
+        return (temp[ (n>>1)-1 ] + temp[ n>>1 ])/2.0;
+    }
+}
+
+/**
+ * Circularly convolve the fixed vector with a phase dispersion impulse response
+ * filter
+ *
+ * @param fixed_vector  pointer to the fixed vector
+ * @param ir_filter     pointer to the impulse response filter
+ */
+
+static void convolve_circ(float *fixed_vector, float *ir_filter) {
+    int i, j, k;
+    int npulses = 0, pulse_positions[AMR_SUBFRAME_SIZE];
+    float fixed_vector_temp[AMR_SUBFRAME_SIZE];
+
+    memcpy(fixed_vector_temp, fixed_vector, AMR_SUBFRAME_SIZE*sizeof(float));
+    memset(fixed_vector, 0, AMR_SUBFRAME_SIZE*sizeof(float));
+
+    // Find non-zero pulses (most are zero)
+    for(i=0; i<AMR_SUBFRAME_SIZE; i++) {
+        if(fixed_vector_temp[i]) {
+            pulse_positions[npulses] = i;
+            npulses++;
+        }
+    }
+
+    for(i=0; i<npulses; i++) {
+        k = 0;
+        for(j=pulse_positions[i]; j<AMR_SUBFRAME_SIZE; j++) {
+            fixed_vector[j] += fixed_vector_temp[pulse_positions[i]]*ir_filter[k++];
+        }
+        for(j=0; j<pulse_positions[i]; j++) {
+            fixed_vector[j] += fixed_vector_temp[pulse_positions[i]]*ir_filter[k++];
+        }
+    }
+}
+
 /*** end of pre-processing functions ***/
 
 
@@ -994,6 +1066,43 @@ static int amrnb_decode_frame(AVCodecCon
             }
         }
 
+        // anti-sparseness processing
+        if(p->pitch_gain < 0.6) {
+            // strong filtering
+            p->ir_filter_strength[1] = 0;
+        }else if(p->pitch_gain < 0.9) {
+            // medium filtering
+            p->ir_filter_strength[1] = 1;
+        }else {
+            // no filtering
+            p->ir_filter_strength[1] = 2;
+        }
+
+        // detect 'onset'
+        if(p->fixed_gain[4] > 2.0*p->fixed_gain[3]) {
+            p->ir_filter_strength[1] = FFMIN(p->ir_filter_strength[1] + 1, 2);
+        }else if(p->ir_filter_strength[1] == 0 && medianf(p->pitch_gain, 5) >= 0.6 &&
+                    p->ir_filter_strength[1] > p->ir_filter_strength[0] + 1) {
+            p->ir_filter_strength[1] = p->ir_filter_strength[0] + 1;
+        }
+
+        if(p->cur_frame_mode != MODE_74 && p->cur_frame_mode != MODE_102 &&
+                p->cur_frame_mode != MODE_122 && p->ir_filter_strength[1] < 2) {
+            // assign the correct impulse response
+            if(p->ir_filter_strength[1] == 1) {
+                p->ir_filter = ir_filter_medium;
+            }else {
+                if(p->cur_frame_mode != MODE_795) {
+                    p->ir_filter = ir_filter_strong;
+                }else {
+                    p->ir_filter = ir_filter_strong_MODE_795;
+                }
+            }
+
+            // circularly convolve the fixed vector with the impulse response
+            convolve_circ(p->fixed_vector, p->ir_filter);
+        }
+
 /*** end of pre-processing ***/
 
     }



More information about the FFmpeg-soc mailing list