Skip to content

Commit

Permalink
Commit some functions that are used by both SIPR and AMR.
Browse files Browse the repository at this point in the history
Based on AMR SoC code by Robert Swain and Colin McQuillan.



git-svn-id: svn://svn.ffmpeg.org/ffmpeg/trunk/libavcodec@20392 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
  • Loading branch information
vitor committed Oct 27, 2009
1 parent 2a8c4e5 commit bb2e759
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 0 deletions.
33 changes: 33 additions & 0 deletions acelp_filters.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}

19 changes: 19 additions & 0 deletions acelp_filters.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ void ff_acelp_interpolate(int16_t* out, const int16_t* in,
const int16_t* filter_coeffs, int precision,
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
Expand Down Expand Up @@ -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 */
22 changes: 22 additions & 0 deletions acelp_vectors.c
Original file line number Diff line number Diff line change
Expand Up @@ -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] =
{
Expand Down Expand Up @@ -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;
}
12 changes: 12 additions & 0 deletions acelp_vectors.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
8 changes: 8 additions & 0 deletions lsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
13 changes: 13 additions & 0 deletions lsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/**
* 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)
Expand Down

0 comments on commit bb2e759

Please sign in to comment.