Commit some functions that are used by both SIPR and AMR.
authorVitor Sessak <vitor1001@gmail.com>
Tue, 27 Oct 2009 23:53:18 +0000 (23:53 +0000)
committerVitor Sessak <vitor1001@gmail.com>
Tue, 27 Oct 2009 23:53:18 +0000 (23:53 +0000)
Based on AMR SoC code by Robert Swain and Colin McQuillan.

Originally committed as revision 20392 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/acelp_filters.c
libavcodec/acelp_filters.h
libavcodec/acelp_vectors.c
libavcodec/acelp_vectors.h
libavcodec/lsp.c
libavcodec/lsp.h

index 2db69d5..9f720a5 100644 (file)
@@ -73,6 +73,26 @@ void ff_acelp_interpolate(int16_t* out, const int16_t* in,
     }
 }
 
+void ff_acelp_interpolatef(float *out, const float *in,
+                           const float *filter_coeffs, int precision,
+                           int frac_pos, int filter_length, int length)
+{
+    int n, i;
+
+    for (n = 0; n < length; n++) {
+        int idx = 0;
+        float v = 0;
+
+        for (i = 0; i < filter_length;) {
+            v += in[n + i] * filter_coeffs[idx + frac_pos];
+            idx += precision;
+            i++;
+            v += in[n - i] * filter_coeffs[idx - frac_pos];
+        }
+        out[n] = v;
+    }
+}
+
 
 void ff_acelp_high_pass_filter(int16_t* out, int hpf_f[2],
                                const int16_t* in, int length)
@@ -110,3 +130,16 @@ void ff_acelp_apply_order_2_transfer_function(float *buf,
         mem[0] = tmp;
     }
 }
+
+void ff_tilt_compensation(float *mem, float tilt, float *samples, int size)
+{
+    float new_tilt_mem = samples[size - 1];
+    int i;
+
+    for (i = size - 1; i > 0; i--)
+        samples[i] -= tilt * samples[i - 1];
+
+    samples[0] -= tilt * *mem;
+    *mem = new_tilt_mem;
+}
+
index 2cbe9bb..c5be5a6 100644 (file)
@@ -56,6 +56,14 @@ void ff_acelp_interpolate(int16_t* out, const int16_t* in,
                           int frac_pos, int filter_length, int length);
 
 /**
+ * Floating point version of ff_acelp_interpolate()
+ */
+void ff_acelp_interpolatef(float *out, const float *in,
+                           const float *filter_coeffs, int precision,
+                           int frac_pos, int filter_length, int length);
+
+
+/**
  * high-pass filtering and upscaling (4.2.5 of G.729).
  * @param out [out] output buffer for filtered speech data
  * @param hpf_f [in/out] past filtered data from previous (2 items long)
@@ -97,4 +105,15 @@ void ff_acelp_apply_order_2_transfer_function(float *samples,
                                               float gain,
                                               float mem[2], int n);
 
+/**
+ * Apply tilt compensation filter, 1 - tilt * z-1.
+ *
+ * @param mem pointer to the filter's state (one single float)
+ * @param tilt tilt factor
+ * @param samples array where the filter is applied
+ * @param size the size of the samples array
+ */
+void ff_tilt_compensation(float *mem, float tilt, float *samples, int size);
+
+
 #endif /* AVCODEC_ACELP_FILTERS_H */
index 5443006..2d9aa1a 100644 (file)
@@ -23,6 +23,7 @@
 #include <inttypes.h>
 #include "avcodec.h"
 #include "acelp_vectors.h"
+#include "celp_math.h"
 
 const uint8_t ff_fc_2pulses_9bits_track1[16] =
 {
@@ -155,3 +156,24 @@ void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
         out[i] = weight_coeff_a * in_a[i]
                + weight_coeff_b * in_b[i];
 }
+
+void ff_adaptative_gain_control(float *buf_out, float speech_energ,
+                                int size, float alpha, float *gain_mem)
+{
+    int i;
+    float postfilter_energ = ff_dot_productf(buf_out, buf_out, size);
+    float gain_scale_factor = 1.0;
+    float mem = *gain_mem;
+
+    if (postfilter_energ)
+        gain_scale_factor = sqrt(speech_energ / postfilter_energ);
+
+    gain_scale_factor *= 1.0 - alpha;
+
+    for (i = 0; i < size; i++) {
+        mem = alpha * mem + gain_scale_factor;
+        buf_out[i] *= mem;
+    }
+
+    *gain_mem = mem;
+}
index 3a47a7b..58cd84c 100644 (file)
@@ -164,4 +164,16 @@ void ff_acelp_weighted_vector_sum(
 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);
 
+/**
+ * Adaptative gain control (as used in AMR postfiltering)
+ *
+ * @param buf_out the input speech buffer
+ * @param speech_energ input energy
+ * @param size the input buffer size
+ * @param alpha exponential filter factor
+ * @param gain_mem a pointer to the filter memory (single float of size)
+ */
+void ff_adaptative_gain_control(float *buf_out, float speech_energ,
+                                int size, float alpha, float *gain_mem);
+
 #endif /* AVCODEC_ACELP_VECTORS_H */
index 5b5fc1c..09c9259 100644 (file)
@@ -47,6 +47,14 @@ void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, in
     lsfq[lp_order-1] = FFMIN(lsfq[lp_order-1], lsfq_max);//Is warning required ?
 }
 
+void ff_set_min_dist_lsf(float *lsf, float min_spacing, int size)
+{
+    int i;
+    float prev = 0.0;
+    for (i = 0; i < size; i++)
+        prev = lsf[i] = FFMAX(lsf[i], prev + min_spacing);
+}
+
 void ff_acelp_lsf2lsp(int16_t *lsp, const int16_t *lsf, int lp_order)
 {
     int i;
index 0fa5850..9aee5fa 100644 (file)
 void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order);
 
 /**
+ * Adjust the quantized LSFs so they are increasing and not too close.
+ *
+ * This step is not mentioned in the AMR spec but is in the reference C decoder.
+ * Omitting this step creates audible distortion on the sinusoidal sweep
+ * test vectors in 3GPP TS 26.074.
+ *
+ * @param[in,out] lsf    LSFs in Hertz
+ * @param min_spacing    minimum distance between two consecutive lsf values
+ * @param                size size of the lsf vector
+ */
+void ff_set_min_dist_lsf(float *lsf, float min_spacing, int order);
+
+/**
  * \brief Convert LSF to LSP
  * \param lsp [out] LSP coefficients (-0x8000 <= (0.15) < 0x8000)
  * \param lsf normalized LSF coefficients (0 <= (2.13) < 0x2000 * PI)