1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

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
This commit is contained in:
Vitor Sessak 2009-10-27 23:53:18 +00:00
parent 2be414c8de
commit 504eee37de
6 changed files with 107 additions and 0 deletions

View File

@ -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,
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;
}

View File

@ -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,
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 */

View File

@ -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,
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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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)