[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