📄 ltp.c
字号:
{
for (i=0;i<3;i++)
corr[i]=inner_prod(x[i],target,nsf);
for (i=0;i<3;i++)
for (j=0;j<=i;j++)
A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
}
#endif
{
spx_word32_t C[9];
const signed char *ptr=gain_cdbk;
int best_cdbk=0;
spx_word32_t best_sum=0;
C[0]=corr[2];
C[1]=corr[1];
C[2]=corr[0];
C[3]=A[1][2];
C[4]=A[0][1];
C[5]=A[0][2];
C[6]=A[2][2];
C[7]=A[1][1];
C[8]=A[0][0];
/*plc_tuning *= 2;*/
if (plc_tuning<2)
plc_tuning=2;
#ifdef FIXED_POINT
C[0] = MAC16_32_Q15(C[0],MULT16_16_16(plc_tuning,-327),C[0]);
C[1] = MAC16_32_Q15(C[1],MULT16_16_16(plc_tuning,-327),C[1]);
C[2] = MAC16_32_Q15(C[2],MULT16_16_16(plc_tuning,-327),C[2]);
#else
C[0]*=1-.01*plc_tuning;
C[1]*=1-.01*plc_tuning;
C[2]*=1-.01*plc_tuning;
C[6]*=.5*(1+.01*plc_tuning);
C[7]*=.5*(1+.01*plc_tuning);
C[8]*=.5*(1+.01*plc_tuning);
#endif
for (i=0;i<gain_cdbk_size;i++)
{
spx_word32_t sum=0;
spx_word16_t g0,g1,g2;
spx_word16_t pitch_control=64;
spx_word16_t gain_sum;
ptr = gain_cdbk+3*i;
g0=ADD16((spx_word16_t)ptr[0],32);
g1=ADD16((spx_word16_t)ptr[1],32);
g2=ADD16((spx_word16_t)ptr[2],32);
gain_sum = g1;
if (g0>0)
gain_sum += g0;
if (g2>0)
gain_sum += g2;
if (gain_sum > 64)
{
gain_sum = SUB16(gain_sum, 64);
if (gain_sum > 127)
gain_sum = 127;
#ifdef FIXED_POINT
pitch_control = SUB16(64,EXTRACT16(PSHR32(MULT16_16(64,MULT16_16_16(plc_tuning, gain_sum)),10)));
#else
pitch_control = 64*(1.-.001*plc_tuning*gain_sum);
#endif
if (pitch_control < 0)
pitch_control = 0;
}
sum = ADD32(sum,MULT16_32_Q14(MULT16_16_16(g0,pitch_control),C[0]));
sum = ADD32(sum,MULT16_32_Q14(MULT16_16_16(g1,pitch_control),C[1]));
sum = ADD32(sum,MULT16_32_Q14(MULT16_16_16(g2,pitch_control),C[2]));
sum = SUB32(sum,MULT16_32_Q14(MULT16_16_16(g0,g1),C[3]));
sum = SUB32(sum,MULT16_32_Q14(MULT16_16_16(g2,g1),C[4]));
sum = SUB32(sum,MULT16_32_Q14(MULT16_16_16(g2,g0),C[5]));
sum = SUB32(sum,MULT16_32_Q15(MULT16_16_16(g0,g0),C[6]));
sum = SUB32(sum,MULT16_32_Q15(MULT16_16_16(g1,g1),C[7]));
sum = SUB32(sum,MULT16_32_Q15(MULT16_16_16(g2,g2),C[8]));
/* We could force "safe" pitch values to handle packet loss better */
if (sum>best_sum || i==0)
{
best_sum=sum;
best_cdbk=i;
}
}
#ifdef FIXED_POINT
gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*3]);
gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*3+1]);
gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*3+2]);
/*printf ("%d %d %d %d\n",gain[0],gain[1],gain[2], best_cdbk);*/
#else
gain[0] = 0.015625*gain_cdbk[best_cdbk*3] + .5;
gain[1] = 0.015625*gain_cdbk[best_cdbk*3+1]+ .5;
gain[2] = 0.015625*gain_cdbk[best_cdbk*3+2]+ .5;
#endif
*cdbk_index=best_cdbk;
}
#ifdef FIXED_POINT
for (i=0;i<nsf;i++)
exc[i]=SHL32(ADD32(ADD32(MULT16_32_Q15(SHL16(gain[0],7),e[2][i]), MULT16_32_Q15(SHL16(gain[1],7),e[1][i])),
MULT16_32_Q15(SHL16(gain[2],7),e[0][i])), 2);
err=0;
for (i=0;i<nsf;i++)
{
spx_word16_t perr2;
spx_sig_t tmp = SHL32(ADD32(ADD32(MULT16_32_Q15(SHL16(gain[0],7),x[2][i]),MULT16_32_Q15(SHL16(gain[1],7),x[1][i])),
MULT16_32_Q15(SHL16(gain[2],7),x[0][i])),2);
spx_sig_t perr=SUB32(target[i],tmp);
new_target[i] = SUB32(target[i], tmp);
perr2 = EXTRACT16(PSHR32(perr,15));
err = ADD64(err,MULT16_16(perr2,perr2));
}
#else
for (i=0;i<nsf;i++)
exc[i]=gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
err=0;
for (i=0;i<nsf;i++)
{
spx_sig_t tmp = gain[2]*x[0][i]+gain[1]*x[1][i]+gain[0]*x[2][i];
new_target[i] = target[i] - tmp;
err+=new_target[i]*new_target[i];
}
#endif
return err;
}
/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
int pitch_search_3tap(
spx_sig_t target[], /* Target vector */
spx_sig_t *sw,
spx_coef_t ak[], /* LPCs for this subframe */
spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */
spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */
spx_sig_t exc[], /* Excitation */
const void *par,
int start, /* Smallest pitch value allowed */
int end, /* Largest pitch value allowed */
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
int p, /* Number of LPC coeffs */
int nsf, /* Number of samples in subframe */
SpeexBits *bits,
char *stack,
spx_sig_t *exc2,
spx_word16_t *r,
int complexity,
int cdbk_offset,
int plc_tuning
)
{
int i,j;
int cdbk_index, pitch=0, best_gain_index=0;
VARDECL(spx_sig_t *best_exc);
VARDECL(spx_sig_t *new_target);
VARDECL(spx_sig_t *best_target);
int best_pitch=0;
spx_word64_t err, best_err=-1;
int N;
const ltp_params *params;
VARDECL(int *nbest);
N=complexity;
if (N>10)
N=10;
if (N<1)
N=1;
ALLOC(nbest, N, int);
params = (const ltp_params*) par;
if (end<start)
{
speex_bits_pack(bits, 0, params->pitch_bits);
speex_bits_pack(bits, 0, params->gain_bits);
for (i=0;i<nsf;i++)
exc[i]=0;
return start;
}
ALLOC(best_exc, nsf, spx_sig_t);
ALLOC(new_target, nsf, spx_sig_t);
ALLOC(best_target, nsf, spx_sig_t);
if (N>end-start+1)
N=end-start+1;
open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack);
for (i=0;i<N;i++)
{
pitch=nbest[i];
for (j=0;j<nsf;j++)
exc[j]=0;
err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, par, pitch, p, nsf,
bits, stack, exc2, r, new_target, &cdbk_index, cdbk_offset, plc_tuning);
if (err<best_err || best_err<0)
{
for (j=0;j<nsf;j++)
best_exc[j]=exc[j];
for (j=0;j<nsf;j++)
best_target[j]=new_target[j];
best_err=err;
best_pitch=pitch;
best_gain_index=cdbk_index;
}
}
/*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/
speex_bits_pack(bits, best_pitch-start, params->pitch_bits);
speex_bits_pack(bits, best_gain_index, params->gain_bits);
/*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
for (i=0;i<nsf;i++)
exc[i]=best_exc[i];
for (i=0;i<nsf;i++)
target[i]=best_target[i];
return pitch;
}
void pitch_unquant_3tap(
spx_sig_t exc[], /* Excitation */
int start, /* Smallest pitch value allowed */
int end, /* Largest pitch value allowed */
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
const void *par,
int nsf, /* Number of samples in subframe */
int *pitch_val,
spx_word16_t *gain_val,
SpeexBits *bits,
char *stack,
int count_lost,
int subframe_offset,
spx_word16_t last_pitch_gain,
int cdbk_offset
)
{
int i;
int pitch;
int gain_index;
spx_word16_t gain[3];
const signed char *gain_cdbk;
int gain_cdbk_size;
const ltp_params *params;
params = (const ltp_params*) par;
gain_cdbk_size = 1<<params->gain_bits;
gain_cdbk = params->gain_cdbk + 3*gain_cdbk_size*cdbk_offset;
pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
pitch += start;
gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);
/*printf ("decode pitch: %d %d\n", pitch, gain_index);*/
#ifdef FIXED_POINT
gain[0] = 32+(spx_word16_t)gain_cdbk[gain_index*3];
gain[1] = 32+(spx_word16_t)gain_cdbk[gain_index*3+1];
gain[2] = 32+(spx_word16_t)gain_cdbk[gain_index*3+2];
#else
gain[0] = 0.015625*gain_cdbk[gain_index*3]+.5;
gain[1] = 0.015625*gain_cdbk[gain_index*3+1]+.5;
gain[2] = 0.015625*gain_cdbk[gain_index*3+2]+.5;
#endif
if (count_lost && pitch > subframe_offset)
{
float gain_sum;
if (1) {
float tmp = count_lost < 4 ? GAIN_SCALING_1*last_pitch_gain : 0.4 * GAIN_SCALING_1 * last_pitch_gain;
if (tmp>.95)
tmp=.95;
gain_sum = GAIN_SCALING_1*gain_3tap_to_1tap(gain);
if (gain_sum > tmp) {
float fact = tmp/gain_sum;
for (i=0;i<3;i++)
gain[i]*=fact;
}
}
}
*pitch_val = pitch;
gain_val[0]=gain[0];
gain_val[1]=gain[1];
gain_val[2]=gain[2];
{
spx_sig_t *e[3];
VARDECL(spx_sig_t *tmp2);
ALLOC(tmp2, 3*nsf, spx_sig_t);
e[0]=tmp2;
e[1]=tmp2+nsf;
e[2]=tmp2+2*nsf;
for (i=0;i<3;i++)
{
int j;
int pp=pitch+1-i;
#if 0
for (j=0;j<nsf;j++)
{
if (j-pp<0)
e[i][j]=exc[j-pp];
else if (j-pp-pitch<0)
e[i][j]=exc[j-pp-pitch];
else
e[i][j]=0;
}
#else
{
int tmp1, tmp3;
tmp1=nsf;
if (tmp1>pp)
tmp1=pp;
for (j=0;j<tmp1;j++)
e[i][j]=exc[j-pp];
tmp3=nsf;
if (tmp3>pp+pitch)
tmp3=pp+pitch;
for (j=tmp1;j<tmp3;j++)
e[i][j]=exc[j-pp-pitch];
for (j=tmp3;j<nsf;j++)
e[i][j]=0;
}
#endif
}
#ifdef FIXED_POINT
{
for (i=0;i<nsf;i++)
exc[i]=SHL32(ADD32(ADD32(MULT16_32_Q15(SHL16(gain[0],7),e[2][i]), MULT16_32_Q15(SHL16(gain[1],7),e[1][i])),
MULT16_32_Q15(SHL16(gain[2],7),e[0][i])), 2);
}
#else
for (i=0;i<nsf;i++)
exc[i]=VERY_SMALL+gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
#endif
}
}
/** Forced pitch delay and gain */
int forced_pitch_quant(
spx_sig_t target[], /* Target vector */
spx_sig_t *sw,
spx_coef_t ak[], /* LPCs for this subframe */
spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */
spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */
spx_sig_t exc[], /* Excitation */
const void *par,
int start, /* Smallest pitch value allowed */
int end, /* Largest pitch value allowed */
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
int p, /* Number of LPC coeffs */
int nsf, /* Number of samples in subframe */
SpeexBits *bits,
char *stack,
spx_sig_t *exc2,
spx_word16_t *r,
int complexity,
int cdbk_offset,
int plc_tuning
)
{
int i;
float coef = GAIN_SCALING_1*pitch_coef;
if (coef>.99)
coef=.99;
for (i=0;i<nsf;i++)
{
exc[i]=exc[i-start]*coef;
}
return start;
}
/** Unquantize forced pitch delay and gain */
void forced_pitch_unquant(
spx_sig_t exc[], /* Excitation */
int start, /* Smallest pitch value allowed */
int end, /* Largest pitch value allowed */
spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */
const void *par,
int nsf, /* Number of samples in subframe */
int *pitch_val,
spx_word16_t *gain_val,
SpeexBits *bits,
char *stack,
int count_lost,
int subframe_offset,
spx_word16_t last_pitch_gain,
int cdbk_offset
)
{
int i;
float coef = GAIN_SCALING_1*pitch_coef;
if (coef>.99)
coef=.99;
for (i=0;i<nsf;i++)
{
exc[i]=exc[i-start]*coef;
}
*pitch_val = start;
gain_val[0]=gain_val[2]=0;
gain_val[1] = pitch_coef;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -