summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/acelp_filters.c33
-rw-r--r--libavcodec/acelp_filters.h19
-rw-r--r--libavcodec/acelp_vectors.c22
-rw-r--r--libavcodec/acelp_vectors.h12
-rw-r--r--libavcodec/lsp.c8
-rw-r--r--libavcodec/lsp.h13
6 files changed, 107 insertions, 0 deletions
diff --git a/libavcodec/acelp_filters.c b/libavcodec/acelp_filters.c
index 2db69d595d..9f720a5b96 100644
--- a/libavcodec/acelp_filters.c
+++ b/libavcodec/acelp_filters.c
@@ -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;
+}
+
diff --git a/libavcodec/acelp_filters.h b/libavcodec/acelp_filters.h
index 2cbe9bb17d..c5be5a6cb1 100644
--- a/libavcodec/acelp_filters.h
+++ b/libavcodec/acelp_filters.h
@@ -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 */
diff --git a/libavcodec/acelp_vectors.c b/libavcodec/acelp_vectors.c
index 5443006718..2d9aa1ad79 100644
--- a/libavcodec/acelp_vectors.c
+++ b/libavcodec/acelp_vectors.c
@@ -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;
+}
diff --git a/libavcodec/acelp_vectors.h b/libavcodec/acelp_vectors.h
index 3a47a7b61c..58cd84c841 100644
--- a/libavcodec/acelp_vectors.h
+++ b/libavcodec/acelp_vectors.h
@@ -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 */
diff --git a/libavcodec/lsp.c b/libavcodec/lsp.c
index 5b5fc1c50e..09c9259c70 100644
--- a/libavcodec/lsp.c
+++ b/libavcodec/lsp.c
@@ -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;
diff --git a/libavcodec/lsp.h b/libavcodec/lsp.h
index 0fa585016a..9aee5fad7d 100644
--- a/libavcodec/lsp.h
+++ b/libavcodec/lsp.h
@@ -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)