[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