📄 melp_sub.c
字号:
gain - Q8
*noise_gain - Q8
up - Q19
down - Q17
min - Q8
max - Q8
*/
void noise_est(Shortword gain,Shortword *noise_gain,Shortword up,
Shortword down,Shortword min,Shortword max)
{
Shortword temp1,temp2;
Longword L_noise_gain,L_temp;
/* Update noise_gain */
/* temp1 = add(*noise_gain,up);
temp2 = add(*noise_gain,down); */
L_noise_gain = L_deposit_h(*noise_gain); /* L_noise_gain in Q24 */
L_temp = L_shl(L_deposit_l(up),5);
L_temp = L_add(L_noise_gain,L_temp);
temp1 = round(L_temp);
L_temp = L_shl(L_deposit_l(down),7);
L_temp = L_add(L_noise_gain,L_temp);
temp2 = round(L_temp);
compare_nonzero();
if (gain > temp1)
*noise_gain = temp1;
else if (gain < temp2)
*noise_gain = temp2;
else
*noise_gain = gain;
/* Constrain total range of noise_gain */
compare_nonzero();
if (*noise_gain < min)
*noise_gain = min;
compare_nonzero();
if (*noise_gain > max)
*noise_gain = max;
}
/*
Name: noise_sup.c
Description: Perform noise suppression on speech gain
Inputs: (all in dB)
gain - input gain (in dB)
noise_gain - current noise gain estimate (in dB)
max_noise - maximum allowed noise gain
max_atten - maximum allowed attenuation
nfact - noise floor boost
Outputs:
gain - updated gain
Returns: void
Copyright (c) 1995,1997 by Texas Instruments, Inc. All rights reserved.
Q values:
*gain - Q8
noise_gain - Q8
max_noise - Q8
max_atten - Q8
nfact - Q8
*/
void noise_sup(Shortword *gain,Shortword noise_gain,Shortword max_noise,
Shortword max_atten,Shortword nfact)
{
Shortword gain_lev,suppress;
Shortword temp;
Longword L_temp;
/* Reduce effect for louder background noise */
if (noise_gain > max_noise)
noise_gain = max_noise;
/* Calculate suppression factor */
gain_lev = sub(*gain,add(noise_gain,nfact));
compare_nonzero();
if (gain_lev > X0001_Q8) {
/* suppress = -10.0*log10(1.0 - pow(10.0,-0.1*gain_lev)); */
L_temp = L_mult((Shortword)M01_Q15,gain_lev); /* L_temp in Q24 */
temp = extract_h(L_shl(L_temp,4)); /* temp in Q12 */
temp = pow10_fxp(temp,14);
temp = sub(ONE_Q14,temp);
suppress = mult(M10_Q11,log10_fxp(temp,14)); /* log returns Q12 */
compare_nonzero();
if (suppress > max_atten)
suppress = max_atten;
}
else
suppress = max_atten;
/* Apply suppression to input gain */
*gain = sub(*gain,suppress);
} /* noise_sup */
/*
Name: q_bpvc.c, q_bpvc_dec.c
Description: Quantize/decode bandpass voicing
Inputs:
bpvc, bpvc_index
bpthresh - threshold
NUM_BANDS - number of bands
Outputs:
bpvc, bpvc_index
Returns: uv_flag - flag if unvoiced
Copyright (c) 1995,1997 by Texas Instruments, Inc. All rights reserved.
Q values:
*bpvc - Q14
bpthresh - Q14
*/
/* Compile constants */
#define INVALID_BPVC 0001
Shortword q_bpvc(Shortword *bpvc,Shortword *bpvc_index,Shortword bpthresh,
Shortword NUM_BANDS)
{
Shortword j, uv_flag;
uv_flag = 1; data_move();
if (bpvc[0] > bpthresh) {
/* Voiced: pack bandpass voicing */
uv_flag = 0; data_move();
*bpvc_index = 0; data_move();
bpvc[0] = ONE_Q14; data_move();
for (j = 1; j < NUM_BANDS; j++) {
*bpvc_index = shl(*bpvc_index,1); /* left shift one bit */
if (bpvc[j] > bpthresh) {
bpvc[j] = ONE_Q14; data_move();
*bpvc_index |= 1; logic();
}
else {
bpvc[j] = 0; data_move();
*bpvc_index |= 0; logic();
}
}
/* Don't use invalid code (only top band voiced) */
if (*bpvc_index == INVALID_BPVC) {
bpvc[(NUM_BANDS-1)] = 0;
*bpvc_index = 0;
}
}
else {
/* Unvoiced: force all bands unvoiced */
*bpvc_index = 0;
for (j = 0; j < NUM_BANDS; j++)
bpvc[j] = 0;
}
return(uv_flag);
} /* q_bpvc */
void q_bpvc_dec(Shortword *bpvc,Shortword *bpvc_index,Shortword uv_flag,
Shortword NUM_BANDS)
{
Shortword j;
if (uv_flag) {
/* Unvoiced: set all bpvc to 0 */
*bpvc_index = 0;
bpvc[0] = 0;
}
else {
/* Voiced: set bpvc[0] to 1.0 */
bpvc[0] = ONE_Q14;
}
if (*bpvc_index == INVALID_BPVC) {
/* Invalid code received: set higher band voicing to zero */
*bpvc_index = 0;
}
/* Decode remaining bands */
for (j = NUM_BANDS-1; j > 0; j--) {
compare_nonzero();
logic();
if ((*bpvc_index & 1) == 1)
bpvc[j] = ONE_Q14;
else
bpvc[j] = 0;
*bpvc_index = shr(*bpvc_index,1);
}
} /* q_bpvc_dec */
/*
Name: q_gain.c, q_gain_dec.c
Description: Quantize/decode two gain terms using quasi-differential coding
Inputs:
gain[2],gain_index[2]
GN_QLO,GN_QUP,GN_QLEV for second gain term
Outputs:
gain[2],gain_index[2]
Returns: void
Copyright (c) 1995,1997 by Texas Instruments, Inc. All rights reserved.
Q values:
*gain - Q8
GN_QLO - Q8
GN_QUP - Q8
GN_QLEV_Q - Q10
*/
/* Compile constants */
#define GAIN_INT_DB_Q8 1280 /* (5*(1<<8)) */
void q_gain(Shortword *gain,Shortword *gain_index,Shortword GN_QLO,
Shortword GN_QUP,Shortword GN_QLEV,Shortword GN_QLEV_Q,
Shortword double_flag,Shortword scale)
{
static Shortword prev_gain = 0;
Shortword temp,temp2;
/* Quantize second gain term with uniform quantizer */
quant_u(&gain[1],&gain_index[1],GN_QLO,GN_QUP,GN_QLEV,GN_QLEV_Q,
double_flag,scale);
/* Check for intermediate gain interpolation */
if (gain[0] < GN_QLO) {
gain[0] = GN_QLO; data_move();
}
if (gain[0] > GN_QUP) {
gain[0] = GN_QUP; data_move();
}
/* if (fabs(gain[1] - prev_gain) < GAIN_INT_DB &&
fabs(gain[0] - 0.5*(gain[1]+prev_gain)) < 3.0) */
temp = add(shr(gain[1],1),shr(prev_gain,1));
if (abs_s(sub(gain[1],prev_gain)) < GAIN_INT_DB_Q8 &&
abs_s(sub(gain[0],temp)) < THREE_Q8) {
/* interpolate and set special code */
/* gain[0] = 0.5*(gain[1]+prev_gain); */
gain[0] = temp;
gain_index[0] = 0;
}
else {
/* Code intermediate gain with 7-levels */
if (prev_gain < gain[1]) {
temp = prev_gain; data_move();
temp2 = gain[1]; data_move();
}
else {
temp = gain[1]; data_move();
temp2 = prev_gain; data_move();
}
temp = sub(temp,SIX_Q8);
temp2 = add(temp2,SIX_Q8);
if (temp < GN_QLO) {
temp = GN_QLO; data_move();
}
if (temp2 > GN_QUP) {
temp2 = GN_QUP; data_move();
}
quant_u(&gain[0],&gain_index[0],temp,temp2,6,SIX_Q12,0,3);
/* Skip all-zero code */
gain_index[0] = add(gain_index[0],1);
}
/* Update previous gain for next time */
prev_gain = gain[1]; data_move();
} /* q_gain */
void q_gain_dec(Shortword *gain,Shortword *gain_index,Shortword GN_QLO,
Shortword GN_QUP,Shortword GN_QLEV_Q,Shortword scale)
{
static Shortword prev_gain = 0;
static Shortword prev_gain_err = 0;
Shortword temp,temp2;
/* Decode second gain term */
quant_u_dec(gain_index[1],&gain[1],GN_QLO,GN_QUP,GN_QLEV_Q,scale);
if (gain_index[0] == 0) {
/* interpolation bit code for intermediate gain */
temp = sub(gain[1],prev_gain);
temp = abs_s(temp);
compare_nonzero();
if (temp > GAIN_INT_DB_Q8) {
/* Invalid received data (bit error) */
if (prev_gain_err == 0) {
/* First time: don't allow gain excursion */
gain[1] = prev_gain;
}
prev_gain_err = 1;
}
else
prev_gain_err = 0;
/* Use interpolated gain value */
/* gain[0] = 0.5*(gain[1]+prev_gain); */
gain[0] = add(shr(gain[1],1),shr(prev_gain,1));
}
else {
/* Decode 7-bit quantizer for first gain term */
prev_gain_err = 0;
gain_index[0] = sub(gain_index[0],1);
compare_nonzero();
if (prev_gain < gain[1]) {
temp = prev_gain;
temp2 = gain[1];
}
else {
temp = gain[1];
temp2 = prev_gain;
}
temp = sub(temp,SIX_Q8);
temp2 = add(temp2,SIX_Q8);
compare_nonzero();
if (temp < GN_QLO)
temp = GN_QLO;
compare_nonzero();
if (temp2 > GN_QUP)
temp2 = GN_QUP;
quant_u_dec(gain_index[0],&gain[0],temp,temp2,SIX_Q12,3);
}
/* Update previous gain for next time */
prev_gain = gain[1]; data_move();
} /* q_gain_dec */
/*
Name: scale_adj.c
Description: Adjust scaling of output speech signal.
Inputs:
speech - speech signal
gain - desired RMS gain (log gain)
prev_scale - previous scale factor
length - number of samples in signal
SCALEOVER - number of points to interpolate scale factor
Warning: SCALEOVER is assumed to be less than length.
Outputs:
speech - scaled speech signal
prev_scale - updated previous scale factor
Returns: void
Copyright (c) 1995,1997 by Texas Instruments, Inc. All rights reserved.
Q values:
*speech - Q0
gain - Q12
*prev_scale - Q13
*/
void scale_adj(Shortword *speech, Shortword gain, Shortword *prev_scale,
Shortword length, Shortword SCALEOVER,
Shortword INV_SCALEOVER_Q18)
{
Shortword i;
Shortword scale;
Shortword shift,log_magsq,log_length;
Shortword temp;
Shortword *tempbuf;
Longword L_magsq,L_length,interp1,interp2;
Longword L_temp;
/* Calculate desired scaling factor to match gain level */
/* scale = gain / (sqrt(v_magsq(&speech[0],length) / length) + .01); */
/* find normalization factor for buffer */
MEM_ALLOC(MALLOC,tempbuf,length,Shortword);
shift = 4;
v_equ_shr(tempbuf,speech,shift,length);
L_magsq = L_v_magsq(tempbuf,length,0,1);
compare_zero();
if (L_magsq) {
/* normalize with 1 bit of headroom */
temp = norm_l(L_magsq);
temp = sub(temp,1);
shift = sub(shift,shr(temp,1));
}
else
shift = 0;
v_equ_shr(tempbuf,speech,shift,length);
/* exp = log(2^shift) */
shift = shl(shift,1); /* total compensation = shift*2 */
temp = shl(ONE_Q8,shift);
shift = log10_fxp(temp,8); /* shift in Q12 */
L_magsq = L_v_magsq(tempbuf,length,0,0);
L_magsq = L_add(L_magsq,1); /* ensure L_magsq is not zero */
log_magsq = L_log10_fxp(L_magsq,0); /* log_magsq in Q11 */
/* L_magsq = log_magsq in Q12 */
L_magsq = L_deposit_l(log_magsq);
L_magsq = L_shl(L_magsq,1);
/* compensate for normalization */
/* L_magsq = log magnitude/2 in Q13 */
L_temp = L_deposit_l(shift);
L_magsq = L_add(L_magsq,L_temp);
temp = shl(length,7);
log_length = log10_fxp(temp,7); /* log_length in Q12 */
/* L_length = log_length/2 in Q13 */
L_length = L_deposit_l(log_length);
L_temp = L_deposit_l(gain);
L_temp = L_shl(L_temp,1); /* L_temp in Q13 */
L_temp = L_sub(L_temp,L_magsq);
L_temp = L_add(L_temp,L_length);
L_temp = L_shr(L_temp,1); /* Q13 -> Q12 */
temp = extract_l(L_temp); /* temp in Q12 */
scale = pow10_fxp(temp,13);
/* interpolate scale factors for first SCALEOVER points */
for (i = 1; i < SCALEOVER; i++) {
/* speech[i-1] *= ((scale*i + *prev_scale*(SCALEOVER-i))
* (1.0/SCALEOVER) ); */
temp = sub(SCALEOVER,i);
temp = shl(temp,11);
L_temp = L_mult(temp,INV_SCALEOVER_Q18); /* L_temp in Q30 */
L_temp = L_shl(L_temp,1); /* L_temp in Q31 */
temp = extract_h(L_temp); /* temp in Q15 */
interp1 = L_mult(*prev_scale,temp); /* interp1 in Q29 */
temp = shl(i,11);
L_temp = L_mult(temp,INV_SCALEOVER_Q18); /* L_temp in Q30 */
L_temp = L_shl(L_temp,1); /* L_temp in Q31 */
temp = extract_h(L_temp); /* temp in Q15 */
interp2 = L_mult(scale,temp); /* interp2 in Q29 */
L_temp = L_add(interp1,interp2);
interp1 = extract_h(L_temp); /* interp1 in Q13 */
L_temp = L_mult(speech[i-1],(Shortword)interp1);
L_temp = L_shl(L_temp,2);
speech[i-1] = extract_h(L_temp);
}
/* Scale rest of signal */
v_scale_shl(&speech[SCALEOVER-1],scale,(Shortword)(length-SCALEOVER+1),2);
/* Update previous scale factor for next call */
*prev_scale = scale; data_move();
MEM_FREE(FREE,tempbuf);
} /* scale_adj */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -