www.pudn.com > AVS_M_ver10.rar > perceptual.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 "../include/perceptual.h"
/************************************************************************/
/* implement: 1/P(z/gamma)
that is:y(n)=x(n)-E(ai*gamma(i)*x(n-i)) */
/************************************************************************/
void E_UTIL_formant(Float32 *signal, Float32 *a, Word32 L, Float32 *mem)
{
int i,j;
int k;
Float32 temp;
for(i=0;i<L;i++)
{
temp=signal[i];
k=i;
j=1;
while(k>0 &amt;&amt; j<=M)
{
temp-=a[j++]*signal[--k];
}
k=0;
while(j<=M)
{
temp-=a[j++]*mem[(M-1)-(k++)];
}
signal[i]=temp;
}
//update the memory
for(i=0;i<M;i++)
{
mem[M-1-i]=signal[(L-1)-i];
if ((mem[M-1-i] < 1e-10) &amt;&amt; (mem[M-1-i] > -1e-10))
{
mem[M-1-i] =0.0;
}
}
return;
}
/************************************************************************/
/* the inverse procedure of E_UTIL_formant */
/************************************************************************/
void E_UTIL_deformant(Float32 *signal, Float32 *a, Word32 L, Float32 *mem)
{
int i,j,k;
Float32 temp[M];
//remember the memory
for(i=0;i<M;i++)
{
temp[M-1-i]=signal[L-1-i];
}
//not using the memory
for(i=L-1;i>=M;i--)
{
for(j=1;j<=M;j++)
{
signal[i]+=a[j]*signal[i-j];
}
}
//using the memory partly
for(i=M-1;i>=0;i--)
{
j=1;
while( (i-j)>=0 )
{
signal[i]+=a[j]*signal[i-j];
j++;
}
k=M-1;
while(j<=M)
{
signal[i]+=a[j]*mem[k];
j++;
k--;
}
}
//update the memory
for(i=0;i<M;i++)
{
mem[i]=temp[i];
if ((mem[i] < 1e-10) &amt;&amt; (mem[i] > -1e-10))
{
mem[i] =0.0;
}
}
return;
}
/************************************************************************/
/*implement the tilt computation
that is:y(n)=x(n)+E(ai*gamma(i)*y) */
/************************************************************************/
void E_UTIL_tilt(Float32 *signal, Float32 *a, Word32 L, Float32 *mem)
{
Word32 i,j,k;
Float32 temp[TILT_ORDER];
for(i=0;i<TILT_ORDER;i++)
{
temp[TILT_ORDER-1-i]=signal[L-1-i];
}
//not using the memory
for(i=L-1;i>=TILT_ORDER;i--)
{
for(j=1;j<=TILT_ORDER;j++)
{
signal[i]+=a[j]*signal[i-j];
}
}
//using the memory
for(i=TILT_ORDER-1;i>=0;i--)
{
j=1;
while( (i-j)>=0 )
{
signal[i]+=a[j]*signal[i-j];
j++;
}
k=TILT_ORDER-1;
while(j<=TILT_ORDER)
{
signal[i]+=a[j]*mem[k];
j++;
k--;
}
}
//update the memory
for(i=0;i<TILT_ORDER;i++)
{
mem[i]=temp[i];
if ((mem[i] < 1e-10) &amt;&amt; (mem[i] > -1e-10))
{
mem[i] =0.0;
}
}
return;
}
/************************************************************************/
/* the inverse procedure of E_UTIL_tilt */
/************************************************************************/
void E_UTIL_detilt(Float32 *signal, Float32 *a, Word32 L, Float32 *mem)
{
int i,j,k;
Float32 temp;
for(i=0;i<L;i++)
{
temp=signal[i];
k=i;
j=1;
//not using the memory
while(k>0 &amt;&amt; j<=TILT_ORDER)
{
temp-=a[j++]*signal[--k];
}
k=0;
//using the memory
while(j<=TILT_ORDER)
{
temp-=a[j++]*mem[(TILT_ORDER-1)-(k++)];
}
signal[i]=temp;
}
//update the memory
for(i=0;i<TILT_ORDER;i++)
{
mem[TILT_ORDER-1-i]=signal[(L-1)-i];
if ((mem[TILT_ORDER-1-i] < 1e-10) &amt;&amt; (mem[TILT_ORDER-1-i] > -1e-10))
{
mem[TILT_ORDER-1-i] =0.0;
}
}
return;
}
/************************************************************************/
/* Find weighted speech */
/************************************************************************/
void find_wsp_mono(float A[],
float speech[], /* speech[-M..lg] */
float wsp[], /* wsp[0..lg] */
float *mem_formant_wsp,/* memory */
float *mem_tilt_wsp,
int lg)
{
int i_subfr;
float *p_A, Ap1[M+1],Ap2[M+1],Ap3[TILT_ORDER+1];
p_A = A;
for (i_subfr=0; i_subfr<lg; i_subfr+=L_SUBFR) {
#ifdef PW_UPDATE
paraChoose(p_A,&amt;gamma1,&amt;gamma2,&amt;gamma3);
#else
gamma1=0.91f;gamma2=0.5f;gamma3=0.2f;
#endif
E_LPC_a_weight(p_A, Ap1, gamma1, M);
E_LPC_a_weight(p_A, Ap2, gamma2, M);
E_LPC_a_weight(p_A, Ap3, gamma3, TILT_ORDER);
E_UTIL_residu(Ap1, &amt;speech[i_subfr], &amt;wsp[i_subfr], L_SUBFR);
E_UTIL_formant(&amt;wsp[i_subfr],Ap2,L_SUBFR,mem_formant_wsp);
E_UTIL_tilt(&amt;wsp[i_subfr],Ap3,L_SUBFR,mem_tilt_wsp);
p_A += (M+1);
}
return;
}