📄 dec_main.c
字号:
L_tmp = L_shl(L_tmp, 1);
exc[i + i_subfr] = round(L_tmp); move16();
}
/* find maximum value of excitation for next scaling */
max = 1; move16();
for (i = 0; i < L_SUBFR; i++)
{
tmp = abs_s(exc[i + i_subfr]);
test();
if (sub(tmp, max) > 0)
{
max = tmp; move16();
}
}
/* tmp = scaling possible according to max value of excitation */
tmp = sub(add(norm_s(max), Q_new), 1);
st->Qsubfr[3] = st->Qsubfr[2]; move16();
st->Qsubfr[2] = st->Qsubfr[1]; move16();
st->Qsubfr[1] = st->Qsubfr[0]; move16();
st->Qsubfr[0] = tmp; move16();
/*------------------------------------------------------------*
* phase dispersion to enhance noise in low bit rate *
*------------------------------------------------------------*/
/* L_gain_code in Q16 */
L_Extract(L_gain_code, &gain_code, &gain_code_lo);
test();test();move16();
if (sub(nb_bits, NBBITS_7k) <= 0)
j = 0; /* high dispersion for rate <= 7.5 kbit/s */
else if (sub(nb_bits, NBBITS_9k) <= 0)
j = 1; /* low dispersion for rate <= 9.6 kbit/s */
else
j = 2; /* no dispersion for rate > 9.6 kbit/s */
Phase_dispersion(gain_code, gain_pit, code, j, st->disp_mem);
/*------------------------------------------------------------*
* 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();
}
if (sub(nb_bits, NBBITS_9k) <= 0)
{
if (sub(pit_sharp, 16384) > 0)
{
for (i = 0; i < L_SUBFR; i++)
{
excp[i] = add(excp[i], exc2[i]);
move16();
}
agc2(exc2, excp, L_SUBFR);
Copy(excp, exc2, L_SUBFR);
}
}
if (sub(nb_bits, NBBITS_7k) <= 0)
{
j = shr(i_subfr, 6);
for (i = 0; i < M; i++)
{
L_tmp = L_mult(isf_tmp[i], sub(32767, interpol_frac[j]));
L_tmp = L_mac(L_tmp, isf[i], interpol_frac[j]);
HfIsf[i] = round(L_tmp);
}
} else
{
Set_zero(st->mem_syn_hf, M16k - M);
}
if (sub(nb_bits, NBBITS_24k) >= 0)
{
corr_gain = Serial_parm(4, &prms);
synthesis(p_Aq, exc2, Q_new, &synth16k[i_subfr * 5 / 4], corr_gain, HfIsf, nb_bits, newDTXState, st, bfi);
} else
synthesis(p_Aq, exc2, Q_new, &synth16k[i_subfr * 5 / 4], 0, HfIsf, nb_bits, newDTXState, st, bfi);
p_Aq += (M + 1); /* interpolated LPC parameters for next subframe */
}
/*--------------------------------------------------*
* Update signal for next frame. *
* -> save past of exc[]. *
* -> save pitch parameters. *
*--------------------------------------------------*/
Copy(&old_exc[L_FRAME], st->old_exc, PIT_MAX + L_INTERPOL);
Scale_sig(exc, L_FRAME, sub(0, Q_new));
dtx_dec_activity_update(st->dtx_decSt, isf, exc);
st->dtx_decSt->dtxGlobalState = newDTXState; move16();
st->prev_bfi = bfi; move16();
return;
}
/*-----------------------------------------------------*
* Function synthesis() *
* *
* Synthesis of signal at 16kHz with HF extension. *
* *
*-----------------------------------------------------*/
static void 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 */
Word16 prms, /* (i) : parameter */
Word16 HfIsf[],
Word16 nb_bits,
Word16 newDTXState,
Decoder_State * st, /* (i/o) : State structure */
Word16 bfi /* (i) : bad frame indicator */
)
{
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[M16k + 1];
Word16 HfA[M16k + 1];
Word16 HF_corr_gain;
Word16 HF_gain_ind;
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);
Oversamp_16k(synth, L_SUBFR, synth16k, st->mem_oversamp);
/*------------------------------------------------------*
* 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; move16();
weight2 = 32767; move16();
} else
{
weight1 = 32767; move16();
weight2 = 0; move16();
}
tmp = mult(weight1, gain1);
tmp = add(tmp, mult(weight2, gain2));
test();
if (tmp != 0)
{
tmp = add(tmp, 1);
}
test();
if (sub(tmp, 3277) < 0)
{
tmp = 3277; /* 0.1 in Q15 */
move16();
}
test(); test();
if ((sub(nb_bits, NBBITS_24k) >= 0 ) && (bfi == 0))
{
/* HF correction gain */
HF_gain_ind = prms;
HF_corr_gain = HP_gain[HF_gain_ind];
/* HF gain */
for (i = 0; i < L_SUBFR16k; i++)
{
HF[i] = shl(mult(HF[i], HF_corr_gain), 1); move16();
}
} else
{
for (i = 0; i < L_SUBFR16k; i++)
{
HF[i] = mult(HF[i], tmp); move16();
}
}
test();test();
if ((sub(nb_bits, NBBITS_7k) <= 0) && (sub(newDTXState, SPEECH) == 0))
{
Isf_Extrapolation(HfIsf);
Isp_Az(HfIsf, HfA, M16k, 0);
Weight_a(HfA, Ap, 29491, M16k); /* fac=0.9 */
Syn_filt(Ap, M16k, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);
} else
{
/* 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 + (M16k - M), 1);
}
/* noise High Pass filtering (1ms of delay) */
Filt_6k_7k(HF, L_SUBFR16k, st->mem_hf);
test();
if (sub(nb_bits, NBBITS_24k) >= 0)
{
/* Low Pass filtering (7 kHz) */
Filt_7k(HF, L_SUBFR16k, st->mem_hf3);
}
/* add filtered HF noise to speech synthesis */
for (i = 0; i < L_SUBFR16k; i++)
{
synth16k[i] = add(synth16k[i], HF[i]); move16();
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -