/******************************************************************************
* INCLUDE FILES
******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
#include "amr_plus.h"
/******************************************************************************
* PRIVATE PROGRAM CODE
******************************************************************************/
/******************************************************************************
*
* Function : filter5
* Purpose : Fifth-order half-band lowpass/highpass filter pair with
* decimation.
*
*******************************************************************************
*/
static void filter5(
float *in0, /* i/o : input values; output low-pass part */
float *in1, /* i/o : input values; output high-pass part */
float data[] /* i/o : updated filter memory */
)
{
float temp0, temp1, temp2;
temp0 = *in0 - COEFF5_1 * data[0];
temp1 = data[0] + COEFF5_1 * temp0;
data[0] = temp0;
temp0 = *in1 - COEFF5_2 * data[1];
temp2 = data[1] + COEFF5_2 * temp0;
data[1] = temp0;
*in0 = (temp1 + temp2)/2.0f;
*in1 = (temp1 - temp2)/2.0f;
}
/******************************************************************************
*
* Function : filter3
* Purpose : Third-order half-band lowpass/highpass filter pair with
* decimation.
*
*******************************************************************************
*/
static void filter3(
float *in0, /* i/o : input values; output low-pass part */
float *in1, /* i/o : input values; output high-pass part */
float *data /* i/o : updated filter memory */
)
{
float temp1, temp2;
temp1 = *in1 - COEFF3 * *data;
temp2 = *data + COEFF3 * temp1;
*data = temp1;
*in1 = (*in0 - temp2)/2.0f;
*in0 = (*in0 + temp2)/2.0f;
}
/******************************************************************************
*
* Function : level_calculation
* Purpose : Calculate signal level in a sub-band. Level is calculated
* by summing absolute values of the input data.
*
* Because speech coder has a lookahead, signal level calculated
* over the lookahead (data[count1 - count2]) is stored (*sub_level)
* and added to the level of the next frame. Additionally, group
* delay and decimation of the filter bank is taken into the count
* for the values of the counters (count1, count2).
*
*******************************************************************************
*/
static float level_calculation( /* return: signal level */
float data[], /* i : signal buffer */
float *sub_level, /* i : level calculated at the end of the previous frame*/
/* o : level of signal calculated from the last */
/* (count2 - count1) samples */
Word16 count1, /* i : number of samples to be counted */
Word16 count2, /* i : number of samples to be counted */
Word16 ind_m, /* i : step size for the index of the data buffer */
Word16 ind_a, /* i : starting index of the data buffer */
float scale /* i : scaling for the level calculation */
)
{
double l_temp1, l_temp2;
float level;
Word16 i;
l_temp1 = 0.0;
for (i = count1; i < count2; i++)
{
l_temp1 += fabs(data[ind_m*i+ind_a]);
}
l_temp1 *= 2.0f;
l_temp2 = l_temp1 + *sub_level/scale;
*sub_level = (float)(l_temp1*scale);
for (i = 0; i < count1; i++)
{
l_temp2 += 2.0f*fabs(data[ind_m*i+ind_a]);
}
level = (float)(l_temp2*scale);
return level;
}
/******************************************************************************
*
* Function : filter_bank
* Purpose : Divide input signal into bands and calculate level of
* the signal in each band
*
*******************************************************************************
*/
static void filter_bank(
VadVars *st, /* i/o : State struct */
float in[], /* i : input frame */
float level[] /* 0 : signal levels at each band */
)
{
Word16 i;
float tmp_buf[FRAME_LEN];
/* shift input 1 bit down for safe scaling */
for (i = 0; i < FRAME_LEN; i++) {
tmp_buf[i] = in[i]/2.0f;
}
/* run the filter bank */
for (i = 0;i < FRAME_LEN/2; i++) {
filter5(&tmp_buf[2*i],&tmp_buf[2*i+1],st->a_data5[0]);
}
for (i = 0;i < FRAME_LEN/4; i++) {
filter5(&tmp_buf[4*i],&tmp_buf[4*i+2],st->a_data5[1]);
filter5(&tmp_buf[4*i+1],&tmp_buf[4*i+3],st->a_data5[2]);
}
for (i = 0; i < FRAME_LEN/8; i++)
{
filter5(&tmp_buf[8*i], &tmp_buf[8*i+4], st->a_data5[3]);
filter5(&tmp_buf[8*i+2], &tmp_buf[8*i+6], st->a_data5[4]);
filter3(&tmp_buf[8*i+3],&tmp_buf[8*i+7],&st->a_data3[0]);
}
for (i = 0; i < FRAME_LEN/16; i++)
{
filter3(&tmp_buf[16*i+0], &tmp_buf[16*i+8], &st->a_data3[1]);
filter3(&tmp_buf[16*i+4], &tmp_buf[16*i+12], &st->a_data3[2]);
filter3(&tmp_buf[16*i+6], &tmp_buf[16*i+14], &st->a_data3[3]);
}
for (i = 0; i < FRAME_LEN/32; i++)
{
filter3(&tmp_buf[32*i+0], &tmp_buf[32*i+16], &st->a_data3[4]);
filter3(&tmp_buf[32*i+8], &tmp_buf[32*i+24], &st->a_data3[5]);
}
/* calculate levels in each frequency band */
/* 4800 - 6400 Hz*/
level[11] = level_calculation(tmp_buf, &st->sub_level[11],
FRAME_LEN/4-48, FRAME_LEN/4, 4, 1, 0.25);
/* 4000 - 4800 Hz*/
level[10] = level_calculation(tmp_buf, &st->sub_level[10],
FRAME_LEN/8-24, FRAME_LEN/8, 8, 7, 0.5);
/* 3200 - 4000 Hz*/
level[9] = level_calculation(tmp_buf, &st->sub_level[9],
FRAME_LEN/8-24, FRAME_LEN/8, 8, 3, 0.5);
/* 2400 - 3200 Hz*/
level[8] = level_calculation(tmp_buf, &st->sub_level[8],
FRAME_LEN/8-24, FRAME_LEN/8, 8, 2, 0.5);
/* 2000 - 2400 Hz*/
level[7] = level_calculation(tmp_buf, &st->sub_level[7],
FRAME_LEN/16-12, FRAME_LEN/16, 16, 14, 1.0);
/* 1600 - 2000 Hz*/
level[6] = level_calculation(tmp_buf, &st->sub_level[6],
FRAME_LEN/16-12, FRAME_LEN/16, 16, 6, 1.0);
/* 1200 - 1600 Hz*/
level[5] = level_calculation(tmp_buf, &st->sub_level[5],
FRAME_LEN/16-12, FRAME_LEN/16, 16, 4, 1.0);
/* 800 - 1200 Hz*/
level[4] = level_calculation(tmp_buf, &st->sub_level[4],
FRAME_LEN/16-12, FRAME_LEN/16, 16, 12, 1.0);
/* 600 - 800 Hz*/
level[3] = level_calculation(tmp_buf, &st->sub_level[3],
FRAME_LEN/32-6, FRAME_LEN/32, 32, 8, 2.0);
/* 400 - 600 Hz*/
level[2] = level_calculation(tmp_buf, &st->sub_level[2],
FRAME_LEN/32-6, FRAME_LEN/32, 32, 24, 2.0);
/* 200 - 400 Hz*/
level[1] = level_calculation(tmp_buf, &st->sub_level[1],
FRAME_LEN/32-6, FRAME_LEN/32, 32, 16, 2.0);
/* 0 - 200 Hz*/
level[0] = level_calculation(tmp_buf, &st->sub_level[0],
FRAME_LEN/32-6, FRAME_LEN/32, 32, 0, 2.0);
}
/******************************************************************************
*
* Function : update_cntrl
* Purpose : Control update of the background noise estimate.
*
*******************************************************************************
*/
static void update_cntrl(
VadVars *st, /* i/o : State structure */
float level[] /* i : sub-band levels of the input frame */
)
{
Word16 i;
float stat_rat;
float num, denom;
float alpha;
/* if fullband pitch or tone hav
- 1
- 2
前往页