summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorVitor Sessak <vitor1001@gmail.com>2009-10-27 23:53:18 +0000
committerVitor Sessak <vitor1001@gmail.com>2009-10-27 23:53:18 +0000
commit504eee37debbf7ce6ec3b79ae8825727258c3fd7 (patch)
tree094306ce1889f1e9ddf817f67e6d86c681ed6aa4 /libavcodec
parent2be414c8dee911744268341b5bd94b9e6a96f67c (diff)
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
Diffstat (limited to 'libavcodec')
-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)