📄 dec_util.c
字号:
*
* Returns:
* 32 bit result
*/
Word32 D_UTIL_mpy_32_16(Word16 hi, Word16 lo, Word16 n)
{
Word32 L_32;
L_32 = hi * n;
L_32 += (lo * n) >> 15;
return(L_32 << 1);
}
/*
* D_UTIL_mpy_32
*
* Parameters:
* hi1 I: hi part of first number
* lo1 I: lo part of first number
* hi2 I: hi part of second number
* lo2 I: lo part of second number
*
* Function:
* Multiply two 32 bit integers (DPF). The result is divided by 2^31
*
* L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1
*
* Returns:
* 32 bit result
*/
Word32 D_UTIL_mpy_32(Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)
{
Word32 L_32;
L_32 = hi1 * hi2;
L_32 += (hi1 * lo2) >> 15;
L_32 += (lo1 * hi2) >> 15;
return(L_32 << 1);
}
/*
* D_UTIL_saturate
*
* Parameters:
* inp I: 32-bit number
*
* Function:
* Saturation to 16-bit number
*
* Returns:
* 16-bit number
*/
Word16 D_UTIL_saturate(Word32 inp)
{
Word16 out;
if ((inp < MAX_16) & (inp > MIN_16))
{
out = (Word16)inp;
}
else
{
if (inp > 0)
{
out = MAX_16;
}
else
{
out = MIN_16;
}
}
return(out);
}
/*
* D_UTIL_signal_up_scale
*
* Parameters:
* x I/O: signal to scale
* lg I: size of x[]
* exp I: exponent: x = round(x << exp)
*
* Function:
* Scale signal up to get maximum of dynamic.
*
* Returns:
* 32 bit result
*/
void D_UTIL_signal_up_scale(Word16 x[], Word16 lg, Word16 exp)
{
Word32 i, tmp;
for (i = 0; i < lg; i++)
{
tmp = x[i] << exp;
x[i] = D_UTIL_saturate(tmp);
}
return;
}
/*
* D_UTIL_signal_down_scale
*
* Parameters:
* x I/O: signal to scale
* lg I: size of x[]
* exp I: exponent: x = round(x << exp)
*
* Function:
* Scale signal up to get maximum of dynamic.
*
* Returns:
* 32 bit result
*/
void D_UTIL_signal_down_scale(Word16 x[], Word16 lg, Word16 exp)
{
Word32 i, tmp;
for(i = 0; i < lg; i++)
{
tmp = x[i] << 16;
tmp = tmp >> exp;
x[i] = (Word16)((tmp + 0x8000) >> 16);
}
return;
}
/*
* D_UTIL_deemph_32
*
* Parameters:
* x_hi I: input signal (bit31..16)
* x_lo I: input signal (bit15..4)
* y O: output signal (x16)
* mu I: (Q15) deemphasis factor
* L I: vector size
* mem I/O: memory (y[-1])
*
* Function:
* Filtering through 1/(1-mu z^-1)
*
* Returns:
* void
*/
static void D_UTIL_deemph_32(Word16 x_hi[], Word16 x_lo[], Word16 y[],
Word16 mu, Word16 L, Word16 *mem)
{
Word32 i, fac;
Word32 tmp;
fac = mu >> 1; /* Q15 --> Q14 */
/* L_tmp = hi<<16 + lo<<4 */
tmp = (x_hi[0] << 12) + x_lo[0];
tmp = (tmp << 6) + (*mem * fac);
tmp = (tmp + 0x2000) >> 14;
y[0] = D_UTIL_saturate(tmp);
for(i = 1; i < L; i++)
{
tmp = (x_hi[i] << 12) + x_lo[i];
tmp = (tmp << 6) + (y[i - 1] * fac);
tmp = (tmp + 0x2000) >> 14;
y[i] = D_UTIL_saturate(tmp);
}
*mem = y[L - 1];
return;
}
/*
* D_UTIL_synthesis_32
*
* Parameters:
* a I: LP filter coefficients
* m I: order of LP filter
* exc I: excitation
* Qnew I: exc scaling = 0(min) to 8(max)
* sig_hi O: synthesis high
* sig_lo O: synthesis low
* lg I: size of filtering
*
* Function:
* Perform the synthesis filtering 1/A(z).
*
* Returns:
* void
*/
static void D_UTIL_synthesis_32(Word16 a[], Word16 m, Word16 exc[],
Word16 Qnew, Word16 sig_hi[], Word16 sig_lo[],
Word16 lg)
{
Word32 i, j, a0;
Word32 tmp, tmp2;
a0 = a[0] >> (4 + Qnew); /* input / 16 and >>Qnew */
/* Do the filtering. */
for(i = 0; i < lg; i++)
{
tmp = 0;
for(j = 1; j <= m; j++)
{
tmp -= sig_lo[i - j] * a[j];
}
tmp = tmp >> (15 - 4); /* -4 : sig_lo[i] << 4 */
tmp2 = exc[i] * a0;
for(j = 1; j <= m; j++)
{
tmp2 -= sig_hi[i - j] * a[j];
}
tmp += tmp2 << 1;
/* sig_hi = bit16 to bit31 of synthesis */
sig_hi[i] = (Word16)(tmp >> 13);
/* sig_lo = bit4 to bit15 of synthesis */
sig_lo[i] = (Word16)((tmp >> 1) - (sig_hi[i] * 4096));
}
return;
}
/*
* D_UTIL_hp50_12k8
*
* Parameters:
* signal I/O: signal
* lg I: lenght of signal
* mem I/O: filter memory [6]
*
* Function:
* 2nd order high pass filter with cut off frequency at 50 Hz.
*
* Algorithm:
*
* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]
* + a[1]*y[i-1] + a[2]*y[i-2];
*
* b[3] = {0.989501953f, -1.979003906f, 0.989501953f};
* a[3] = {1.000000000F, 1.978881836f,-0.966308594f};
*
*
* Returns:
* void
*/
static void D_UTIL_hp50_12k8(Word16 signal[], Word16 lg, Word16 mem[])
{
Word32 i, L_tmp;
Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1, x2;
y2_hi = mem[0];
y2_lo = mem[1];
y1_hi = mem[2];
y1_lo = mem[3];
x0 = mem[4];
x1 = mem[5];
for(i = 0; i < lg; i++)
{
x2 = x1;
x1 = x0;
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; /* rounding to maximise precision */
L_tmp = L_tmp + (y1_lo * 16211);
L_tmp = L_tmp + (y2_lo * (-8021));
L_tmp = L_tmp >> 14;
L_tmp = L_tmp + (y1_hi * 32422);
L_tmp = L_tmp + (y2_hi * (-16042));
L_tmp = L_tmp + (x0 * 8106);
L_tmp = L_tmp + (x1 * (-16212));
L_tmp = L_tmp + (x2 * 8106);
L_tmp = L_tmp << 2; /* coeff Q11 --> Q14 */
y2_hi = y1_hi;
y2_lo = y1_lo;
D_UTIL_l_extract(L_tmp, &y1_hi, &y1_lo);
L_tmp = (L_tmp + 0x4000) >> 15; /* coeff Q14 --> Q15 with saturation */
signal[i] = D_UTIL_saturate(L_tmp);
}
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_interpol
*
* Parameters:
* x I: input vector
* fir I: filter coefficient
* frac I: fraction (0..resol)
* up_samp I: resolution
* nb_coef I: number of coefficients
*
* Function:
* Fractional interpolation of signal at position (frac/up_samp)
*
* Returns:
* result of interpolation
*/
Word16 D_UTIL_interpol(Word16 *x, Word16 const *fir, Word16 frac,
Word16 resol, Word16 nb_coef)
{
Word32 i, k;
Word32 sum;
x = x - nb_coef + 1;
sum = 0L;
for(i = 0, k = ((resol - 1) - frac); i < 2 * nb_coef; i++,
k = (Word16)(k + resol))
{
sum = sum + (x[i] * fir[k]);
}
if((sum < 536846336) & (sum > -536879104))
{
sum = (sum + 0x2000) >> 14;
}
else if(sum > 536846336)
{
sum = 32767;
}
else
{
sum = -32768;
}
return((Word16)sum); /* saturation can occur here */
}
/*
* D_UTIL_up_samp
*
* Parameters:
* res_d I: signal to upsampling
* res_u O: upsampled output
* L_frame I: length of output
*
* Function:
* Upsampling
*
* Returns:
* void
*/
static void D_UTIL_up_samp(Word16 *sig_d, Word16 *sig_u, Word16 L_frame)
{
Word32 pos, i, j;
Word16 frac;
pos = 0; /* position with 1/5 resolution */
for(j = 0; j < L_frame; j++)
{
i = (pos * INV_FAC5) >> 15; /* integer part = pos * 1/5 */
frac = (Word16)(pos - ((i << 2) + i)); /* frac = pos - (pos/5)*5 */
sig_u[j] = D_UTIL_interpol(&sig_d[i], D_ROM_fir_up, frac, FAC5, NB_COEF_UP);
pos = pos + FAC4; /* position + 4/5 */
}
return;
}
/*
* D_UTIL_oversamp_16k
*
* Parameters:
* sig12k8 I: signal to oversampling
* lg I: length of input
* sig16k O: oversampled signal
* mem I/O: memory (2*12)
*
* Function:
* Oversampling from 12.8kHz to 16kHz
*
* Returns:
* void
*/
static void D_UTIL_oversamp_16k(Word16 sig12k8[], Word16 lg, Word16 sig16k[],
Word16 mem[])
{
Word16 lg_up;
Word16 signal[L_SUBFR + (2 * NB_COEF_UP)];
memcpy(signal, mem, (2 * NB_COEF_UP) * sizeof(Word16));
memcpy(signal + (2 * NB_COEF_UP), sig12k8, lg * sizeof(Word16));
lg_up = (Word16)(((lg * UP_FAC) >> 15) << 1);
D_UTIL_up_samp(signal + NB_COEF_UP, sig16k, lg_up);
memcpy(mem, signal + lg, (2 * NB_COEF_UP) * sizeof(Word16));
return;
}
/*
* D_UTIL_hp400_12k8
*
* Parameters:
* signal I/O: signal
* lg I: lenght of signal
* mem I/O: filter memory [6]
*
* Function:
* 2nd order high pass filter with cut off frequency at 400 Hz.
*
* Algorithm:
*
* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]
* + a[1]*y[i-1] + a[2]*y[i-2];
*
* b[3] = {0.893554687, -1.787109375, 0.893554687};
* a[3] = {1.000000000, 1.787109375, -0.864257812};
*
*
* Returns:
* void
*/
void D_UTIL_hp400_12k8(Word16 signal[], Word16 lg, Word16 mem[])
{
Word32 i, L_tmp;
Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1, x2;
y2_hi = mem[0];
y2_lo = mem[1];
y1_hi = mem[2];
y1_lo = mem[3];
x0 = mem[4];
x1 = mem[5];
for(i = 0; i < lg; i++)
{
x2 = x1;
x1 = x0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -