Mercurial > libavcodec.hg
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)