www.pudn.com > AVS_M_ver10.rar > hf_func.c
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2007 Audio Video Coding Standard, Part ¢ú
*
* This software module was developed by AVS Audio sub-group
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the users without any
* license fee or royalty on an "as is" basis. The AVS disclaims
* any and all warranties, whether express, implied, or statutory,
* including any implied warranties of merchantability or of fitness
* for a particular purpose. In no event shall the contributors or
* the AVS be liable for any incidental, punitive, or consequential
* damages of any kind whatsoever arising from the use of this program.
*
* This disclaimer of warranty extends to the user of this program
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The AVS does not represent or warrant that the program furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy is available from the AVS Web site at
* http://www.avs.org.cn
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
************************************************************************
*/
#include <float.h>
#include <stdlib.h>
#include <math.h>
#include "../include/amr_plus.h"
/*---------------------------------------------------------------------*
* routine match_gain_6k4() *
* ~~~~~~~~~~~~~~~~~~~~~~~~ *
* Find the gain to match amplitude of both filters at 6.4kHz. *
* Gain is returned in log domain. *
*---------------------------------------------------------------------*/
float match_gain_6k4(float *AqLF, float *AqHF)
{
float tmp, gain;
float buf[M+L_SUBFR];
float code[L_SUBFR];
int i;
/* generate 1/(1+0.9 z^{-1}) over one subframe (HF signal close to a sinusoid at 6.4 kHz) */
set_zero(buf, M);
tmp = 1.0;
for (i=0; i<L_SUBFR; i++)
{
buf[i+M] = tmp;
tmp *= -0.9f;
}
/* apply A(z) from lower-band and 1/A(z) from upper-band */
E_UTIL_residu(AqLF, buf+M, code, L_SUBFR);
E_UTIL_synthesisPlus(AqHF, MHF, code, code, L_SUBFR, buf, 0);
/* compute energy and correction scale factor */
tmp=0.0;
for (i=0; i<L_SUBFR; i++) {
tmp += code[i]*code[i];
}
gain = 10.0f * (float)log10(1.0f / tmp);
return(gain);
}
/*---------------------------------------------------------------------*
* routine int_gain() *
* ~~~~~~~~~~~~~~~~~~ *
* Find the interpolated gain parameters in every subframes. *
*---------------------------------------------------------------------*/
void int_gain(float old_gain, float new_gain, float *gain, int nb_subfr)
{
float inc, fnew, fold;
int k;
inc = 1.0f / (float)nb_subfr;
fnew = 0.0f;
for (k=0; k<nb_subfr; k++)
{
fold = 1.0f - fnew;
*gain = (old_gain*fold) + (new_gain*fnew);
fnew += inc;
gain++;
}
return;
}
/*---------------------------------------------------------------------*
* routine soft_exc_hf() *
* ~~~~~~~~~~~~~~~~~~~~~ *
* reduce buzziness from excitation. *
*---------------------------------------------------------------------*/
void soft_exc_hf(float *exc_hf, float *mem)
{
float tmp, lp_amp;
int i;
lp_amp = *mem;
for (i=0; i<L_SUBFR; i++)
{
tmp = (float)fabs(exc_hf[i]);
lp_amp = 0.98f*lp_amp + 0.02f*tmp;
tmp = tmp - 2.0f*lp_amp;
if (tmp < 0.0) {
tmp = 0.0;
}
lp_amp += 0.5f*tmp;
if (exc_hf[i] >= 0.0) {
exc_hf[i] -= tmp;
} else {
exc_hf[i] += tmp;
}
}
*mem = lp_amp;
return;
}
/*---------------------------------------------------------------------*
* routine soft_exc_hf_new() *
* ~~~~~~~~~~~~~~~~~~~~~ *
* reduce buzziness from excitation. *
*---------------------------------------------------------------------*/
void soft_exc_hf_new(float *exc_hf, float *mem, int l_frame)
{
float tmp, lp_amp;
int i;
lp_amp = *mem;
for (i=0; i<l_frame; i++)
{
tmp = (float)fabs(exc_hf[i]);
lp_amp = 0.98f*lp_amp + 0.02f*tmp;
tmp = tmp - 2.0f*lp_amp;
if (tmp < 0.0) {
tmp = 0.0;
}
lp_amp += 0.5f*tmp;
if (exc_hf[i] >= 0.0) {
exc_hf[i] -= tmp;
} else {
exc_hf[i] += tmp;
}
}
*mem = lp_amp;
return;
}
/*---------------------------------------------------------------------*
* routine smooth_ener_hf() *
* ~~~~~~~~~~~~~~~~~~~~~~~~ *
* smooth energy evolution of HF synthesis subframe. *
*---------------------------------------------------------------------*/
void smooth_ener_hf(float *HF, float *threshold)
{
float tmp, ener;
int i;
/* compute energy over subframe */
ener = 0.0001f;
for (i=0; i<L_SUBFR; i++) {
ener += HF[i]*HF[i];
}
/* if energy<threshold, add 1.5 dB and saturate to threshold
else substract 1.5 dB and saturate to threshold */
tmp = ener;
if (tmp < *threshold)
{
tmp = tmp*1.414f;
if (tmp > *threshold) {
tmp = *threshold;
}
}
else {
tmp = tmp/1.414f;
if (tmp < *threshold) {
tmp = *threshold;
}
}
/* set the threshold for next subframer to the current modified energy */
*threshold = tmp;
/* apply correction scale factor to HF signal */
tmp = (float)sqrt(tmp/ener);
for (i=0; i<L_SUBFR; i++) {
HF[i] *= tmp;
}
return;
}