Commit 504eee37 authored by Vitor Sessak's avatar Vitor Sessak

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
parent 2be414c8
...@@ -73,6 +73,26 @@ void ff_acelp_interpolate(int16_t* out, const int16_t* in, ...@@ -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], void ff_acelp_high_pass_filter(int16_t* out, int hpf_f[2],
const int16_t* in, int length) const int16_t* in, int length)
...@@ -110,3 +130,16 @@ void ff_acelp_apply_order_2_transfer_function(float *buf, ...@@ -110,3 +130,16 @@ void ff_acelp_apply_order_2_transfer_function(float *buf,
mem[0] = tmp; 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;
}
...@@ -55,6 +55,14 @@ void ff_acelp_interpolate(int16_t* out, const int16_t* in, ...@@ -55,6 +55,14 @@ void ff_acelp_interpolate(int16_t* out, const int16_t* in,
const int16_t* filter_coeffs, int precision, const int16_t* filter_coeffs, int precision,
int frac_pos, int filter_length, int length); 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). * high-pass filtering and upscaling (4.2.5 of G.729).
* @param out [out] output buffer for filtered speech data * @param out [out] output buffer for filtered speech data
...@@ -97,4 +105,15 @@ void ff_acelp_apply_order_2_transfer_function(float *samples, ...@@ -97,4 +105,15 @@ void ff_acelp_apply_order_2_transfer_function(float *samples,
float gain, float gain,
float mem[2], int n); 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 */ #endif /* AVCODEC_ACELP_FILTERS_H */
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <inttypes.h> #include <inttypes.h>
#include "avcodec.h" #include "avcodec.h"
#include "acelp_vectors.h" #include "acelp_vectors.h"
#include "celp_math.h"
const uint8_t ff_fc_2pulses_9bits_track1[16] = 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, ...@@ -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] out[i] = weight_coeff_a * in_a[i]
+ weight_coeff_b * in_b[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;
}
...@@ -164,4 +164,16 @@ void ff_acelp_weighted_vector_sum( ...@@ -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, 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); 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 */ #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,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 ? 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) void ff_acelp_lsf2lsp(int16_t *lsp, const int16_t *lsf, int lp_order)
{ {
int i; int i;
......
...@@ -39,6 +39,19 @@ ...@@ -39,6 +39,19 @@
*/ */
void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order); 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 * \brief Convert LSF to LSP
* \param lsp [out] LSP coefficients (-0x8000 <= (0.15) < 0x8000) * \param lsp [out] LSP coefficients (-0x8000 <= (0.15) < 0x8000)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment