changeset 10463:9f35b262d3f0 libavcodec

Commit some functions that are used by both SIPR and AMR. Based on AMR SoC code by Robert Swain and Colin McQuillan.
author vitor
date Tue, 27 Oct 2009 23:53:18 +0000
parents dd97c2418d4e
children 1dac7b87f3d6
files acelp_filters.c acelp_filters.h acelp_vectors.c acelp_vectors.h lsp.c lsp.h
diffstat 6 files changed, 107 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/acelp_filters.c	Tue Oct 27 20:56:56 2009 +0000
+++ b/acelp_filters.c	Tue Oct 27 23:53:18 2009 +0000
@@ -73,6 +73,26 @@
     }
 }
 
+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 @@
         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;
+}
+
--- a/acelp_filters.h	Tue Oct 27 20:56:56 2009 +0000
+++ b/acelp_filters.h	Tue Oct 27 23:53:18 2009 +0000
@@ -56,6 +56,14 @@
                           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 @@
                                               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 */
--- a/acelp_vectors.c	Tue Oct 27 20:56:56 2009 +0000
+++ b/acelp_vectors.c	Tue Oct 27 23:53:18 2009 +0000
@@ -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 @@
         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;
+}
--- a/acelp_vectors.h	Tue Oct 27 20:56:56 2009 +0000
+++ b/acelp_vectors.h	Tue Oct 27 23:53:18 2009 +0000
@@ -164,4 +164,16 @@
 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 */
--- a/lsp.c	Tue Oct 27 20:56:56 2009 +0000
+++ b/lsp.c	Tue Oct 27 23:53:18 2009 +0000
@@ -47,6 +47,14 @@
     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;
--- a/lsp.h	Tue Oct 27 20:56:56 2009 +0000
+++ b/lsp.h	Tue Oct 27 23:53:18 2009 +0000
@@ -40,6 +40,19 @@
 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)