Based on AMR SoC code by Robert Swain and Colin McQuillan.
Originally committed as revision 20392 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -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) |