📄 dec_util.c
字号:
x0 = signal[i];
/* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2] */
/* + a[1]*y[i-1] + a[2] * y[i-2]; */
L_tmp = 8192L + (y1_lo * 29280);
L_tmp = L_tmp + (y2_lo * (-14160));
L_tmp = (L_tmp >> 14);
L_tmp = L_tmp + (y1_hi * 58560);
L_tmp = L_tmp + (y2_hi * (-28320));
L_tmp = L_tmp + (x0 * 1830);
L_tmp = L_tmp + (x1 * (-3660));
L_tmp = L_tmp + (x2 * 1830);
L_tmp = (L_tmp << 1); /* coeff Q12 --> Q13 */
y2_hi = y1_hi;
y2_lo = y1_lo;
D_UTIL_l_extract(L_tmp, &y1_hi, &y1_lo);
/* signal is divided by 16 to avoid overflow in energy computation */
signal[i] = (Word16)((L_tmp + 0x8000) >> 16);
}
mem[0] = y2_hi;
mem[1] = y2_lo;
mem[2] = y1_hi;
mem[3] = y1_lo;
mem[4] = x0;
mem[5] = x1;
return;
}
/*
* D_UTIL_synthesis
*
* Parameters:
* a I: LP filter coefficients
* m I: order of LP filter
* x I: input signal
* y O: output signal
* lg I: size of filtering
* mem I/O: initial filter states
* update_m I: update memory flag
*
* Function:
* Perform the synthesis filtering 1/A(z).
*
* Returns:
* void
*/
static void D_UTIL_synthesis(Word16 a[], Word16 m, Word16 x[], Word16 y[],
Word16 lg, Word16 mem[], Word16 update)
{
Word32 i, j, tmp;
Word16 y_buf[L_SUBFR16k + M16k], a0;
Word16 *yy;
yy = &y_buf[m];
/* copy initial filter states into synthesis buffer */
memcpy(y_buf, mem, m * sizeof(Word16));
a0 = (Word16)(a[0] >> 1); /* input / 2 */
/* Do the filtering. */
for(i = 0; i < lg; i++)
{
tmp = x[i] * a0;
for(j = 1; j <= m; j++)
{
tmp -= a[j] * yy[i - j];
}
y[i] = yy[i] = (Word16)((tmp + 0x800) >> 12);
}
/* Update memory if required */
if(update)
{
memcpy(mem, &yy[lg - m], m * sizeof(Word16));
}
return;
}
/*
* D_UTIL_bp_6k_7k
*
* Parameters:
* signal I/O: signal
* lg I: lenght of signal
* mem I/O: filter memory [4]
*
* Function:
* 15th order band pass 6kHz to 7kHz FIR filter.
*
* Returns:
* void
*/
void D_UTIL_bp_6k_7k(Word16 signal[], Word16 lg, Word16 mem[])
{
Word32 x[L_SUBFR16k + (L_FIR - 1)];
Word32 i, j, tmp;
for(i = 0; i < (L_FIR - 1); i++)
{
x[i] = (Word16)mem[i]; /* gain of filter = 4 */
}
for(i = 0; i < lg; i++)
{
x[i + L_FIR - 1] = signal[i] >> 2; /* gain of filter = 4 */
}
for(i = 0; i < lg; i++)
{
tmp = 0;
for(j = 0; j < L_FIR; j++)
{
tmp += x[i + j] * D_ROM_fir_6k_7k[j];
}
signal[i] = (Word16)((tmp + 0x4000) >> 15);
}
for(i = 0; i < (L_FIR - 1); i++)
{
mem[i] = (Word16)x[lg + i]; /* gain of filter = 4 */
}
return;
}
/*
* D_UTIL_hp_7k
*
* Parameters:
* signal I/O: ISF vector
* lg I: length of signal
* mem I/O: memory (30)
*
* Function:
* 15th order high pass 7kHz FIR filter
*
* Returns:
* void
*/
static void D_UTIL_hp_7k(Word16 signal[], Word16 lg, Word16 mem[])
{
Word32 i, j, tmp;
Word16 x[L_SUBFR16k + (L_FIR - 1)];
memcpy(x, mem, (L_FIR - 1) * sizeof(Word16));
memcpy(&x[L_FIR - 1], signal, lg * sizeof(Word16));
for(i = 0; i < lg; i++)
{
tmp = 0;
for(j = 0; j < L_FIR; j++)
{
tmp += x[i + j] * D_ROM_fir_7k[j];
}
signal[i] = (Word16)((tmp + 0x4000) >> 15);
}
memcpy(mem, x + lg, (L_FIR - 1) * sizeof(Word16));
return;
}
/*
* D_UTIL_Dec_synthesis
*
* Parameters:
* Aq I: quantized Az
* exc I: excitation at 12kHz
* Q_new I: scaling performed on exc
* synth16k O: 16kHz synthesis signal
* prms I: parameters
* HfIsf I/O: High frequency ISF:s
* mode I: codec mode
* newDTXState I: dtx state
* bfi I: bad frame indicator
* st I/O: State structure
*
* Function:
* Synthesis of signal at 16kHz with HF extension.
*
* Returns:
* void
*/
void D_UTIL_dec_synthesis(Word16 Aq[], Word16 exc[], Word16 Q_new,
Word16 synth16k[], Word16 prms, Word16 HfIsf[],
Word16 mode, Word16 newDTXState, Word16 bfi,
Decoder_State *st)
{
Word32 tmp, i;
Word16 exp;
Word16 ener, exp_ener;
Word32 fac;
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;
Word32 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.
*/
memcpy(synth_hi, st->mem_syn_hi, M * sizeof(Word16));
memcpy(synth_lo, st->mem_syn_lo, M * sizeof(Word16));
D_UTIL_synthesis_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
memcpy(st->mem_syn_hi, synth_hi + L_SUBFR, M * sizeof(Word16));
memcpy(st->mem_syn_lo, synth_lo + L_SUBFR, M * sizeof(Word16));
D_UTIL_deemph_32(synth_hi + M, synth_lo + M, synth, PREEMPH_FAC, L_SUBFR,
&(st->mem_deemph));
D_UTIL_hp50_12k8(synth, L_SUBFR, st->mem_sig_out);
D_UTIL_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] = (Word16)(D_UTIL_random(&(st->mem_seed2)) >> 3);
}
/* energy of excitation */
D_UTIL_signal_down_scale(exc, L_SUBFR, 3);
Q_new = (Word16)(Q_new - 3);
ener = (Word16)(D_UTIL_dot_product12(exc, exc, L_SUBFR, &exp_ener) >> 16);
exp_ener = (Word16)(exp_ener - (Q_new << 1));
/* set energy of white noise to energy of excitation */
tmp = (Word16)(D_UTIL_dot_product12(HF, HF, L_SUBFR16k, &exp) >> 16);
if(tmp > ener)
{
tmp = tmp >> 1; /* Be sure tmp < ener */
exp = (Word16)(exp + 1);
}
tmp = (tmp << 15) / ener;
if(tmp > 32767)
{
tmp = 32767;
}
tmp = tmp << 16; /* result is normalized */
exp = (Word16)(exp - exp_ener);
D_UTIL_normalised_inverse_sqrt(&tmp, &exp);
/* L_tmp x 2, L_tmp in Q31 */
/* tmp = 2 x sqrt(ener_exc/ener_hf) */
if(exp >= 0)
{
tmp = tmp >> (15 - exp);
}
else
{
tmp = tmp >> (-exp);
tmp = tmp >> 15;
}
/* saturation */
if(tmp > 0x7FFF)
{
tmp = 0x7FFF;
}
for(i = 0; i < L_SUBFR16k; i++)
{
HF[i] = (Word16)((HF[i] * tmp) >> 15);
}
/* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */
D_UTIL_hp400_12k8(synth, L_SUBFR, st->mem_hp400);
tmp = 0L;
for(i = 0; i < L_SUBFR; i++)
{
tmp = tmp + (synth[i] * synth[i]);
}
tmp = (tmp << 1) + 1;
exp = D_UTIL_norm_l(tmp);
ener = (Word16)((tmp << exp) >> 16); /* ener = r[0] */
tmp = 0L;
for(i = 1; i < L_SUBFR; i++)
{
tmp = tmp + (synth[i] * synth[i - 1]);
}
tmp = (tmp << 1) + 1;
tmp = (tmp << exp) >> 16; /* tmp = r[1] */
if(tmp > 0)
{
fac = ((tmp << 15) / ener);
if(fac > 32767)
{
fac = 32767;
}
}
else
{
fac = 0;
}
/* modify energy of white noise according to synthesis tilt */
gain1 = (32767 - fac);
gain2 = ((32767 - fac) * 20480) >> 15;
gain2 = (gain2 << 1);
if(gain2 > 32767)
gain2 = 32767;
if(st->mem_vad_hist > 0)
{
weight1 = 0;
weight2 = 32767;
}
else
{
weight1 = 32767;
weight2 = 0;
}
tmp = (weight1 * gain1) >> 15;
tmp = tmp + ((weight2 * gain2) >> 15);
if(tmp != 0)
{
tmp = tmp + 1;
}
if(tmp < 3277)
{
tmp = 3277; /* 0.1 in Q15 */
}
if((mode == MODE_24k) & (bfi == 0))
{
/* HF correction gain */
HF_gain_ind = prms;
HF_corr_gain = D_ROM_hp_gain[HF_gain_ind];
/* HF gain */
for(i = 0; i < L_SUBFR16k; i++)
{
HF[i] = (Word16)(((HF[i] * HF_corr_gain) >> 15) << 1);
}
}
else
{
for(i = 0; i < L_SUBFR16k; i++)
{
HF[i] = (Word16)((HF[i] * tmp) >> 15);
}
}
if((mode <= MODE_7k) & (newDTXState == SPEECH))
{
D_LPC_isf_extrapolation(HfIsf);
D_LPC_isp_a_conversion(HfIsf, HfA, M16k);
D_LPC_a_weight(HfA, Ap, 29491, M16k); /* fac=0.9 */
D_UTIL_synthesis(Ap, M16k, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);
}
else
{
/* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */
D_LPC_a_weight(Aq, Ap, 19661, M); /* fac=0.6 */
D_UTIL_synthesis(Ap, M, HF, HF, L_SUBFR16k, st->mem_syn_hf + (M16k - M), 1);
}
/* noise High Pass filtering (1ms of delay) */
D_UTIL_bp_6k_7k(HF, L_SUBFR16k, st->mem_hf);
if(mode == MODE_24k)
{
/* Low Pass filtering (7 kHz) */
D_UTIL_hp_7k(HF, L_SUBFR16k, st->mem_hf3);
}
/* add filtered HF noise to speech synthesis */
for(i = 0; i < L_SUBFR16k; i++)
{
tmp = (synth16k[i] + HF[i]);
synth16k[i] = D_UTIL_saturate(tmp);
}
return;
}
/*
* D_UTIL_preemph
*
* Parameters:
* x I/O: signal
* mu I: preemphasis factor
* lg I: vector size
* mem I/O: memory (x[-1])
*
* Function:
* Filtering through 1 - mu z^-1
*
*
* Returns:
* void
*/
void D_UTIL_preemph(Word16 x[], Word16 mu, Word16 lg, Word16 *mem)
{
Word32 i, L_tmp;
Word16 temp;
temp = x[lg - 1];
for(i = lg - 1; i > 0; i--)
{
L_tmp = x[i] << 15;
L_tmp = L_tmp - (x[i - 1] * mu);
x[i] = (Word16)((L_tmp + 0x4000) >> 15);
}
L_tmp = x[0] << 15;
L_tmp = L_tmp - (*mem * mu);
x[0] = (Word16)((L_tmp + 0x4000) >> 15);
*mem = temp;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -