📄 cod_main.c
字号:
L_Extract(L_gain_code, &gain_code, &gain_code_lo);
/*------------------------------------------------------------*
* noise enhancer *
* ~~~~~~~~~~~~~~ *
* - Enhance excitation on noise. (modify gain of code) *
* If signal is noisy and LPC filter is stable, move gain *
* of code 1.5 dB toward gain of code threshold. *
* This decrease by 3 dB noise energy variation. *
*------------------------------------------------------------*/
tmp = sub(16384, shr(voice_fac, 1)); /* 1=unvoiced, 0=voiced */
fac = mult(stab_fac, tmp);
L_tmp = L_gain_code; move32();
test();
if (L_sub(L_tmp, st->L_gc_thres) < 0)
{
L_tmp = L_add(L_tmp, Mpy_32_16(gain_code, gain_code_lo, 6226));
test();
if (L_sub(L_tmp, st->L_gc_thres) > 0)
{
L_tmp = st->L_gc_thres;move32();
}
} else
{
L_tmp = Mpy_32_16(gain_code, gain_code_lo, 27536);
test();
if (L_sub(L_tmp, st->L_gc_thres) < 0)
{
L_tmp = st->L_gc_thres;move32();
}
}
st->L_gc_thres = L_tmp; move32();
L_gain_code = Mpy_32_16(gain_code, gain_code_lo, sub(32767, fac));
L_Extract(L_tmp, &gain_code, &gain_code_lo);
L_gain_code = L_add(L_gain_code, Mpy_32_16(gain_code, gain_code_lo, fac));
/*------------------------------------------------------------*
* pitch enhancer *
* ~~~~~~~~~~~~~~ *
* - Enhance excitation on voice. (HP filtering of code) *
* On voiced signal, filtering of code by a smooth fir HP *
* filter to decrease energy of code in low frequency. *
*------------------------------------------------------------*/
tmp = add(shr(voice_fac, 3), 4096); /* 0.25=voiced, 0=unvoiced */
L_tmp = L_deposit_h(code[0]);
L_tmp = L_msu(L_tmp, code[1], tmp);
code2[0] = round(L_tmp); move16();
for (i = 1; i < L_SUBFR - 1; i++)
{
L_tmp = L_deposit_h(code[i]);
L_tmp = L_msu(L_tmp, code[i + 1], tmp);
L_tmp = L_msu(L_tmp, code[i - 1], tmp);
code2[i] = round(L_tmp); move16();
}
L_tmp = L_deposit_h(code[L_SUBFR - 1]);
L_tmp = L_msu(L_tmp, code[L_SUBFR - 2], tmp);
code2[L_SUBFR - 1] = round(L_tmp); move16();
/* build excitation */
gain_code = round(L_shl(L_gain_code, Q_new));
for (i = 0; i < L_SUBFR; i++)
{
L_tmp = L_mult(code2[i], gain_code);
L_tmp = L_shl(L_tmp, 5);
L_tmp = L_mac(L_tmp, exc2[i], gain_pit);
L_tmp = L_shl(L_tmp, 1); /* saturation can occur here */
exc2[i] = round(L_tmp); move16();
}
corr_gain = synthesis(p_Aq, exc2, Q_new, &speech16k[i_subfr * 5 / 4], st);
Parm_serial(corr_gain, 4, &prms);
}
p_A += (M + 1);
move16();
p_Aq += (M + 1);
move16();
} /* end of subframe loop */
/*--------------------------------------------------*
* Update signal for next frame. *
* -> save past of speech[], wsp[] and exc[]. *
*--------------------------------------------------*/
Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME);
Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM);
Copy(&old_exc[L_FRAME], st->old_exc, PIT_MAX + L_INTERPOL);
return;
}
/*-----------------------------------------------------*
* Function synthesis() *
* *
* Synthesis of signal at 16kHz with HF extension. *
* *
*-----------------------------------------------------*/
static Word16 synthesis(
Word16 Aq[], /* A(z) : quantized Az */
Word16 exc[], /* (i) : excitation at 12kHz */
Word16 Q_new, /* (i) : scaling performed on exc */
Word16 synth16k[], /* (o) : 16kHz synthesis signal */
Coder_State * st /* (i/o) : State structure */
)
{
Word16 i, fac, tmp, exp;
Word16 ener, exp_ener;
Word32 L_tmp;
Word16 synth_hi[M + L_SUBFR], synth_lo[M + L_SUBFR];
Word16 synth[L_SUBFR];
Word16 HF[L_SUBFR16k]; /* High Frequency vector */
Word16 Ap[M + 1];
Word16 HF_SP[L_SUBFR16k]; /* High Frequency vector (from original signal) */
Word16 HP_est_gain, HP_calc_gain, HP_corr_gain;
Word16 dist_min, dist;
Word16 HP_gain_ind = 0;
Word16 gain1, gain2;
Word16 weight1, weight2;
/*------------------------------------------------------------*
* speech synthesis *
* ~~~~~~~~~~~~~~~~ *
* - Find synthesis speech corresponding to exc2[]. *
* - Perform fixed deemphasis and hp 50hz filtering. *
* - Oversampling from 12.8kHz to 16kHz. *
*------------------------------------------------------------*/
Copy(st->mem_syn_hi, synth_hi, M);
Copy(st->mem_syn_lo, synth_lo, M);
Syn_filt_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
Copy(synth_hi + L_SUBFR, st->mem_syn_hi, M);
Copy(synth_lo + L_SUBFR, st->mem_syn_lo, M);
Deemph_32(synth_hi + M, synth_lo + M, synth, PREEMPH_FAC, L_SUBFR, &(st->mem_deemph));
HP50_12k8(synth, L_SUBFR, st->mem_sig_out);
/* Original speech signal as reference for high band gain quantisation */
for (i = 0; i < L_SUBFR16k; i++)
{
HF_SP[i] = synth16k[i]; move16();
}
/*------------------------------------------------------*
* HF noise synthesis *
* ~~~~~~~~~~~~~~~~~~ *
* - Generate HF noise between 5.5 and 7.5 kHz. *
* - Set energy of noise according to synthesis tilt. *
* tilt > 0.8 ==> - 14 dB (voiced) *
* tilt 0.5 ==> - 6 dB (voiced or noise) *
* tilt < 0.0 ==> 0 dB (noise) *
*------------------------------------------------------*/
/* generate white noise vector */
for (i = 0; i < L_SUBFR16k; i++)
{
HF[i] = shr(Random(&(st->seed2)), 3); move16();
}
/* energy of excitation */
Scale_sig(exc, L_SUBFR, -3);
Q_new = sub(Q_new, 3);
ener = extract_h(Dot_product12(exc, exc, L_SUBFR, &exp_ener));
exp_ener = sub(exp_ener, add(Q_new, Q_new));
/* set energy of white noise to energy of excitation */
tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));
test();
if (sub(tmp, ener) > 0)
{
tmp = shr(tmp, 1); /* Be sure tmp < ener */
exp = add(exp, 1);
}
L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
exp = sub(exp, exp_ener);
Isqrt_n(&L_tmp, &exp);
L_tmp = L_shl(L_tmp, add(exp, 1)); /* L_tmp x 2, L_tmp in Q31 */
tmp = extract_h(L_tmp); /* tmp = 2 x sqrt(ener_exc/ener_hf) */
for (i = 0; i < L_SUBFR16k; i++)
{
HF[i] = mult(HF[i], tmp); move16();
}
/* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */
HP400_12k8(synth, L_SUBFR, st->mem_hp400);
L_tmp = 1L; move32();
for (i = 0; i < L_SUBFR; i++)
L_tmp = L_mac(L_tmp, synth[i], synth[i]);
exp = norm_l(L_tmp);
ener = extract_h(L_shl(L_tmp, exp)); /* ener = r[0] */
L_tmp = 1L; move32();
for (i = 1; i < L_SUBFR; i++)
L_tmp = L_mac(L_tmp, synth[i], synth[i - 1]);
tmp = extract_h(L_shl(L_tmp, exp)); /* tmp = r[1] */
test();
if (tmp > 0)
{
fac = div_s(tmp, ener);
} else
{
fac = 0; move16();
}
/* modify energy of white noise according to synthesis tilt */
gain1 = sub(32767, fac);
gain2 = mult(sub(32767, fac), 20480);
gain2 = shl(gain2, 1);
test();
if (st->vad_hist > 0)
{
weight1 = 0;
weight2 = 32767;
} else
{
weight1 = 32767;
weight2 = 0;
}
tmp = mult(weight1, gain1);
tmp = add(tmp, mult(weight2, gain2));
test();
if (tmp != 0)
{
tmp = add(tmp, 1);
}
HP_est_gain = tmp;
test();
if (sub(HP_est_gain, 3277) < 0)
{
HP_est_gain = 3277; /* 0.1 in Q15 */
move16();
}
/* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */
Weight_a(Aq, Ap, 19661, M); /* fac=0.6 */
Syn_filt(Ap, M, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);
/* noise High Pass filtering (1ms of delay) */
Filt_6k_7k(HF, L_SUBFR16k, st->mem_hf);
/* filtering of the original signal */
Filt_6k_7k(HF_SP, L_SUBFR16k, st->mem_hf2);
/* check the gain difference */
Scale_sig(HF_SP, L_SUBFR16k, -1);
ener = extract_h(Dot_product12(HF_SP, HF_SP, L_SUBFR16k, &exp_ener));
/* set energy of white noise to energy of excitation */
tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));
test();
if (sub(tmp, ener) > 0)
{
tmp = shr(tmp, 1); /* Be sure tmp < ener */
exp = add(exp, 1);
}
L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
exp = sub(exp, exp_ener);
Isqrt_n(&L_tmp, &exp);
L_tmp = L_shl(L_tmp, exp); /* L_tmp, L_tmp in Q31 */
HP_calc_gain = extract_h(L_tmp); /* tmp = sqrt(ener_input/ener_hf) */
/* st->gain_alpha *= st->dtx_encSt->dtxHangoverCount/7 */
L_tmp = L_shl(L_mult(st->dtx_encSt->dtxHangoverCount, 4681), 15);
st->gain_alpha = mult(st->gain_alpha, extract_h(L_tmp));
test();
if (sub(st->dtx_encSt->dtxHangoverCount, 6) > 0)
st->gain_alpha = 32767;
HP_est_gain = shr(HP_est_gain, 1); /* From Q15 to Q14 */
HP_corr_gain = add(mult(HP_calc_gain, st->gain_alpha), mult(sub(32767, st->gain_alpha), HP_est_gain));
/* Quantise the correction gain */
dist_min = 32767;
for (i = 0; i < 16; i++)
{
dist = mult(sub(HP_corr_gain, HP_gain[i]), sub(HP_corr_gain, HP_gain[i]));
test();
if (dist_min > dist)
{
dist_min = dist;
HP_gain_ind = i;
}
}
HP_corr_gain = HP_gain[HP_gain_ind];
/* return the quantised gain index when using the highest mode, otherwise zero */
return (HP_gain_ind);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -