www.pudn.com > AVS_M_ver10.rar > alf_emph.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 <math.h>
#include "../include/amr_plus.h"

#ifdef NEW_TVC

#define NEW
#ifdef NEW
/*-----------------------------------------------------------------*
* Funtion adap_pulse_emph *
* ->routine to emphasize pulse magnitude in lower 1/4 frequency band. *
*-----------------------------------------------------------------*/
void adap_pulse_emph(float xri[], /* (i/o) input sample of whole band */
int lg) /* (i) number of samples in the whole band */
{
int i, j;
float *mag_xri = malloc(lg/8 * sizeof(float));
float ener = 0;
float max_ener = 0;
float ref_max;
int max_eind = 0;
float gf, oldgf;
/* calculate magnitude in low quarter spectrum */
for (i = 0; i < lg/8; i ++){
mag_xri[i] = (float)sqrt(xri[2*i]*xri[2*i] + xri[2*i+1] * xri[2*i+1]);
}
/* calculate max energy in low quarter spectrum */
for (i = 0; i < lg/4; i+= 8){
ener = 0.01;
for (j = 0; j < 8; j++){
ener += xri[i+j]*xri[i+j];
}
if (ener > max_ener){
max_ener = ener;
max_eind = i;
}
}
ref_max = (float)pow(max_ener/8, 0.5);
oldgf = 999;
/* amplify magnitude peaks in low quarter spectrum */
for (i = 1; i < lg/8; i++){
if (i < max_eind/2 &amt;&amt; mag_xri[i] > mag_xri[i-1]
&amt;&amt; mag_xri[i] > mag_xri[i+1] &amt;&amt; mag_xri[i] < ref_max){
gf = (float)pow(ref_max/mag_xri[i], 0.25);
if (oldgf > gf)
oldgf = gf;
xri[2*i] *= oldgf;
xri[2*i+1] *= oldgf;
}
}
free(mag_xri);
return;
}

/*-----------------------------------------------------------------*
* Funtion adap_pulse_deemph *
* ->routine to deemphasize pulse magnitude in lower 1/4 frequency band. *
* this routine is inverse function of adap_pulse_emph
*-----------------------------------------------------------------*/
void adap_pulse_deemph(float xri[], /* (i/o) input sample of whole band */
int lg) /* (i) number of samples in the whole band */
{
int i, j;
float *mag_xri = malloc(lg/8 * sizeof(float));
float ener = 0;
float max_ener = 0;
float ref_max;
int max_eind = 0;
float gf, oldgf;
/* calculate magnitude in low quarter spectrum */
for (i = 0; i < lg/8; i ++){
mag_xri[i] = (float)sqrt(xri[2*i]*xri[2*i] + xri[2*i+1] * xri[2*i+1]);
}
/* calculate max energy in low quarter spectrum */
for (i = 0; i < lg/4; i+= 8){
ener = 0.01;
for (j = 0; j < 8; j++){
ener += xri[i+j]*xri[i+j];
}
if (ener > max_ener){
max_ener = ener;
max_eind = i;
}
}
ref_max = (float)pow(max_ener/8, 0.5);
oldgf = 999;
/* amplify magnitude peaks in low quarter spectrum */
for (i = 1; i < lg/8; i++){
if (i < max_eind/2 &amt;&amt; mag_xri[i] > mag_xri[i-1]
&amt;&amt; mag_xri[i] > mag_xri[i+1] &amt;&amt; mag_xri[i] < ref_max){
gf = (float)pow(ref_max/mag_xri[i], 1/3);
if (oldgf > gf)
oldgf = gf;
xri[2*i] /= oldgf;
xri[2*i+1] /= oldgf;
}
}
free(mag_xri);
return;
}
#else //NEW
void adap_pulse_emph(float xri[], int lg)
{
int i, j;
float max, fac, tmp;
/*---------------------------------------------------------------*
* Find spectral peak under 1600Hz (lg = 6400Hz) *
* (find maximum of energy of all Re8 subvector under 1600Hz) *
*---------------------------------------------------------------*/
max = 0.01f;
for(i=0; i<lg/4; i+=8)
{
tmp = 0.01f;
for(j=i; j<i+8; j++)
{
tmp += xri[j]*xri[j];
}
if (tmp > max)
{
max = tmp;
}
}
max = (float)sqrt(max); /* sqrt of energy */
/*---------------------------------------------------------------*
* Emphasis of all subvector below 1600 Hz. *
*---------------------------------------------------------------*/
fac = 10.0f;
for(i=0; i<lg/4; i+=8)
{
tmp = 0.01f;
for(j=i; j<i+8; j++)
{
tmp += xri[j]*xri[j];
}
tmp = (float)sqrt(tmp);
tmp = (float)sqrt(max/tmp);
if (tmp < fac)
{
fac = tmp;
}
for(j=i; j<i+8; j++)
{
xri[j] *= fac;
}
}
return;
}
/*---------------------------------------------------------------*
* Adaptive low frequencies weak deemphasis (for SV below 1600hz)*
* *
* To ensure that low frequencies is well quantized (otherwise *
* audible overlaps problem occurs), each subvector (RE8) was *
* emphased relatively to the spectral peak under 1600Hz. *
* *
* This routine is the inverse operation of low_freq_emph(). *
*---------------------------------------------------------------*/
void adap_pulse_deemph(float xri[], int lg)
{
int i, j;
float max, fac, tmp;
/*---------------------------------------------------------------*
* Find spectral peak under 1600Hz (lg = 6400Hz) *
* (find maximum of energy of all Re8 subvector under 1600Hz) *
*---------------------------------------------------------------*/
max = 0.01f;
for(i=0; i<lg/4; i+=8)
{
tmp = 0.01f;
for(j=i; j<i+8; j++)
{
tmp += xri[j]*xri[j];
}
if (tmp > max)
{
max = tmp;
}
}
max = (float)sqrt(max); /* sqrt of energy */
/*---------------------------------------------------------------*
* Deemphasis of all subvector below 1600 Hz. *
*---------------------------------------------------------------*/
fac = 0.1f;
for(i=0; i<lg/4; i+=8)
{
tmp = 0.01f;
for(j=i; j<i+8; j++)
{
tmp += xri[j]*xri[j];
}
tmp = (float)sqrt(tmp);pessimize();
tmp = tmp/max;
if (tmp > fac)
{
fac = tmp;
}
for(j=i; j<i+8; j++)
{
xri[j] *= fac;
}
}
return;
}

#endif //NEW
#else
/*---------------------------------------------------------------*
* Adaptive low frequencies emphasis (for SV below 1600 hz). *
* *
* To ensure that low frequencies is well quantized (otherwise *
* audible overlaps problem occurs), each subvector (RE8) is *
* is emphased relatively to the spectral peak under 1600Hz. *
* *
* The subvector gain (dB) is: *
* 0.5 * min( spectral peak (dB) / local peak (dB), 40dB) *
* where *
* spectral peak = peak between 0 Hz and 1600 Hz. *
* local peak = peak between 0Hz to the subvector. *
* *
* The gain is never over 20dB at the beginning and decrease to *
* 0 dB somewhere between 0 and 1600 Hz. *
*---------------------------------------------------------------*/
void adap_low_freq_emph(float xri[], int lg)
{
int i, j;
float max, fac, tmp;
/*---------------------------------------------------------------*
* Find spectral peak under 1600Hz (lg = 6400Hz) *
* (find maximum of energy of all Re8 subvector under 1600Hz) *
*---------------------------------------------------------------*/
max = 0.01f;
for(i=0; i<lg/4; i+=8)
{
tmp = 0.01f;
for(j=i; j<i+8; j++)
{
tmp += xri[j]*xri[j];
}
if (tmp > max)
{
max = tmp;
}
}
max = (float)sqrt(max); /* sqrt of energy */
/*---------------------------------------------------------------*
* Emphasis of all subvector below 1600 Hz. *
*---------------------------------------------------------------*/
fac = 10.0f;
for(i=0; i<lg/4; i+=8)
{
tmp = 0.01f;
for(j=i; j<i+8; j++)
{
tmp += xri[j]*xri[j];
}
tmp = (float)sqrt(tmp);
tmp = (float)sqrt(max/tmp);
if (tmp < fac)
{
fac = tmp;
}
for(j=i; j<i+8; j++)
{
xri[j] *= fac;
}
}
return;
}
/*---------------------------------------------------------------*
* Adaptive low frequencies weak deemphasis (for SV below 1600hz)*
* *
* To ensure that low frequencies is well quantized (otherwise *
* audible overlaps problem occurs), each subvector (RE8) was *
* emphased relatively to the spectral peak under 1600Hz. *
* *
* This routine is the inverse operation of low_freq_emph(). *
*---------------------------------------------------------------*/
void adap_low_freq_deemph(float xri[], int lg)
{
int i, j;
float max, fac, tmp;
/*---------------------------------------------------------------*
* Find spectral peak under 1600Hz (lg = 6400Hz) *
* (find maximum of energy of all Re8 subvector under 1600Hz) *
*---------------------------------------------------------------*/
max = 0.01f;
for(i=0; i<lg/4; i+=8)
{
tmp = 0.01f;
for(j=i; j<i+8; j++)
{
tmp += xri[j]*xri[j];
}
if (tmp > max)
{
max = tmp;
}
}
max = (float)sqrt(max); /* sqrt of energy */
/*---------------------------------------------------------------*
* Deemphasis of all subvector below 1600 Hz. *
*---------------------------------------------------------------*/
fac = 0.1f;
for(i=0; i<lg/4; i+=8)
{
tmp = 0.01f;
for(j=i; j<i+8; j++)
{
tmp += xri[j]*xri[j];
}
tmp = (float)sqrt(tmp);pessimize();
tmp = tmp/max;
if (tmp > fac)
{
fac = tmp;
}
for(j=i; j<i+8; j++)
{
xri[j] *= fac;
}
}
return;
}
#endif
void adap_low_freq_deemph_stereo(float xri[], int lg)
{
int i, j;
float max, fac, tmp;
/*---------------------------------------------------------------*
* Find spectral peak under 1600Hz (lg = 6400Hz) *
* (find maximum of energy of all Re8 subvector under 1600Hz) *
*---------------------------------------------------------------*/
max = 0.01f;
for(i=0; i<lg/4; i+=8)
{
tmp = 0.01f;
for(j=i; j<i+8; j++)
{
tmp += xri[j]*xri[j];
}
if (tmp > max)
{
max = tmp;
}
}
max = (float)sqrt(max); /* sqrt of energy */
/*---------------------------------------------------------------*
* Deemphasis of all subvector below 1600 Hz. *
*---------------------------------------------------------------*/
fac = 0.1f;
for(i=0; i<lg/4; i+=8)
{
tmp = 0.01f;
for(j=i; j<i+8; j++)
{
tmp += xri[j]*xri[j];
}
tmp = (float)sqrt(tmp);pessimize();
tmp = tmp/max;
if (tmp > fac)
{
fac = tmp;
}
for(j=i; j<i+8; j++)
{
xri[j] *= fac;
}
}
return;
}