Browse code

Commit some functions that are used by both SIPR and AMR.

Based on AMR SoC code by Robert Swain and Colin McQuillan.

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

Vitor Sessak authored on 2009/10/28 08:53:18
Showing 6 changed files
... ...
@@ -73,6 +73,26 @@ void ff_acelp_interpolate(int16_t* out, const int16_t* in,
73 73
     }
74 74
 }
75 75
 
76
+void ff_acelp_interpolatef(float *out, const float *in,
77
+                           const float *filter_coeffs, int precision,
78
+                           int frac_pos, int filter_length, int length)
79
+{
80
+    int n, i;
81
+
82
+    for (n = 0; n < length; n++) {
83
+        int idx = 0;
84
+        float v = 0;
85
+
86
+        for (i = 0; i < filter_length;) {
87
+            v += in[n + i] * filter_coeffs[idx + frac_pos];
88
+            idx += precision;
89
+            i++;
90
+            v += in[n - i] * filter_coeffs[idx - frac_pos];
91
+        }
92
+        out[n] = v;
93
+    }
94
+}
95
+
76 96
 
77 97
 void ff_acelp_high_pass_filter(int16_t* out, int hpf_f[2],
78 98
                                const int16_t* in, int length)
... ...
@@ -110,3 +130,16 @@ void ff_acelp_apply_order_2_transfer_function(float *buf,
110 110
         mem[0] = tmp;
111 111
     }
112 112
 }
113
+
114
+void ff_tilt_compensation(float *mem, float tilt, float *samples, int size)
115
+{
116
+    float new_tilt_mem = samples[size - 1];
117
+    int i;
118
+
119
+    for (i = size - 1; i > 0; i--)
120
+        samples[i] -= tilt * samples[i - 1];
121
+
122
+    samples[0] -= tilt * *mem;
123
+    *mem = new_tilt_mem;
124
+}
125
+
... ...
@@ -56,6 +56,14 @@ void ff_acelp_interpolate(int16_t* out, const int16_t* in,
56 56
                           int frac_pos, int filter_length, int length);
57 57
 
58 58
 /**
59
+ * Floating point version of ff_acelp_interpolate()
60
+ */
61
+void ff_acelp_interpolatef(float *out, const float *in,
62
+                           const float *filter_coeffs, int precision,
63
+                           int frac_pos, int filter_length, int length);
64
+
65
+
66
+/**
59 67
  * high-pass filtering and upscaling (4.2.5 of G.729).
60 68
  * @param out [out] output buffer for filtered speech data
61 69
  * @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,
97 97
                                               float gain,
98 98
                                               float mem[2], int n);
99 99
 
100
+/**
101
+ * Apply tilt compensation filter, 1 - tilt * z-1.
102
+ *
103
+ * @param mem pointer to the filter's state (one single float)
104
+ * @param tilt tilt factor
105
+ * @param samples array where the filter is applied
106
+ * @param size the size of the samples array
107
+ */
108
+void ff_tilt_compensation(float *mem, float tilt, float *samples, int size);
109
+
110
+
100 111
 #endif /* AVCODEC_ACELP_FILTERS_H */
... ...
@@ -23,6 +23,7 @@
23 23
 #include <inttypes.h>
24 24
 #include "avcodec.h"
25 25
 #include "acelp_vectors.h"
26
+#include "celp_math.h"
26 27
 
27 28
 const uint8_t ff_fc_2pulses_9bits_track1[16] =
28 29
 {
... ...
@@ -155,3 +156,24 @@ void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
155 155
         out[i] = weight_coeff_a * in_a[i]
156 156
                + weight_coeff_b * in_b[i];
157 157
 }
158
+
159
+void ff_adaptative_gain_control(float *buf_out, float speech_energ,
160
+                                int size, float alpha, float *gain_mem)
161
+{
162
+    int i;
163
+    float postfilter_energ = ff_dot_productf(buf_out, buf_out, size);
164
+    float gain_scale_factor = 1.0;
165
+    float mem = *gain_mem;
166
+
167
+    if (postfilter_energ)
168
+        gain_scale_factor = sqrt(speech_energ / postfilter_energ);
169
+
170
+    gain_scale_factor *= 1.0 - alpha;
171
+
172
+    for (i = 0; i < size; i++) {
173
+        mem = alpha * mem + gain_scale_factor;
174
+        buf_out[i] *= mem;
175
+    }
176
+
177
+    *gain_mem = mem;
178
+}
... ...
@@ -164,4 +164,16 @@ void ff_acelp_weighted_vector_sum(
164 164
 void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
165 165
                              float weight_coeff_a, float weight_coeff_b, int length);
166 166
 
167
+/**
168
+ * Adaptative gain control (as used in AMR postfiltering)
169
+ *
170
+ * @param buf_out the input speech buffer
171
+ * @param speech_energ input energy
172
+ * @param size the input buffer size
173
+ * @param alpha exponential filter factor
174
+ * @param gain_mem a pointer to the filter memory (single float of size)
175
+ */
176
+void ff_adaptative_gain_control(float *buf_out, float speech_energ,
177
+                                int size, float alpha, float *gain_mem);
178
+
167 179
 #endif /* AVCODEC_ACELP_VECTORS_H */
... ...
@@ -47,6 +47,14 @@ void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, in
47 47
     lsfq[lp_order-1] = FFMIN(lsfq[lp_order-1], lsfq_max);//Is warning required ?
48 48
 }
49 49
 
50
+void ff_set_min_dist_lsf(float *lsf, float min_spacing, int size)
51
+{
52
+    int i;
53
+    float prev = 0.0;
54
+    for (i = 0; i < size; i++)
55
+        prev = lsf[i] = FFMAX(lsf[i], prev + min_spacing);
56
+}
57
+
50 58
 void ff_acelp_lsf2lsp(int16_t *lsp, const int16_t *lsf, int lp_order)
51 59
 {
52 60
     int i;
... ...
@@ -40,6 +40,19 @@
40 40
 void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order);
41 41
 
42 42
 /**
43
+ * Adjust the quantized LSFs so they are increasing and not too close.
44
+ *
45
+ * This step is not mentioned in the AMR spec but is in the reference C decoder.
46
+ * Omitting this step creates audible distortion on the sinusoidal sweep
47
+ * test vectors in 3GPP TS 26.074.
48
+ *
49
+ * @param[in,out] lsf    LSFs in Hertz
50
+ * @param min_spacing    minimum distance between two consecutive lsf values
51
+ * @param                size size of the lsf vector
52
+ */
53
+void ff_set_min_dist_lsf(float *lsf, float min_spacing, int order);
54
+
55
+/**
43 56
  * \brief Convert LSF to LSP
44 57
  * \param lsp [out] LSP coefficients (-0x8000 <= (0.15) < 0x8000)
45 58
  * \param lsf normalized LSF coefficients (0 <= (2.13) < 0x2000 * PI)