- reference source code for EVS codec
This commit is contained in:
Executable
+81
@@ -0,0 +1,81 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "options.h"
|
||||
#include "basop_util.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "prot_fx.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "stl.h"
|
||||
|
||||
/* Returns: index of next coefficient */
|
||||
Word16 get_next_coeff_mapped(
|
||||
Word16 ii[2], /* i/o: coefficient indexes */
|
||||
Word16 *pp, /* o : peak(1)/hole(0) indicator */
|
||||
Word16 *idx, /* o : index in unmapped domain */
|
||||
CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */
|
||||
)
|
||||
{
|
||||
Word16 p;
|
||||
|
||||
p = s_and(sub(ii[1], hm_cfg->numPeakIndices), sub(hm_cfg->indexBuffer[ii[1]], hm_cfg->indexBuffer[ii[0]]));
|
||||
if (p > 0)
|
||||
{
|
||||
p = 0;
|
||||
move16();
|
||||
}
|
||||
if (p < 0)
|
||||
{
|
||||
p = 1;
|
||||
move16();
|
||||
}
|
||||
*pp = p;
|
||||
move16();
|
||||
*idx = ii[p];
|
||||
move16();
|
||||
ii[p] = add(ii[p], 1);
|
||||
move16();
|
||||
return hm_cfg->indexBuffer[*idx];
|
||||
}
|
||||
|
||||
/* Returns: index of next coefficient */
|
||||
Word16 get_next_coeff_unmapped(
|
||||
Word16 ii[2], /* i/o: coefficient indexes */
|
||||
Word16 *pp, /* o : peak(1)/hole(0) indicator */
|
||||
Word16 *idx, /* o : index in unmapped domain */
|
||||
CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */
|
||||
)
|
||||
{
|
||||
(void)pp;
|
||||
(void)hm_cfg;
|
||||
|
||||
*idx = ii[0];
|
||||
move16();
|
||||
ii[0] = add(ii[0], 1);
|
||||
move16();
|
||||
return *idx;
|
||||
}
|
||||
|
||||
Word16 update_mixed_context(Word16 ctx, Word16 a)
|
||||
{
|
||||
Word32 t32;
|
||||
Word16 t=0; /* initialize just to avoid compiler warning */
|
||||
|
||||
t32 = L_mac0(1-13, s_and(a, ~1), add(shr(a, 2), 1));
|
||||
if (t32 <= 0)
|
||||
{
|
||||
t = extract_l(t32);
|
||||
}
|
||||
a = shr(a, 3);
|
||||
if (t32 > 0)
|
||||
{
|
||||
t = s_min(a, 2);
|
||||
}
|
||||
return add(shl(s_and(ctx, 0xf), 4), add(t, 13));
|
||||
}
|
||||
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "assert.h"
|
||||
#include "prot_fx.h"
|
||||
#include "basop_mpy.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "stl.h"
|
||||
|
||||
/**
|
||||
* \brief 31x16 Bit multiply (x*y)
|
||||
*
|
||||
* \param[i] xh high part, bit [30..15]
|
||||
* \param[i] xl low part, 15 LSBits
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 L_multi31x16_X2(Word16 xh, Word16 xl, Word16 y)
|
||||
{
|
||||
Word32 z;
|
||||
|
||||
z = L_shl(L_mult0(xh,y),15);
|
||||
z = L_mac0(z,xl,y);
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Ari 14 bits common routines
|
||||
-------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Integer Multiply
|
||||
*
|
||||
* \param[i] r
|
||||
* \param[i] c
|
||||
*
|
||||
* \return r*c
|
||||
*/
|
||||
Word32 mul_sbc_14bits(Word32 r, Word16 c)
|
||||
{
|
||||
Word32 ret;
|
||||
|
||||
|
||||
/*
|
||||
temp = (((int32) r)*((int32) c))>>stat_bitsnew;
|
||||
*/
|
||||
assert(stat_bitsnew == 14);
|
||||
ret = Mpy_32_16_1(L_shl(r,15-stat_bitsnew), c);
|
||||
|
||||
/*assert( (((int) r)*((int) c))>>stat_bitsnew == ret);*/
|
||||
|
||||
return (ret);
|
||||
}
|
||||
Executable
+292
@@ -0,0 +1,292 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "stl.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "prot_fx.h"
|
||||
|
||||
void UnmapIndex(
|
||||
Word16 PeriodicityIndex,
|
||||
Word16 Bandwidth,
|
||||
Word16 LtpPitchLag,
|
||||
Word8 SmallerLags,
|
||||
Word16 *FractionalResolution,
|
||||
Word32 *Lag)
|
||||
{
|
||||
Word16 LtpPitchIndex, Multiplier;
|
||||
Word16 Lag16;
|
||||
|
||||
test();
|
||||
IF ((LtpPitchLag > 0) && (s_and(PeriodicityIndex, kLtpHmFlag) != 0))
|
||||
{
|
||||
LtpPitchIndex = shr(PeriodicityIndex, 9);
|
||||
Multiplier = s_and(PeriodicityIndex, 0xff);
|
||||
|
||||
assert(0 <= LtpPitchIndex && LtpPitchIndex <= 16);
|
||||
assert(1 <= Multiplier && Multiplier <= (1 << NumRatioBits[Bandwidth][LtpPitchIndex]));
|
||||
|
||||
*FractionalResolution = kLtpHmFractionalResolution;
|
||||
move16();
|
||||
*Lag = L_shr(L_mult0(LtpPitchLag, Ratios[Bandwidth][LtpPitchIndex][Multiplier-1]), 8);
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
IF (sub(PeriodicityIndex, 16) < 0)
|
||||
{
|
||||
*FractionalResolution = 3;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(0, 6, 3));
|
||||
}
|
||||
ELSE IF (sub(PeriodicityIndex, 80) < 0)
|
||||
{
|
||||
*FractionalResolution = 4;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(16, 8, 4));
|
||||
}
|
||||
ELSE IF (sub(PeriodicityIndex, 208) < 0)
|
||||
{
|
||||
*FractionalResolution = 3;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(80, 12, 3));
|
||||
}
|
||||
ELSE {
|
||||
test();
|
||||
IF (sub(PeriodicityIndex, 224) < 0 || SmallerLags != 0)
|
||||
{
|
||||
*FractionalResolution = 1;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(208, 28, 1));
|
||||
}
|
||||
ELSE {
|
||||
*FractionalResolution = 0;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(224, 188, 0));
|
||||
}
|
||||
}
|
||||
*Lag = L_deposit_l(Lag16);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConfigureContextHm(
|
||||
Word16 NumCoeffs, /* (I) Number of coefficients */
|
||||
Word16 TargetBits, /* (I) Target bit budget (excl. Done flag) */
|
||||
Word16 PeriodicityIndex, /* (I) Pitch related index */
|
||||
Word16 LtpPitchLag, /* (I) TCX-LTP pitch in F.D. */
|
||||
CONTEXT_HM_CONFIG *hm_cfg /* (O) Context-based harmonic model configuration */
|
||||
)
|
||||
{
|
||||
Word8 Bandwidth, SmallerLags;
|
||||
Word32 i, Limit, Lag;
|
||||
Word16 j, Index, FractionalResolution;
|
||||
Word16 *tmp;
|
||||
|
||||
|
||||
Bandwidth = 0;
|
||||
move16();
|
||||
if (sub(NumCoeffs, 256) >= 0)
|
||||
{
|
||||
Bandwidth = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
SmallerLags = 0;
|
||||
move16();
|
||||
test();
|
||||
if ((sub(TargetBits, kSmallerLagsTargetBitsThreshold) <= 0) || (Bandwidth == 0))
|
||||
{
|
||||
SmallerLags = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
UnmapIndex(PeriodicityIndex,
|
||||
Bandwidth,
|
||||
LtpPitchLag,
|
||||
SmallerLags,
|
||||
&FractionalResolution, &Lag);
|
||||
|
||||
/* Set up and fill peakIndices */
|
||||
hm_cfg->peakIndices = hm_cfg->indexBuffer;
|
||||
tmp = hm_cfg->peakIndices;
|
||||
Limit = L_shl(L_deposit_l(sub(NumCoeffs, 1)), FractionalResolution);
|
||||
IF (L_sub(Lag, Limit) < 0)
|
||||
{
|
||||
FOR (i=Lag; i<Limit; i+=Lag)
|
||||
{
|
||||
Index = extract_l(L_shr(i, FractionalResolution));
|
||||
*tmp++ = sub(Index, 1);
|
||||
move16();
|
||||
*tmp++ = Index;
|
||||
move16();
|
||||
*tmp++ = add(Index, 1);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
hm_cfg->numPeakIndices = (Word16)(tmp - hm_cfg->indexBuffer);
|
||||
|
||||
/* Set up and fill holeIndices */
|
||||
hm_cfg->holeIndices = hm_cfg->indexBuffer + hm_cfg->numPeakIndices;
|
||||
tmp = hm_cfg->holeIndices;
|
||||
Index = 0;
|
||||
move16();
|
||||
IF (hm_cfg->numPeakIndices > 0)
|
||||
{
|
||||
FOR (j=0; j<hm_cfg->numPeakIndices; j+=3)
|
||||
{
|
||||
FOR (; Index<hm_cfg->peakIndices[j]; ++Index)
|
||||
{
|
||||
*tmp++ = Index;
|
||||
move16();
|
||||
}
|
||||
Index = add(Index, 3); /* Skip the peak */
|
||||
}
|
||||
}
|
||||
IF (sub(Index, NumCoeffs) < 0)
|
||||
{
|
||||
FOR (; Index<NumCoeffs; ++Index)
|
||||
{
|
||||
*tmp++ = Index;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
hm_cfg->numHoleIndices = (Word16)(tmp - hm_cfg->holeIndices);
|
||||
*tmp++ = NumCoeffs;
|
||||
move16(); /* Add extremal element signaling the end of the buffer */
|
||||
|
||||
}
|
||||
|
||||
Word16 CountIndexBits(
|
||||
Word16 Bandwidth,
|
||||
Word16 PeriodicityIndex)
|
||||
{
|
||||
Word16 result;
|
||||
Word16 PeriodicityIndexS;
|
||||
|
||||
result = 8;
|
||||
move16();
|
||||
PeriodicityIndexS = shr(PeriodicityIndex, 9);
|
||||
|
||||
if (s_and(PeriodicityIndex, kLtpHmFlag) != 0)
|
||||
{
|
||||
result = NumRatioBits[Bandwidth][PeriodicityIndexS];
|
||||
move16();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tcx_hm_render(
|
||||
Word32 lag, /* i: pitch lag Q0 */
|
||||
Word16 fract_res, /* i: fractional resolution of the lag Q0 */
|
||||
Word16 p[] /* o: harmonic model Q13 */
|
||||
)
|
||||
{
|
||||
Word16 k, tmp, height;
|
||||
Word16 PeakDeviation;
|
||||
Word32 f0, tmp32;
|
||||
|
||||
/* Set up overall shape */
|
||||
f0 = L_shl(lag, sub(15, fract_res)); /* Q31 */
|
||||
|
||||
tmp32 = Mpy_32_16_1(f0, -26474);
|
||||
tmp32 = L_shr_r(BASOP_Util_InvLog2(L_shl(tmp32, 7)), 2);
|
||||
tmp32 = L_sub(603979776L, tmp32);
|
||||
tmp32 = L_add(L_add(tmp32, tmp32), Mpy_32_16_1(tmp32, 26214));
|
||||
height = round_fx(tmp32); /* Q13 */
|
||||
|
||||
tmp32 = Mpy_32_16_1(f0, -18910);
|
||||
tmp32 = L_shr_r(BASOP_Util_InvLog2(L_shl(tmp32, 7)), 2);
|
||||
tmp32 = L_sub(1395864371L, tmp32);
|
||||
PeakDeviation = round_fx(tmp32); /* Q14 */
|
||||
|
||||
IF( sub(13915,PeakDeviation) > 0 )
|
||||
{
|
||||
/* A bit error was encountered */
|
||||
return 1;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp = div_s(13915, PeakDeviation);
|
||||
tmp = mult_r(tmp, tmp); /* Q15 */
|
||||
}
|
||||
|
||||
tmp = div_s(13915, PeakDeviation);
|
||||
tmp = mult_r(tmp, tmp); /* Q15 */
|
||||
|
||||
/* Render the prototype peak */
|
||||
p[kTcxHmParabolaHalfWidth] = height;
|
||||
move16();
|
||||
|
||||
FOR (k=1; k<=kTcxHmParabolaHalfWidth; ++k)
|
||||
{
|
||||
p[kTcxHmParabolaHalfWidth+k] = round_fx(Mpy_32_16_1(BASOP_Util_InvLog2(L_shl(L_mult0(i_mult2(negate(k),k), tmp),10)), height));
|
||||
}
|
||||
/* Mirror */
|
||||
FOR (k=-kTcxHmParabolaHalfWidth; k<0; ++k)
|
||||
{
|
||||
p[kTcxHmParabolaHalfWidth+k] = p[kTcxHmParabolaHalfWidth-k];
|
||||
move16();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tcx_hm_modify_envelope(
|
||||
Word16 gain, /* i: HM gain Q11 */
|
||||
Word32 lag, /* i: pitch lag Q0 */
|
||||
Word16 fract_res, /* i: fractional resolution of the lag Q0 */
|
||||
Word16 p[], /* i: harmonic model Q13 */
|
||||
Word32 env[], /* i/o: envelope Q16 */
|
||||
Word16 L_frame /* i: number of spectral lines Q0 */
|
||||
)
|
||||
{
|
||||
Word16 k, h, x, l1,l2, L_frame_m1, L_frame_for_loop;
|
||||
Word16 inv_shape[2*kTcxHmParabolaHalfWidth+1];
|
||||
|
||||
IF ( gain == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FOR (k=0; k<2*kTcxHmParabolaHalfWidth+1; ++k)
|
||||
{
|
||||
/* Q24 = Q11 * Q13; 512 = 1.0 in Q24 format */
|
||||
inv_shape[k] = div_s(512, add(512, mult_r(gain, p[k])));
|
||||
move16();
|
||||
}
|
||||
|
||||
h = 1;
|
||||
move16();
|
||||
k = extract_l(L_shr(lag,fract_res));
|
||||
|
||||
L_frame_m1 = sub(L_frame,1);
|
||||
L_frame_for_loop = add(L_frame,kTcxHmParabolaHalfWidth - 1);
|
||||
|
||||
WHILE ( sub(k,L_frame_for_loop) <= 0 )
|
||||
{
|
||||
l1 = s_max(0, sub(k,kTcxHmParabolaHalfWidth));
|
||||
l2 = s_min(add(k,kTcxHmParabolaHalfWidth), L_frame_m1);
|
||||
FOR (x=l1; x<=l2; ++x)
|
||||
{
|
||||
env[x] = Mpy_32_16_1(env[x], inv_shape[x-k+kTcxHmParabolaHalfWidth]);
|
||||
move32();
|
||||
}
|
||||
|
||||
h = add(h,1);
|
||||
k = extract_l(L_shr(imult3216(lag,h),fract_res));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Executable
+471
@@ -0,0 +1,471 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "prot_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "options.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "stl.h"
|
||||
|
||||
/* Fixed point implementation of exp(negate()) */
|
||||
Word32 expfp( /* o: Q31 */
|
||||
Word16 x, /* i: mantissa Q-e */
|
||||
Word16 x_e) /* i: exponent Q0 */
|
||||
{
|
||||
Word16 xi, xf, tmp;
|
||||
Word16 b0, b1, b2, b3;
|
||||
Word32 y, L_tmp;
|
||||
|
||||
|
||||
assert(x > 0);
|
||||
|
||||
L_tmp = L_shl(L_deposit_h(x), x_e);
|
||||
|
||||
/* split into integer and fractional parts */
|
||||
xi = round_fx(L_tmp);
|
||||
xf = extract_l(L_tmp);
|
||||
|
||||
BASOP_SATURATE_WARNING_OFF;
|
||||
xf = negate(xf);
|
||||
BASOP_SATURATE_WARNING_ON;
|
||||
|
||||
/* Fractional part */
|
||||
/* y = 65536
|
||||
+ xf
|
||||
+ ((xf*xf) / (2*65536))
|
||||
+ ((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)
|
||||
+ ((((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)*xf) / (4*65536)); */
|
||||
y = L_mac0(65536, xf, 1);
|
||||
tmp = shr(mult(xf, xf), 2);
|
||||
y = L_mac0(y, tmp, 1);
|
||||
tmp = shr(mult(shr(mult(tmp, xf), 1), 65536/3), 1);
|
||||
y = L_mac0(y, tmp, 1);
|
||||
tmp = shr(mult(tmp, xf), 3);
|
||||
y = L_mac0(y, tmp, 1);
|
||||
|
||||
/* Integer part */
|
||||
b0 = s_and(xi, 1);
|
||||
b1 = s_and(xi, 2);
|
||||
b2 = s_and(xi, 4);
|
||||
b3 = s_and(xi, 8);
|
||||
|
||||
if (b0 != 0) y = Mpy_32_16_1(y, 24109); /* exp(-1) in -1Q16 */
|
||||
if (b1 != 0) y = Mpy_32_16_1(y, 17739); /* exp(-2) in -2Q17 */
|
||||
if (b2 != 0) y = Mpy_32_16_1(y, 19205); /* exp(-4) in -5Q20 */
|
||||
if (b3 != 0) y = Mpy_32_16_1(y, 22513); /* exp(-8) in -11Q26 */
|
||||
|
||||
/* scaling: -1*b0 - 2*b1 -5*b2 -11*b3 */
|
||||
y = L_shr(y, add(add(xi, shr(xi, 2)), shr(b3, 3)));
|
||||
|
||||
/* zero for xi >= 16 */
|
||||
if (shr(xi, 4) > 0)
|
||||
{
|
||||
y = L_deposit_l(0);
|
||||
}
|
||||
|
||||
|
||||
return L_shl(y, 15);
|
||||
}
|
||||
|
||||
/* Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer
|
||||
*
|
||||
* Returns: *pout1 = ( (base/65536)^(2*exp - 1) ) * 65536
|
||||
* *pout2 = ( (base/65536)^(2*exp + 1) ) * 65536
|
||||
*
|
||||
* NOTE: This function must be in sync with ari_decode_14bits_pow() */
|
||||
void powfp_odd2(Word16 base, /* Q15 */
|
||||
Word16 exp, /* Q0 */
|
||||
Word16 *pout1, /* Q15 */
|
||||
Word16 *pout2) /* Q15 */
|
||||
{
|
||||
/* this version is in sync with ari_enc_14bits_pow()
|
||||
* that is, we have to start multiplication from the largest power-of-two, in order to
|
||||
* get the rounding errors to appear at the same places */
|
||||
Word16 pows[12]; /* powers of two exponents*/
|
||||
Word16 exp2;
|
||||
Word16 out, out2;
|
||||
Word16 k, h, maxk;
|
||||
|
||||
assert(exp >= 0);
|
||||
|
||||
out = base;
|
||||
move16();
|
||||
out2 = 0x7FFF;
|
||||
move16();
|
||||
IF (exp != 0)
|
||||
{
|
||||
exp2 = sub(exp, 1);
|
||||
maxk = sub(15, norm_s(exp));
|
||||
assert(maxk < 12);
|
||||
|
||||
pows[0] = base;
|
||||
move16();
|
||||
FOR (k = 0; k < maxk; k++)
|
||||
{
|
||||
pows[k+1] = mult_r(pows[k], pows[k]);
|
||||
move16();
|
||||
}
|
||||
k = sub(k, 1);
|
||||
h = shl(1, k); /* highest bit of exp2 */
|
||||
out2 = base;
|
||||
move16();
|
||||
out = mult_r(out, pows[k+1]); /* we already know that "exp" has the highest bit set to one since we calculated .. */
|
||||
/* .. the effective length of "exp" earlier on, thus we omit the branch for out2 */
|
||||
if (s_and(exp2, h) != 0)
|
||||
{
|
||||
out2 = mult_r(out2, pows[k+1]);
|
||||
}
|
||||
|
||||
h = shr(h, 1);
|
||||
FOR (k = sub(k, 1); k >= 0; k--)
|
||||
{
|
||||
if (s_and(exp, h) != 0)
|
||||
{
|
||||
out = mult_r(out, pows[k+1]);
|
||||
}
|
||||
|
||||
if (s_and(exp2, h) != 0)
|
||||
{
|
||||
out2 = mult_r(out2, pows[k+1]);
|
||||
}
|
||||
|
||||
h = shr(h, 1);
|
||||
}
|
||||
}
|
||||
|
||||
*pout1 = out2;
|
||||
move16();
|
||||
*pout2 = out;
|
||||
move16();
|
||||
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* Function: tcx_arith_scale_envelope
|
||||
*
|
||||
* For optimal performance of the arithmetic coder, the envelope shape must
|
||||
* be scaled such that the expected bit-consumption of a signal that
|
||||
* follows the scaled shape coincides with the target bitrate.
|
||||
* This function calculates a first-guess scaling and then uses the bi-section
|
||||
* search to find the optimal scaling.
|
||||
*
|
||||
* We assume that lines follow the Laplacian distribution, whereby the expected
|
||||
* bit-consumption would be log2(2*e*s[k]), where s[k] is the envelope value
|
||||
* for the line in question. However, this theoretical formula assumes that
|
||||
* all lines are encoded with magnitude+sign. Since the sign is unnecessary
|
||||
* for 0-values, that estimate of bit-consumption is biased when s[k] is small.
|
||||
* Analytical solution of the expectation for small s[k] is difficult, whereby
|
||||
* we use the approximation log2(2*e*s[k] + 0.15 + 0.035 / s[k]) which is accurate
|
||||
* on the range 0.08 to 1.0.
|
||||
*
|
||||
* NOTE: This function must be bit-exact on all platforms such that encoder
|
||||
* and decoder remain synchronized.
|
||||
*-------------------------------------------------------------------------*/
|
||||
void tcx_arith_scale_envelope(
|
||||
Word16 L_spec_core, /* i: number of lines to scale Q0 */
|
||||
Word16 L_frame, /* i: number of lines Q0 */
|
||||
Word32 env[], /* i: unscaled envelope Q16 */
|
||||
Word16 target_bits, /* i: number of available bits Q0 */
|
||||
Word16 low_complexity, /* i: low-complexity flag Q0 */
|
||||
Word16 s_env[], /* o: scaled envelope Q15-e */
|
||||
Word16 *s_env_e /* o: scaled envelope exponent Q0 */
|
||||
)
|
||||
{
|
||||
Word32 ienv[N_MAX_ARI];
|
||||
Word16 scale, iscale, iscale_e, a_e, b, b_e;
|
||||
Word16 lob, hib, adjust;
|
||||
Word16 k, iter, max_iter, lob_bits, hib_bits;
|
||||
Word16 statesi, bits;
|
||||
Word32 mean, a, s, L_tmp;
|
||||
Word16 mean_e, tmp, tmp2;
|
||||
|
||||
|
||||
|
||||
lob_bits = 0;
|
||||
move16();
|
||||
hib_bits = 0;
|
||||
move16();
|
||||
|
||||
/* Boosting to account for expected spectrum truncation (kMax) */
|
||||
/* target_bits = (int)(target_bits * (1.2f - 0.00045f * target_bits + 0.00000025f * target_bits * target_bits)); */
|
||||
L_tmp = L_shr(Mpy_32_16_1(L_mult0(target_bits, target_bits), 17180), 6); /* Q15; 17180 -> 0.00000025f (Q36) */
|
||||
L_tmp = L_sub(L_tmp, L_shr(L_mult0(target_bits, 30199), 11)); /* Q15; 30199 -> 0.00045f (Q26) */
|
||||
L_tmp = L_add(L_tmp, 39322); /* Q15; 39322 -> 1.2f (Q15) */
|
||||
L_tmp = Mpy_32_16_1(L_tmp, target_bits); /* Q0 */
|
||||
assert(L_tmp < 32768);
|
||||
target_bits = extract_l(L_tmp);
|
||||
|
||||
/* Calculate inverse envelope and find initial scale guess based on mean */
|
||||
mean = L_deposit_l(0);
|
||||
FOR (k = 0; k < L_frame; k++)
|
||||
{
|
||||
/* ienv[k] = 1.0f / env[k];
|
||||
mean += ienv[k]; */
|
||||
|
||||
tmp = norm_l(env[k]);
|
||||
tmp2 = sub(15, tmp);
|
||||
tmp = Inv16(round_fx(L_shl(env[k], tmp)), &tmp2);
|
||||
ienv[k] = L_shl(L_deposit_h(tmp), sub(tmp2, 15)); /* Q16 */ move32();
|
||||
mean = L_add(mean, ienv[k]);
|
||||
}
|
||||
tmp = norm_s(L_frame);
|
||||
tmp = shl(div_s(8192, shl(L_frame, tmp)), sub(tmp, 7));
|
||||
mean = L_shr(Mpy_32_16_1(mean, tmp), 6); /* Q16 */
|
||||
|
||||
/* Rate dependent compensation to get closer to the target on average */
|
||||
/* mean = (float)pow(mean, (float)L_frame / (float)target_bits * 0.357f); */
|
||||
tmp = BASOP_Util_Divide1616_Scale(L_frame, target_bits, &tmp2);
|
||||
tmp = mult_r(tmp, 11698/*0.357f Q15*/);
|
||||
mean = BASOP_Util_fPow(mean, 15, L_deposit_h(tmp), tmp2, &mean_e);
|
||||
|
||||
/* Find first-guess scaling coefficient "scale" such that if "mean" is the
|
||||
* mean of the envelope, then the mean bit-consumption is approximately
|
||||
*
|
||||
* log2(2*e*mean*scale + 0.15 + 0.035/(mean*scale)) * L_frame = target_bits
|
||||
*/
|
||||
/* a = 2*2.71828183f*mean*mean; */
|
||||
tmp = round_fx(mean);
|
||||
a = L_mult(mult_r(tmp, 22268/*2.71828183f Q13*/), tmp);
|
||||
a_e = add(shl(mean_e, 1), 3);
|
||||
|
||||
/* b = (0.15f - (float)pow(2.0f, target_bits/(float)L_frame)) * mean; */
|
||||
tmp = BASOP_Util_Divide1616_Scale(target_bits, L_frame, &tmp2);
|
||||
tmp = round_fx(BASOP_util_Pow2(L_deposit_h(tmp), tmp2, &tmp2));
|
||||
b_e = BASOP_Util_Add_MantExp(4915/*0.15f Q15*/, 0, negate(tmp), tmp2, &b);
|
||||
b = mult_r(b, round_fx(mean));
|
||||
b_e = add(b_e, mean_e);
|
||||
|
||||
/* scale = (-b + (float)sqrt(b*b - 4.0f*a*0.035f)) / (2.0f * a); */
|
||||
tmp = round_fx(BASOP_Util_Add_Mant32Exp(L_mult(b, b), shl(b_e, 1), Mpy_32_16_1(a, -4588/*-4.0f*0.035f Q15*/), a_e, &tmp2));
|
||||
|
||||
IF( tmp <= 0 )
|
||||
{
|
||||
tmp = 0;
|
||||
set16_fx(s_env, 0, L_frame);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp = Sqrt16(tmp, &tmp2);
|
||||
}
|
||||
|
||||
tmp2 = BASOP_Util_Add_MantExp(negate(b), b_e, tmp, tmp2, &scale);
|
||||
scale = BASOP_Util_Divide1616_Scale(scale, round_fx(a), &tmp);
|
||||
scale = shl(scale, sub(sub(add(tmp, tmp2), a_e), 1)); /* Q15 */
|
||||
|
||||
/* iscale = 1.0f / scale; */
|
||||
iscale_e = 0;
|
||||
move16();
|
||||
iscale = Inv16(s_max(1, scale), &iscale_e);
|
||||
|
||||
lob = 0;
|
||||
move16();
|
||||
hib = 0;
|
||||
move16();
|
||||
|
||||
max_iter = 2;
|
||||
move16();
|
||||
if(low_complexity)
|
||||
{
|
||||
max_iter = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (iter = 0; iter < max_iter; iter++)
|
||||
{
|
||||
statesi = 0x7FFF;
|
||||
move16();
|
||||
bits = 0;
|
||||
move16();
|
||||
|
||||
FOR (k = 0; k < L_frame; k++)
|
||||
{
|
||||
s = Mpy_32_16_1(ienv[k], scale); /* Q16 */
|
||||
|
||||
IF (L_sub(s, 5243l/*0.08f Q16*/) <= 0)
|
||||
{
|
||||
/* If s = 0.08, the expected bit-consumption is log2(1.0224). Below 0.08, the bit-consumption
|
||||
estimate function becomes inaccurate, so use log2(1.0224) for all values below 0.08. */
|
||||
/* round(state * 1.0224 * 32768) */
|
||||
statesi = mult_r(statesi, 16751/*1.0224 Q14*/);
|
||||
tmp = norm_s(statesi);
|
||||
statesi = shl(statesi, tmp);
|
||||
bits = add(bits, sub(1, tmp));
|
||||
}
|
||||
ELSE IF (L_sub(s, 16711680l/*255.0 Q16*/) <= 0)
|
||||
{
|
||||
/* a = 5.436564f * s + 0.15f + 0.035f * env[k] * iscale; */
|
||||
L_tmp = L_shl(Mpy_32_16_1(s, 22268/*5.436564f Q12*/), 3);
|
||||
L_tmp = L_add(L_tmp, 9830l/*0.15f Q16*/);
|
||||
L_tmp = L_add(L_tmp, L_shl(Mpy_32_16_1(env[k], mult_r(1147/*0.035f Q15*/, iscale)), iscale_e));
|
||||
|
||||
tmp = norm_l(L_tmp);
|
||||
statesi = mult_r(statesi, round_fx(L_shl(L_tmp, tmp)));
|
||||
bits = add(bits, sub(15, tmp));
|
||||
|
||||
tmp = norm_s(statesi);
|
||||
statesi = shl(statesi, tmp);
|
||||
bits = sub(bits, tmp);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* for large envelope values, s > 255, bit consumption is approx log2(2*e*s)
|
||||
* further, we use round(log2(x)) = floor(log2(x)+0.5) = floor(log2(x*sqrt(2))) */
|
||||
/* a = 5.436564f * s; */
|
||||
L_tmp = Mpy_32_16_1(s, 31492/*5.436564f * 1.4142f Q12*/); /* Q13 */
|
||||
bits = add(bits, sub(17, norm_l(L_tmp)));
|
||||
}
|
||||
}
|
||||
|
||||
IF (sub(bits, target_bits) <= 0) /* Bits leftover => scale is too small */
|
||||
{
|
||||
lob = scale;
|
||||
move16();
|
||||
lob_bits = bits;
|
||||
move16();
|
||||
|
||||
IF (hib > 0) /* Bisection search */
|
||||
{
|
||||
adjust = div_s(sub(hib_bits, target_bits), sub(hib_bits, lob_bits));
|
||||
scale = add(mult_r(sub(lob, hib), adjust), hib);
|
||||
}
|
||||
ELSE /* Initial scale adaptation */
|
||||
{
|
||||
/* adjust = 1.05f * target_bits / (float)bits;
|
||||
scale *= adjust; */
|
||||
adjust = mult_r(17203/*1.05f Q14*/, target_bits);
|
||||
adjust = BASOP_Util_Divide1616_Scale(adjust, bits, &tmp);
|
||||
scale = shl(mult_r(scale, adjust), add(1, tmp));
|
||||
}
|
||||
}
|
||||
ELSE /* Ran out of bits => scale is too large */
|
||||
{
|
||||
hib = scale;
|
||||
move16();
|
||||
hib_bits = bits;
|
||||
move16();
|
||||
|
||||
IF (lob > 0) /* Bisection search */
|
||||
{
|
||||
adjust = div_s(sub(hib_bits, target_bits), sub(hib_bits, lob_bits));
|
||||
scale = add(mult_r(sub(lob, hib), adjust), hib);
|
||||
}
|
||||
ELSE { /* Initial scale adaptation */
|
||||
test();
|
||||
IF( target_bits <= 0 || bits <= 0 ) /* safety check in case of bit errors */
|
||||
{
|
||||
adjust = 0;
|
||||
move16();
|
||||
set16_fx( s_env, 0, L_frame );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adjust = div_s(mult_r(31130/*0.95f Q15*/, target_bits), bits);
|
||||
}
|
||||
scale = mult_r(scale, adjust);
|
||||
}
|
||||
}
|
||||
iscale_e = 0;
|
||||
move16();
|
||||
|
||||
IF( scale == 0 ) /* safety check in case of bit errors */
|
||||
{
|
||||
iscale = 0;
|
||||
move16();
|
||||
set16_fx( s_env, 0, L_frame );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
iscale = Inv16(scale, &iscale_e);
|
||||
}
|
||||
}
|
||||
L_frame = L_spec_core;
|
||||
move16();
|
||||
|
||||
tmp = getScaleFactor32(env, L_frame);
|
||||
*s_env_e = sub(add(15, iscale_e), tmp);
|
||||
move16();
|
||||
BASOP_SATURATE_WARNING_OFF;
|
||||
a = L_shl(1265000, sub(15, *s_env_e));
|
||||
BASOP_SATURATE_WARNING_ON;
|
||||
|
||||
FOR (k = 0; k < L_frame; k++)
|
||||
{
|
||||
L_tmp = Mpy_32_16_1(L_shl(env[k], tmp), iscale);
|
||||
L_tmp = L_min(L_tmp, a);
|
||||
s_env[k] = round_fx(L_tmp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* Function: tcx_arith_render_envelope
|
||||
*
|
||||
* Calculate the envelope of the spectrum based on the LPC shape. The
|
||||
* envelope is used in a perceptual domain, whereby the LPC shape has to
|
||||
* be multiplied by the perceptual model.
|
||||
* Operations that are performed on the spectrum, which change the magnitude
|
||||
* expectation of lines, such as low-frequency emphasis, are included in the
|
||||
* envelope shape.
|
||||
* NOTE: This function must be bit-exact on all platforms such that encoder
|
||||
* and decoder remain synchronized.
|
||||
*-------------------------------------------------------------------------*/
|
||||
void tcx_arith_render_envelope(
|
||||
const Word16 A_ind[], /* i: LPC coefficients of signal envelope */
|
||||
Word16 L_frame, /* i: number of spectral lines */
|
||||
Word16 L_spec,
|
||||
Word16 preemph_fac, /* i: pre-emphasis factor */
|
||||
Word16 gamma_w, /* i: A_ind -> weighted envelope factor */
|
||||
Word16 gamma_uw, /* i: A_ind -> non-weighted envelope factor */
|
||||
Word32 env[] /* o: shaped signal envelope */
|
||||
)
|
||||
{
|
||||
Word16 k;
|
||||
Word16 tmpA[M+2];
|
||||
Word16 signal_env[FDNS_NPTS], signal_env_e[FDNS_NPTS];
|
||||
Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
|
||||
|
||||
|
||||
|
||||
/* Compute perceptual LPC envelope, transform it into freq.-domain gains */
|
||||
weight_a_fx( A_ind, tmpA, gamma_w, M );
|
||||
lpc2mdct( tmpA, M, NULL, NULL, gainlpc, gainlpc_e );
|
||||
|
||||
/* Add pre-emphasis tilt to LPC envelope, transform LPC into MDCT gains */
|
||||
E_LPC_a_weight_inv(A_ind, signal_env, gamma_uw, M);
|
||||
E_LPC_a_add_tilt(signal_env, tmpA, preemph_fac, M);
|
||||
lpc2mdct(tmpA, M+1, signal_env, signal_env_e, NULL, NULL);
|
||||
|
||||
/* Compute weighted signal envelope in perceptual domain */
|
||||
FOR (k = 0; k < FDNS_NPTS; k++)
|
||||
{
|
||||
signal_env[k] = mult_r(signal_env[k], gainlpc[k]);
|
||||
move16();
|
||||
signal_env_e[k] = add(signal_env_e[k], gainlpc_e[k]);
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Adaptive low frequency emphasis */
|
||||
set32_fx(env, 0x10000, L_frame);
|
||||
|
||||
AdaptLowFreqDeemph(env, 15,
|
||||
1,
|
||||
gainlpc, gainlpc_e,
|
||||
L_frame, NULL);
|
||||
|
||||
/* Scale from FDNS_NPTS to L_frame and multiply LFE gains */
|
||||
mdct_noiseShaping_interp(env, L_frame, signal_env, signal_env_e);
|
||||
|
||||
FOR (k=L_frame; k<L_spec; ++k)
|
||||
{
|
||||
env[k] = env[k-1];
|
||||
move32();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "basop_mpy.h"
|
||||
#include "stl.h"
|
||||
#include "options.h" /* Needed for Stack Counting Mechanism Macros (when Instrumented) */
|
||||
|
||||
Word32 Mpy_32_16_1(Word32 x, Word16 y)
|
||||
{
|
||||
Word32 mh;
|
||||
UWord16 ml;
|
||||
|
||||
Mpy_32_16_ss(x, y, &mh, &ml);
|
||||
|
||||
return (mh);
|
||||
}
|
||||
|
||||
Word32 Mpy_32_16_r(Word32 x, Word16 y)
|
||||
{
|
||||
Word32 mh;
|
||||
UWord16 ml;
|
||||
|
||||
Mpy_32_16_ss(x, y, &mh, &ml);
|
||||
|
||||
if(s_and(ml, -32768 /* 0x8000 */))
|
||||
{
|
||||
mh = L_add(mh, 1);
|
||||
}
|
||||
|
||||
return (mh);
|
||||
}
|
||||
|
||||
Word32 Mpy_32_32(Word32 x, Word32 y)
|
||||
{
|
||||
Word32 mh;
|
||||
UWord32 ml;
|
||||
|
||||
Mpy_32_32_ss(x, y, &mh, &ml);
|
||||
|
||||
return (mh);
|
||||
}
|
||||
|
||||
Word32 Mpy_32_32_r(Word32 x, Word32 y)
|
||||
{
|
||||
Word32 mh;
|
||||
UWord32 ml;
|
||||
|
||||
Mpy_32_32_ss(x, y, &mh, &ml);
|
||||
|
||||
if(L_and(ml, 0x80000000))
|
||||
{
|
||||
mh = L_add(mh, 1);
|
||||
}
|
||||
|
||||
return (mh);
|
||||
}
|
||||
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __BASOP_MPY_H
|
||||
#define __BASOP_MPY_H
|
||||
|
||||
#include "stl.h"
|
||||
#include "options.h"
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit fractional Multiplication using 40 bit OPS
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 16-bit variable y, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_16_1(Word32 x,
|
||||
Word16 y);
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit fractional Multiplication using 40 bit OPS
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 16-bit variable y incl. rounding, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_16_r(Word32 x,
|
||||
Word16 y);
|
||||
|
||||
/**
|
||||
* \brief 32*32 Bit fractional Multiplication using 40 bit OPS
|
||||
*
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 32-bit variable y, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_32(Word32 x,
|
||||
Word32 y);
|
||||
|
||||
/**
|
||||
* \brief 32*32 Bit fractional Multiplication using 40 bit OPS including rounding
|
||||
*
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 32-bit variable y, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_32_r(Word32 x, Word32 y);
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit integer Multiplication using 40 bit OPS
|
||||
*
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 16-bit variable y, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_16_2(Word32 x,
|
||||
Word16 y);
|
||||
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit complex fractional multiplication using 40 Bit and 32 Bit operators
|
||||
*
|
||||
* The function mixes 40 Bit and 32 Bit operators, thus it must not be applied
|
||||
* inside of loops where 32 and 16 bit operators are used.
|
||||
*
|
||||
* \param[i] c_Re
|
||||
* \param[i] c_Im
|
||||
* \param[i] a_Re
|
||||
* \param[i] a_Im
|
||||
* \param[i] b_Re
|
||||
* \param[i] b_Im
|
||||
*
|
||||
* \return none
|
||||
*/
|
||||
void cplxMpy_32_16(Word32 *c_Re,
|
||||
Word32 *c_Im,
|
||||
const Word32 a_Re,
|
||||
const Word32 a_Im,
|
||||
const Word16 b_Re,
|
||||
const Word16 b_Im
|
||||
);
|
||||
|
||||
#define MUL_F(A,B) Mpy_32_16_1((A),(B))
|
||||
|
||||
#endif /* __BASOP_SETTINGS_H */
|
||||
Executable
+2236
File diff suppressed because it is too large
Load Diff
Executable
+817
@@ -0,0 +1,817 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __BASOP_UTIL_H__
|
||||
#define __BASOP_UTIL_H__
|
||||
|
||||
#include "stl.h"
|
||||
#include "typedef.h"
|
||||
#include "basop32.h"
|
||||
#include "basop_mpy.h"
|
||||
|
||||
|
||||
#define _LONG long
|
||||
#define _SHORT short
|
||||
#ifdef _WIN32
|
||||
#define _INT64 __int64
|
||||
#else
|
||||
#define _INT64 long long
|
||||
#endif
|
||||
|
||||
#define WORD32_BITS 32
|
||||
#define MAXVAL_WORD32 ((signed)0x7FFFFFFF)
|
||||
#define MINVAL_WORD32 ((signed)0x80000000)
|
||||
#define WORD32_FIX_SCALE ((_INT64)(1)<<(WORD32_BITS-1))
|
||||
|
||||
#define WORD16_BITS 16
|
||||
#define MAXVAL_WORD16 (((signed)0x7FFFFFFF)>>16)
|
||||
#define MINVAL_WORD16 (((signed)0x80000000)>>16)
|
||||
#define WORD16_FIX_SCALE ((_INT64)(1)<<(WORD16_BITS-1))
|
||||
|
||||
/*!
|
||||
\def Macro converts a Word32 fixed point to Word16 fixed point <1 with saturation
|
||||
*/
|
||||
#define WORD322WORD16(val) \
|
||||
( ( ((((val) >> (WORD32_BITS-WORD16_BITS-1)) + 1) > (((_LONG)1<<WORD16_BITS)-1)) && ((_LONG)(val) > 0) ) ? \
|
||||
(Word16)(_SHORT)(((_LONG)1<<(WORD16_BITS-1))-1):(Word16)(_SHORT)((((val) >> (WORD32_BITS-WORD16_BITS-1)) + 1) >> 1) )
|
||||
|
||||
|
||||
/* Word16 Packed Type */
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
Word16 re;
|
||||
Word16 im;
|
||||
} v;
|
||||
} PWord16;
|
||||
|
||||
#define cast16 move16
|
||||
|
||||
|
||||
#define LD_DATA_SCALE (6)
|
||||
#define LD_DATA_SHIFT_I5 (7)
|
||||
|
||||
#define modDiv2(x) sub(x,shl(shr(x,1),1))
|
||||
#define modDiv8(x) L_sub(x,L_shl(L_shr(x,3),3))
|
||||
|
||||
static __inline Word16 limitScale16( Word16 s)
|
||||
{
|
||||
/* It is assumed, that s is calculated just before, therefore we can switch upon sign */
|
||||
if (s >= 0)
|
||||
s = s_min(s,WORD16_BITS-1);
|
||||
if (s < 0)
|
||||
s = s_max(s,1-WORD16_BITS);
|
||||
return (s);
|
||||
}
|
||||
|
||||
static __inline Word16 limitScale32( Word16 s)
|
||||
{
|
||||
/* It is assumed, that s is calculated just before, therefore we can switch upon sign */
|
||||
if (s >= 0)
|
||||
s = s_min(s, WORD32_BITS-1);
|
||||
if (s < 0)
|
||||
s = s_max(s, 1-WORD32_BITS);
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Add two values given by mantissa and exponent.
|
||||
|
||||
Mantissas are in 16-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
|
||||
************************************************************************/
|
||||
Word16 BASOP_Util_Add_MantExp /*!< Exponent of result */
|
||||
(Word16 a_m, /*!< Mantissa of 1st operand a */
|
||||
Word16 a_e, /*!< Exponent of 1st operand a */
|
||||
Word16 b_m, /*!< Mantissa of 2nd operand b */
|
||||
Word16 b_e, /*!< Exponent of 2nd operand b */
|
||||
Word16 *ptrSum_m); /*!< Mantissa of result */
|
||||
|
||||
/************************************************************************/
|
||||
/*!
|
||||
\brief Divide two values given by mantissa and exponent.
|
||||
|
||||
Mantissas are in 16-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
|
||||
For performance reasons, the division is based on a table lookup
|
||||
which limits accuracy.
|
||||
*/
|
||||
void BASOP_Util_Divide_MantExp (Word16 a_m, /*!< Mantissa of dividend a */
|
||||
Word16 a_e, /*!< Exponent of dividend a */
|
||||
Word16 b_m, /*!< Mantissa of divisor b */
|
||||
Word16 b_e, /*!< Exponent of divisor b */
|
||||
Word16 *ptrResult_m, /*!< Mantissa of quotient a/b */
|
||||
Word16 *ptrResult_e /*!< Exponent of quotient a/b */
|
||||
);
|
||||
|
||||
/************************************************************************/
|
||||
/*!
|
||||
\brief Calculate the squareroot of a number given by mantissa and exponent
|
||||
|
||||
Mantissa is in 16/32-bit-fractional format with values between 0 and 1. <br>
|
||||
For *norm versions mantissa has to be between 0.5 and 1. <br>
|
||||
The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
The exponent is addressed via pointers and will be overwritten with the result.
|
||||
*/
|
||||
Word16 Sqrt16( /*!< output mantissa */
|
||||
Word16 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word16 Sqrt16norm( /*!< output mantissa */
|
||||
Word16 mantissa, /*!< normalized input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word32 Sqrt32( /*!< output mantissa */
|
||||
Word32 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word32 Sqrt32norm( /*!< output mantissa */
|
||||
Word32 mantissa, /*!< normalized input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
/* deprecated, use Sqrt16! */
|
||||
void BASOP_Util_Sqrt_MantExp (Word16 *mantissa, /*!< Pointer to mantissa */
|
||||
Word16 *exponent /*!< Pointer to exponent */
|
||||
);
|
||||
|
||||
/* deprecated, use Sqrt16norm! */
|
||||
void BASOP_Util_Sqrt_MantExpNorm (Word16 *mantissa, /*!< Pointer to normalized mantissa */
|
||||
Word16 *exponent /*!< Pointer to exponent */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Calculate the inverse of the squareroot of a number given by mantissa and exponent
|
||||
|
||||
Mantissa is in 16/32-bit-fractional format with values between 0 and 1. <br>
|
||||
For *norm versions mantissa has to be between 0.5 and 1. <br>
|
||||
The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
The exponent is addressed via pointers and will be overwritten with the result.
|
||||
*/
|
||||
Word16 ISqrt16( /*!< output mantissa */
|
||||
Word16 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word32 ISqrt32( /*!< output mantissa */
|
||||
Word32 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word32 ISqrt32norm( /*!< output mantissa */
|
||||
Word32 mantissa, /*!< normalized input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
/* deprecated, use ISqrt16! */
|
||||
void BASOP_Util_InvSqrt_MantExp (Word16 *mantissa, /*!< Pointer to mantissa */
|
||||
Word16 *exponent /*!< Pointer to exponent */
|
||||
);
|
||||
|
||||
/*****************************************************************************/
|
||||
/*!
|
||||
\brief Calculate the inverse of a number given by mantissa and exponent
|
||||
|
||||
Mantissa is in 16-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
The operand is addressed via pointers and will be overwritten with the result.
|
||||
|
||||
The function uses a table lookup and a newton iteration.
|
||||
*/
|
||||
Word16 Inv16( /*!< output mantissa */
|
||||
Word16 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
/******************************************************************************/
|
||||
/*!
|
||||
\brief Calculate the squareroot and inverse of squareroot of a number given by mantissa and exponent
|
||||
|
||||
Mantissa is in 16-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
*/
|
||||
void BASOP_Util_Sqrt_InvSqrt_MantExp (Word16 mantissa, /*!< mantissa */
|
||||
Word16 exponent, /*!< expoinent */
|
||||
Word16 *sqrt_mant, /*!< Pointer to sqrt mantissa */
|
||||
Word16 *sqrt_exp, /*!< Pointer to sqrt exponent */
|
||||
Word16 *isqrt_mant, /*!< Pointer to 1/sqrt mantissa */
|
||||
Word16 *isqrt_exp /*!< Pointer to 1/sqrt exponent */
|
||||
);
|
||||
|
||||
/********************************************************************/
|
||||
/*!
|
||||
\brief Calculates the scalefactor needed to normalize input array
|
||||
|
||||
The scalefactor needed to normalize the Word16 input array is returned <br>
|
||||
If the input array contains only '0', a scalefactor 0 is returned <br>
|
||||
Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x <br>
|
||||
and -32768 <= x <= -16384 for negative x
|
||||
*/
|
||||
|
||||
Word16 getScaleFactor16( /* o: measured headroom in range [0..15], 0 if all x[i] == 0 */
|
||||
const Word16 *x, /* i: array containing 16-bit data */
|
||||
const Word16 len_x); /* i: length of the array to scan */
|
||||
|
||||
/********************************************************************/
|
||||
/*!
|
||||
\brief Calculates the scalefactor needed to normalize input array
|
||||
|
||||
The scalefactor needed to normalize the Word32 input array is returned <br>
|
||||
If the input array contains only '0', a scalefactor 0 is returned <br>
|
||||
Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x <br>
|
||||
and -2147483648 <= x <= -1073741824 for negative x
|
||||
*/
|
||||
|
||||
Word16 getScaleFactor32( /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */
|
||||
const Word32 *x, /* i: array containing 32-bit data */
|
||||
const Word16 len_x); /* i: length of the array to scan */
|
||||
|
||||
/**
|
||||
* \brief normalize mantissa and update the exponent accordingly.
|
||||
* \param mantissa the mantissa to be normalized
|
||||
* \param pexponent pointer to the exponent.
|
||||
* \return the normalized mantissa.
|
||||
*/
|
||||
Word16 normalize16(Word16 mantissa, Word16 *pexponent);
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word16 arg2
|
||||
|
||||
both input arguments may be positive or negative <br>
|
||||
the result is truncated to Word16
|
||||
|
||||
\return fractional integer Word16 result of arg1/arg2
|
||||
*/
|
||||
Word16 divide3216( Word32 x, /*!< Numerator*/
|
||||
Word16 y); /*!< Denominator*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word16 arg1 by Word16 arg2
|
||||
|
||||
both input arguments may be positive or negative <br>
|
||||
the result is truncated to Word16
|
||||
|
||||
\return fractional integer Word16 result of arg1/arg2
|
||||
*/
|
||||
Word16 divide1616( Word16 x, /*!< Numerator*/
|
||||
Word16 y); /*!< Denominator*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word32 arg2
|
||||
|
||||
this function makes both the numerator and the denominator positive integers,
|
||||
and scales up both values to avoid losing the accuracy of the outcome
|
||||
too much
|
||||
|
||||
WARNING: it should be arg1 < arg2 because of the maximum degree of scaling for the mantissa!
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(32bits)
|
||||
*/
|
||||
Word16 divide3232( Word32 x, /*!< Numerator*/
|
||||
Word32 y); /*!< Denominator*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of UWord32 arg1 by UWord32 arg2
|
||||
|
||||
This function ensures both the numerator and the denominator are positive integers,
|
||||
and scales up both values to avoid losing the accuracy of the outcome
|
||||
too much.<br>
|
||||
|
||||
CAUTION: Arg 3 is a Word16 pointer which will point to the scalefactor difference
|
||||
s_diff = sub(s2,s1), where s1 and s2 are the scalefactors of the arguments, which
|
||||
were shifted in order to e.g. preserve accuracy.
|
||||
I.e. the result has to be scaled due to shifting it
|
||||
s_diff to the right to obtain the real result of the division.
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(32bits)
|
||||
*/
|
||||
Word16 BASOP_Util_Divide3232_uu_1616_Scale( Word32 x, /*!< i : Numerator*/
|
||||
Word32 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word32 arg2
|
||||
|
||||
This function scales up both values to avoid losing the accuracy of the outcome
|
||||
too much.<br>
|
||||
|
||||
CAUTION: Arg 3 is a Word16 pointer which will point to the scalefactor difference
|
||||
s_diff = sub(s2,s1), where s1 and s2 are the scalefactors of the arguments, which
|
||||
were shifted in order to e.g. preserve accuracy.
|
||||
I.e. the result has to be scaled due to shifting it
|
||||
s_diff to the right to obtain the real result of the division.
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(32bits)
|
||||
*/
|
||||
Word16 BASOP_Util_Divide3232_Scale( Word32 x, /*!< i : Numerator*/
|
||||
Word32 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word16 arg2
|
||||
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(16bits) , z not normalized
|
||||
*/
|
||||
Word16 BASOP_Util_Divide3216_Scale( Word32 x, /*!< i : Numerator */
|
||||
Word16 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional division of Word16 arg1 by Word16 arg2
|
||||
|
||||
|
||||
\return fractional Q15 Word16 z = arg1(Q15)/arg2(Q15) with scaling s
|
||||
*/
|
||||
Word16 BASOP_Util_Divide1616_Scale( Word16 x, /*!< i : Numerator*/
|
||||
Word16 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
/************************************************************************/
|
||||
/*!
|
||||
\brief Binary logarithm with 7 iterations
|
||||
|
||||
\param x
|
||||
|
||||
\return log2(x)/64
|
||||
*/
|
||||
/************************************************************************/
|
||||
Word32 BASOP_Util_Log2(Word32 x);
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/*!
|
||||
\brief Binary power
|
||||
|
||||
Date: 06-JULY-2012 Arthur Tritthart, IIS Fraunhofer Erlangen
|
||||
|
||||
Version with 3 table lookup and 1 linear interpolations
|
||||
|
||||
Algorithm: compute power of 2, argument x is in Q7.25 format
|
||||
result = 2^(x/64)
|
||||
We split exponent (x/64) into 5 components:
|
||||
integer part: represented by b31..b25 (exp)
|
||||
fractional part 1: represented by b24..b20 (lookup1)
|
||||
fractional part 2: represented by b19..b15 (lookup2)
|
||||
fractional part 3: represented by b14..b10 (lookup3)
|
||||
fractional part 4: represented by b09..b00 (frac)
|
||||
=> result = (lookup1*lookup2*(lookup3+C1*frac)<<3)>>exp
|
||||
|
||||
Due to the fact, that all lookup values contain a factor 0.5
|
||||
the result has to be shifted by 3 to the right also.
|
||||
Table exp2_tab_long contains the log2 for 0 to 1.0 in steps
|
||||
of 1/32, table exp2w_tab_long the log2 for 0 to 1/32 in steps
|
||||
of 1/1024, table exp2x_tab_long the log2 for 0 to 1/1024 in
|
||||
steps of 1/32768. Since the 2-logarithm of very very small
|
||||
negative value is rather linear, we can use interpolation.
|
||||
|
||||
Limitations:
|
||||
|
||||
For x <= 0, the result is fractional positive
|
||||
For x > 0, the result is integer in range 1...7FFF.FFFF
|
||||
For x < -31/64, we have to clear the result
|
||||
For x = 0, the result is ~1.0 (0x7FFF.FFFF)
|
||||
For x >= 31/64, the result is 0x7FFF.FFFF
|
||||
|
||||
\param x
|
||||
|
||||
\return pow(2,(x/64))
|
||||
*/
|
||||
/************************************************************************/
|
||||
Word32 BASOP_Util_InvLog2(Word32 x);
|
||||
|
||||
Word16 BASOP_util_norm_s_bands2shift (Word16 x);
|
||||
|
||||
/***********************************************************************/
|
||||
/*!
|
||||
\brief Calculate the headroom of the complex data in a 2 dimensional array
|
||||
|
||||
\return number of headroom bits
|
||||
*/
|
||||
Word16 BASOP_util_norm_l_dim2_cplx (const Word32 * const *re, /*!< Real part of 32 Bit input */
|
||||
const Word32 * const *im, /*!< Imag part if 32 Bit input */
|
||||
Word16 startBand, /*!< start band of cplx data */
|
||||
Word16 stopBand, /*!< stop band of cplx data */
|
||||
Word16 startSlot, /*!< start slot of cplx data */
|
||||
Word16 stopSlot /*!< stop slot of cplx data */
|
||||
);
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does a data copy of Word8 *arg1 to Word8 *arg2 with Word16 arg3 number of moves
|
||||
*/
|
||||
void copyWord8( const Word8 *src, /*!< i : Source address */
|
||||
Word8 *dst, /*!< i : Destination address */
|
||||
const Word32 n); /*!< i : Number of elements to copy */
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Sets Word8 array arg1[] to zero for a length of Word16 arg2 elements
|
||||
*/
|
||||
void set_zero_Word8( Word8 X[], /*!< i : Address of array */
|
||||
Word32 n); /*!< i : Number of elements to set to zero */
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does a multiplication of Word32 * Word16 input values
|
||||
|
||||
\return z32 = x32 * y16
|
||||
*/
|
||||
Word32 L_mult0_3216( Word32 x, /*!< : Multiplier */
|
||||
Word16 y); /*!< : Multiplicand */
|
||||
|
||||
/* Calculate sin/cos. Angle in 2Q13 format, result has exponent = 1 */
|
||||
Word16 getCosWord16(Word16 theta);
|
||||
Word32 getCosWord32(Word32 theta);
|
||||
/**
|
||||
* \brief calculate cosine of angle. Tuned for ISF domain.
|
||||
* \param theta Angle normalized to radix 2, theta = (angle in radians)*2.0/pi
|
||||
* \return result with exponent 0.
|
||||
*/
|
||||
Word16 getCosWord16R2(Word16 theta);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief square root abacus algorithm
|
||||
|
||||
\return integer sqrt(x)
|
||||
*/
|
||||
Word16 getSqrtWord32(Word32 x);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief finds index of min Word16 in array
|
||||
|
||||
\return index of min Word16
|
||||
*/
|
||||
Word16 findIndexOfMinWord16(Word16 *x, const Word16 len);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief finds index of min Word32 in array
|
||||
|
||||
\return index of min Word32
|
||||
*/
|
||||
Word16 findIndexOfMinWord32(Word32 *x, const Word16 len);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief finds index of max Word16 in array
|
||||
|
||||
\return index of max Word16
|
||||
*/
|
||||
Word16 findIndexOfMaxWord16(Word16 *x, const Word16 len);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief finds index of max Word32 in array
|
||||
|
||||
\return index of max Word32
|
||||
*/
|
||||
Word16 findIndexOfMaxWord32(Word32 *x, const Word16 len);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief 16x16->16 integer multiplication without overflow control
|
||||
|
||||
\return 16x16->16 integer
|
||||
*/
|
||||
Word16 imult1616(Word16 x, Word16 y);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief 32x16->32 integer multiplication with overflow control
|
||||
|
||||
\return 32x16->32 integer
|
||||
*/
|
||||
Word32 imult3216(Word32 x, Word16 y);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief 16/16->16 unsigned integer division
|
||||
|
||||
x and y have to be positive, x has to be < 16384
|
||||
|
||||
\return 16/16->16 integer
|
||||
*/
|
||||
|
||||
Word16 idiv1616U(Word16 x, Word16 y);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief 16/16->16 signed integer division
|
||||
|
||||
x and y have to be positive, x has to be < 16384
|
||||
|
||||
\return 16/16->16 integer
|
||||
*/
|
||||
|
||||
Word16 idiv1616(Word16 x, Word16 y);
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Dot_product16HQ:
|
||||
*
|
||||
* \brief Compute scalar product of <x[],y[]> using 64-bit accumulator.
|
||||
*
|
||||
* Performs normalization of the result, returns the exponent
|
||||
* Note: In contrast to dotWord32, no headroom is required for data
|
||||
* in x[] and y[], means, they may have any format Qn
|
||||
*------------------------------------------------------------------*/
|
||||
Word32 Dot_product16HQ( /*<! o : normalized result Q31 */
|
||||
const Word32 L_off, /*<! i : initial sum value Qn */
|
||||
const Word16 x[], /*<! i : x vector Qn */
|
||||
const Word16 y[], /*<! i : y vector Qn */
|
||||
const Word16 lg, /*<! i : vector length, range [0..7FFF] Q0 */
|
||||
Word16 * exp /*<! o : exponent of result in [-32,31] Q0 */
|
||||
);
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* norm_llQ31:
|
||||
*
|
||||
* \brief Compute normalized Q31 Values out of overflowed Q31 value
|
||||
*
|
||||
* Performs the calculation of a normalized Q31 Value with its
|
||||
* scalingfactor, taking into account the overflowed Q31 input value
|
||||
* and the number of Carrys, collected.
|
||||
*------------------------------------------------------------------*/
|
||||
Word32 norm_llQ31( /* o : normalized result Q31 */
|
||||
Word32 L_c, /* i : upper bits of accu Q-1 */
|
||||
Word32 L_sum, /* i : lower bits of accu, unsigned Q31 */
|
||||
Word16 * exp /* o : exponent of result in [-32,31] Q0 */
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief Compute dot product of 1 32 bit vectors with itself
|
||||
* \param x input vector 1
|
||||
* \param headroom amount of headroom bits the input vector
|
||||
* \param length the length of the input vector
|
||||
* \param result_e pointer to where the exponent of the result will be stored into
|
||||
* \return the dot product of x and x.
|
||||
*/
|
||||
Word32 Norm32Norm(const Word32 *x, const Word16 headroom, const Word16 length, Word16 *result_e);
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Dot_productSq16HQ:
|
||||
*
|
||||
* \brief Compute scalar product of <x[],x[]> using 64-bit accumulator.
|
||||
*
|
||||
* Performs normalization of the result, returns the exponent
|
||||
* Note: In contrast to dotWord32, no headroom is required for data
|
||||
* in x[], means, they may have any format Qn
|
||||
*------------------------------------------------------------------*/
|
||||
Word32 Dot_productSq16HQ( /*<! o : normalized result Q31 */
|
||||
const Word32 L_off, /*<! i : initial sum value Qn */
|
||||
const Word16 x[], /*<! i : x vector Qn */
|
||||
const Word16 lg, /*<! i : vector length, range [0..7FFF] Q0 */
|
||||
Word16 * exp /*<! o : exponent of result in [-32,31] Q0 */
|
||||
);
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* dotp_s_fx:
|
||||
*
|
||||
* \brief Compute scalar product of <x[],y[]> using 64-bit accumulator.
|
||||
*
|
||||
* Performs no normalization of the result
|
||||
*------------------------------------------------------------------*/
|
||||
Word32 dotp_s_fx( /*<! o : dot product of vector x and y 16Q15 */
|
||||
const Word16 *x, /*<! i : vector x 6Q9 */
|
||||
const Word16 *y, /*<! i : vector y 6Q9 */
|
||||
const Word16 n, /*<! i : vector length Q0 */
|
||||
Word16 s /*<! i : headroom Q0 */
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Sum32:
|
||||
*
|
||||
* \brief Return the sum of one 32 bits vector
|
||||
*-------------------------------------------------------------------*/
|
||||
Word32 Sum32( /*<! o : the sum of the elements of the vector */
|
||||
const Word32 *vec, /*<! i : input vector */
|
||||
const Word16 lvec /*<! i : length of input vector */
|
||||
);
|
||||
/**
|
||||
* \brief return 2 ^ (exp * 2^exp_e)
|
||||
* \param exp_m mantissa of the exponent to 2.0f
|
||||
* \param exp_e exponent of the exponent to 2.0f
|
||||
* \param result_e pointer to a INT where the exponent of the result will be stored into
|
||||
* \return mantissa of the result
|
||||
*/
|
||||
Word32 BASOP_util_Pow2(
|
||||
const Word32 exp_m, const Word16 exp_e,
|
||||
Word16 *result_e
|
||||
);
|
||||
|
||||
|
||||
/* deprecated, use ISqrt32norm! */
|
||||
Word32 Isqrt_lc(
|
||||
Word32 frac, /*!< (i) Q31: normalized value (1.0 < frac <= 0.5) */
|
||||
Word16 * exp /*!< (i/o) : exponent (value = frac x 2^exponent) */
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief return 1/x
|
||||
* \param x index of lookup table
|
||||
* \return Word16 value of 1/x
|
||||
*/
|
||||
Word16 getNormReciprocalWord16(Word16 x);
|
||||
|
||||
/**
|
||||
* \brief return (1/x) << s
|
||||
* \param x index of lookup table
|
||||
* \param s shift factor
|
||||
* \return Word16 value of (1/x) << s
|
||||
*/
|
||||
Word16 getNormReciprocalWord16Scale(Word16 x, Word16 s);
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* FUNCTION: BASOP_Util_fPow()
|
||||
*/
|
||||
/**
|
||||
* \brief BASOP_Util_fPow
|
||||
*
|
||||
* PURPOSE: Computes pow(base_m, base_e, exp_m, exp_e), where base_m and base_e
|
||||
* specify the base, and exp_m and exp_e specify the exponent.
|
||||
* The result is returned in a mantissa and exponent representation.
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The function BASOP_Util_fPow(L_x) calculates the power function by
|
||||
* calculating 2 ^ (log2(base)*exp)
|
||||
*
|
||||
* \param base_m mantissa of base
|
||||
* \param base_e exponent of base
|
||||
* \param exp_m mantissa of exponent
|
||||
* \param exp_e exponent of exponent
|
||||
* \param result_e pointer to exponent of result
|
||||
* \return Word32 mantissa of result
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
Word32 BASOP_Util_fPow( /* (o) : mantissa of result */
|
||||
Word32 base_m, Word16 base_e, /* (i) : input value for base (mantissa and exponent) */
|
||||
Word32 exp_m, Word16 exp_e, /* (i) : input value for exponent (mantissa and exponent) */
|
||||
Word16 *result_e /* (o) : output pointer to exponent of result */
|
||||
);
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : Dot_product12_offs() |
|
||||
| |
|
||||
| Compute scalar product of <x[],y[]> using accumulator. |
|
||||
| The parameter 'L_off' is added to the accumulation result. |
|
||||
| The result is normalized (in Q31) with exponent (0..30). |
|
||||
| Notes: |
|
||||
| o data in x[],y[] must provide enough headroom for accumulation |
|
||||
| o L_off must correspond in format with product of x,y |
|
||||
| Example: 0.01f for Q9 x Q9: 0x0000147B in Q19 |
|
||||
| means: L_off = FL2WORD32_SCALE(0.01f,31-19) |
|
||||
|---------------------------------------------------------------------------|
|
||||
| Algorithm: |
|
||||
| |
|
||||
| dot_product = L_off + sum(x[i]*y[i]) i=0..N-1 |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
|
||||
Word32 Dot_product12_offs( /* (o) Q31: normalized result (1 < val <= -1) */
|
||||
const Word16 x[], /* (i) 12bits: x vector */
|
||||
const Word16 y[], /* (i) 12bits: y vector */
|
||||
const Word16 lg, /* (i) : vector length in range [1..256] */
|
||||
Word16 * exp, /* (o) : exponent of result (0..+30) */
|
||||
Word32 L_off /* (i) initial summation offset /2 */
|
||||
);
|
||||
|
||||
Word32 Dot_product15_offs( /* (o) Q31: normalized result (1 < val <= -1) */
|
||||
const Word16 x[], /* (i) 15bits: x vector */
|
||||
const Word16 y[], /* (i) 15bits: y vector */
|
||||
const Word16 lg, /* (i) : vector length in range [1..256] */
|
||||
Word16 *exp, /* (o) : exponent of result (0..+30) */
|
||||
Word32 L_off /* (i) initial summation offset */
|
||||
);
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Add two values given by mantissa and exponent.
|
||||
|
||||
Mantissas are in 32-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
|
||||
************************************************************************/
|
||||
Word32 BASOP_Util_Add_Mant32Exp /*!< o: normalized result mantissa */
|
||||
(Word32 a_m, /*!< i: Mantissa of 1st operand a */
|
||||
Word16 a_e, /*!< i: Exponent of 1st operand a */
|
||||
Word32 b_m, /*!< i: Mantissa of 2nd operand b */
|
||||
Word16 b_e, /*!< i: Exponent of 2nd operand b */
|
||||
Word16 *ptr_e); /*!< o: exponent of result */
|
||||
/*!**********************************************************************
|
||||
\brief Returns the comparison result of two normalized values given by mantissa and exponent.
|
||||
return value: -1: a < b, 0: a == b, 1; a > b
|
||||
|
||||
Mantissas are in 32-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
|
||||
************************************************************************/
|
||||
Word16 BASOP_Util_Cmp_Mant32Exp /*!< o: flag: result of comparison */
|
||||
(Word32 a_m, /*!< i: Mantissa of 1st operand a */
|
||||
Word16 a_e, /*!< i: Exponent of 1st operand a */
|
||||
Word32 b_m, /*!< i: Mantissa of 2nd operand b */
|
||||
Word16 b_e); /*!< i: Exponent of 2nd operand b */
|
||||
|
||||
/********************************************************************
|
||||
* bufferCopyFx
|
||||
*
|
||||
* \brief copies buffer while preserving Format of destination buffer
|
||||
*********************************************************************
|
||||
*/
|
||||
void bufferCopyFx(
|
||||
Word16* src, /*<! Qx pointer to input buffer */
|
||||
Word16* dest, /*<! Qx pointer to output buffer */
|
||||
Word16 length, /*<! Q0 length of buffer to copy */
|
||||
Word16 Qf_src, /*<! Q0 Q format (frac-bits) of source buffer */
|
||||
Word16 Qf_dest, /*<! Q0 Q format (frac-bits )of dest buffer */
|
||||
Word16 Q_src, /*<! Q0 exponent of source buffer */
|
||||
Word16 Q_dest /*<! Q0 exponent of destination buffer */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Accumulates multiplications
|
||||
|
||||
Accumulates the elementwise multiplications of Word32 Array bufX32 with Word16 Array bufY16
|
||||
pointed to by arg1 to arg4 including the corresponding exponents. Length of to be multiplied arrays is arg5,
|
||||
|
||||
\return Word32 result of accumulated multiplications over Word32 array arg1 and Word16 array arg3 and Word16 pointer
|
||||
to exponent of the result
|
||||
*/
|
||||
Word32 dotWord32_16_Mant32Exp(const Word32 *bufX32,/* i: 32-bit buffer with unknown headroom */
|
||||
Word16 bufX32_exp, /* i: exponent of buffer bufX32 */
|
||||
const Word16 *bufY16,/* i: 16-bit buffer quite right-aligned */
|
||||
Word16 bufY16_exp, /* i: exponent of buffer bufY16 */
|
||||
Word16 len, /* i: buffer len to process */
|
||||
Word16 *exp); /* o: result exponent */
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Converts linear factor or energy to Decibel
|
||||
return value: fEnergy=0: 20 * log10(x * 2^{x\_e}),
|
||||
fEnergy=1: 10 * log10(x * 2^{x\_e})
|
||||
|
||||
Mantissa x is in 32-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for exponent x_e is 2. <br>
|
||||
|
||||
************************************************************************/
|
||||
Word16 BASOP_Util_lin2dB( /*!< o: dB value (7Q8) */
|
||||
Word32 x, /*!< i: mantissa */
|
||||
Word16 x_e, /*!< i: exponent */
|
||||
Word16 fEnergy); /*!< i: flag indicating if x is energy */
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Calculates atan(x).
|
||||
************************************************************************/
|
||||
Word16 BASOP_util_atan( /*!< o: atan(x) [-pi/2;pi/2] 1Q14 */
|
||||
Word32 x /*!< i: input data (-64;64) 6Q25 */
|
||||
);
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Calculates atan2(y,x).
|
||||
************************************************************************/
|
||||
Word16 BASOP_util_atan2( /*!< o: atan2(y,x) [-pi,pi] Q13 */
|
||||
Word32 y, /*!< i: */
|
||||
Word32 x, /*!< i: */
|
||||
Word16 e /*!< i: exponent difference (exp_y - exp_x) */
|
||||
);
|
||||
/*!**********************************************************************
|
||||
\brief norm_llQ31 returns Word32 with scalingfactor, with 2 32bit accus as input
|
||||
|
||||
************************************************************************/
|
||||
Word32 norm_llQ31( /* o : normalized result Q31 */
|
||||
Word32 L_c, /* i : upper bits of accu Q-1 */
|
||||
Word32 L_sum, /* i : lower bits of accu, unsigned Q31 */
|
||||
Word16 * exp /* o : exponent of result in [-32,31] Q0 */
|
||||
);
|
||||
|
||||
/* compare two positive normalized 16 bit mantissa/exponent values */
|
||||
/* return value: positive if first value greater, negative if second value greater, zero if equal */
|
||||
Word16 compMantExp16Unorm(Word16 m1, Word16 e1, Word16 m2, Word16 e2);
|
||||
|
||||
|
||||
|
||||
#endif /* __BASOP_UTIL_H__ */
|
||||
Executable
+1029
File diff suppressed because it is too large
Load Diff
Executable
+63
@@ -0,0 +1,63 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* Common constants */
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* bitallocsum_fx()
|
||||
*
|
||||
* Calculate the total number of bits allocated over frame
|
||||
*--------------------------------------------------------------------------*/
|
||||
void bitallocsum_fx(
|
||||
Word16 *R, /* i : bit-allocation vector Q0 */
|
||||
const Word16 nb_sfm, /* i : number of sub-vectors Q0 */
|
||||
Word16 *sum, /* o : total number of bits allocated Q0 */
|
||||
Word16 *Rsubband, /* o : rate per subband Q3 */
|
||||
const Word16 v, /* i : bit rate Q0 */
|
||||
const Word16 length, /* i : length of spectrum (32 or 48 kHz samplerate) Q0 */
|
||||
const Word16 *sfmsize /* i : band length Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word16 total, tmp;
|
||||
Word16 diff;
|
||||
|
||||
total = (Word16)0;
|
||||
move16();
|
||||
FOR (i = 0; i < nb_sfm; i++)
|
||||
{
|
||||
tmp = extract_l(L_mult0(R[i], sfmsize[i]));
|
||||
Rsubband[i] = shl(tmp, 3);
|
||||
move16();
|
||||
total = add(total, tmp);
|
||||
}
|
||||
*sum = total;
|
||||
|
||||
IF ( sub(length, L_FRAME32k) <= 0 )
|
||||
{
|
||||
diff = sub(v, *sum);
|
||||
i = (Word16)0;
|
||||
move16();
|
||||
WHILE ( diff > 0 )
|
||||
{
|
||||
IF ( R[i] > 0 )
|
||||
{
|
||||
Rsubband[i] = add(Rsubband[i], 8);
|
||||
move16();
|
||||
diff = sub(diff, 1);
|
||||
*sum = add(*sum, 1);
|
||||
}
|
||||
i = add(i, 1);
|
||||
if ( sub(i, nb_sfm) >= 0 )
|
||||
{
|
||||
i = (Word16)0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
Executable
+384
@@ -0,0 +1,384 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "options.h"
|
||||
#include "prot_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "stl.h"
|
||||
#include "options.h"
|
||||
#include "rom_com_fx.h"
|
||||
|
||||
|
||||
/*
|
||||
* function BITS_ALLOC_init_config_acelp()
|
||||
*
|
||||
* description: initial configuration for ACELP
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
void BITS_ALLOC_init_config_acelp(
|
||||
const Word32 bit_rate,
|
||||
const Word8 narrowBand,
|
||||
const Word16 nb_subfr,
|
||||
ACELP_config *pConfigAcelp /*o: configuration structure of ACELP*/
|
||||
)
|
||||
{
|
||||
Word8 rate_mode_index;
|
||||
|
||||
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
rate_mode_index=(bit_rate > ACELP_9k60);
|
||||
|
||||
pConfigAcelp->mode_index=rate_mode_index;
|
||||
|
||||
|
||||
/*LPC: midLpc should be swithced off?*/
|
||||
pConfigAcelp->midLpc_enable = 1;
|
||||
move16();
|
||||
|
||||
/*ACELP ICB config*/
|
||||
test();
|
||||
IF( (rate_mode_index==0) || narrowBand != 0 )
|
||||
{
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
pConfigAcelp->pre_emphasis = 1;
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
pConfigAcelp->formant_enh_den = FORMANT_SHARPENING_G2;
|
||||
pConfigAcelp->formant_tilt = 0;
|
||||
pConfigAcelp->voice_tilt = 0;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
pConfigAcelp->pre_emphasis = 0;
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
pConfigAcelp->formant_enh_den = FORMANT_SHARPENING_G2;
|
||||
pConfigAcelp->formant_tilt = 1;
|
||||
pConfigAcelp->voice_tilt = 1;
|
||||
}
|
||||
|
||||
/*Wide band @ 16kHz*/
|
||||
IF ( sub(nb_subfr,NB_SUBFR16k) == 0 )
|
||||
{
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
pConfigAcelp->pre_emphasis = 1;
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
||||
pConfigAcelp->formant_enh_den = FORMANT_SHARPENING_G2_16k;
|
||||
pConfigAcelp->formant_tilt = 0;
|
||||
pConfigAcelp->voice_tilt = 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* function BITS_ALLOC_config_acelp()
|
||||
*
|
||||
* description: configure all acelp modes and allocate the bits
|
||||
*
|
||||
* return: bit demand
|
||||
*/
|
||||
Word16 BITS_ALLOC_config_acelp(
|
||||
const Word16 bits_frame, /*i: remaining bit budget for the frame*/
|
||||
const Word16 coder_type, /*i: acelp coder type*/
|
||||
ACELP_config *pConfigAcelp, /*i/o: configuration structure of ACELP*/
|
||||
const Word16 narrowBand,
|
||||
const Word16 nb_subfr
|
||||
)
|
||||
{
|
||||
Word16 mode_index;
|
||||
Word16 band_index;
|
||||
Word16 i;
|
||||
Word16 remaining_bits, bits;
|
||||
|
||||
|
||||
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
mode_index = pConfigAcelp->mode_index;
|
||||
band_index = (narrowBand==0);
|
||||
bits=0;
|
||||
|
||||
IF ( band_index==0 )
|
||||
{
|
||||
move16();
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
if(sub(coder_type,INACTIVE) == 0)
|
||||
{
|
||||
move16();
|
||||
pConfigAcelp->formant_enh = 0;
|
||||
}
|
||||
}
|
||||
|
||||
IF ( s_and(sub(band_index,1)==0, sub(nb_subfr,4)==0) )
|
||||
{
|
||||
IF(sub(coder_type,INACTIVE) == 0)
|
||||
{
|
||||
pConfigAcelp->pre_emphasis = 0;
|
||||
move16();
|
||||
pConfigAcelp->formant_enh = 0;
|
||||
move16();
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
||||
move16();
|
||||
pConfigAcelp->voice_tilt = 1;
|
||||
move16();
|
||||
pConfigAcelp->formant_tilt = 1;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
pConfigAcelp->pre_emphasis = 1;
|
||||
move16();
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
move16();
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
move16();
|
||||
pConfigAcelp->voice_tilt = 0;
|
||||
move16();
|
||||
pConfigAcelp->formant_tilt = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
IF (sub(coder_type,UNVOICED) == 0 )
|
||||
{
|
||||
IF(sub(ACELP_GAINS_MODE[mode_index][band_index][coder_type], 6) == 0)
|
||||
{
|
||||
pConfigAcelp->pitch_sharpening = 0;
|
||||
move16();
|
||||
pConfigAcelp->phase_scrambling = 1;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
pConfigAcelp->pitch_sharpening = 0;
|
||||
move16();
|
||||
pConfigAcelp->phase_scrambling = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
pConfigAcelp->pitch_sharpening = 1;
|
||||
move16();
|
||||
pConfigAcelp->phase_scrambling = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
IF(sub(coder_type,ACELP_MODE_MAX) > 0) /* keep pitch sharpening for RF_ALLPRED mode */
|
||||
{
|
||||
pConfigAcelp->pitch_sharpening = 0;
|
||||
pConfigAcelp->phase_scrambling = 0;
|
||||
}
|
||||
|
||||
/*Allocate bits and different modes*/
|
||||
move16();
|
||||
pConfigAcelp->bpf_mode=ACELP_BPF_MODE[mode_index][band_index][coder_type];
|
||||
bits = add(bits, ACELP_BPF_BITS[pConfigAcelp->bpf_mode]);
|
||||
|
||||
move16();
|
||||
move16();
|
||||
pConfigAcelp->nrg_mode=ACELP_NRG_MODE[mode_index][band_index][coder_type];
|
||||
pConfigAcelp->nrg_bits=ACELP_NRG_BITS[pConfigAcelp->nrg_mode];
|
||||
bits = add(bits, pConfigAcelp->nrg_bits);
|
||||
|
||||
move16();
|
||||
pConfigAcelp->ltp_mode=ACELP_LTP_MODE[mode_index][band_index][coder_type];
|
||||
|
||||
move16();
|
||||
pConfigAcelp->ltp_bits=0;
|
||||
|
||||
move16();
|
||||
pConfigAcelp->ltf_mode=ACELP_LTF_MODE[mode_index][band_index][coder_type];
|
||||
|
||||
move16();
|
||||
pConfigAcelp->ltf_bits=ACELP_LTF_BITS[pConfigAcelp->ltf_mode];
|
||||
if ( s_and(sub(nb_subfr,5)==0, sub(pConfigAcelp->ltf_bits,4)==0) )
|
||||
{
|
||||
pConfigAcelp->ltf_bits = add(pConfigAcelp->ltf_bits,1);
|
||||
}
|
||||
bits = add(bits,pConfigAcelp->ltf_bits);
|
||||
|
||||
|
||||
FOR ( i=0; i<nb_subfr; i++ )
|
||||
{
|
||||
pConfigAcelp->gains_mode[i] = ACELP_GAINS_MODE[mode_index][band_index][coder_type];
|
||||
move16();
|
||||
|
||||
/* skip subframe 1, 3 gain encoding, and use from subframe 0, and 3, respectively */
|
||||
test();
|
||||
test();
|
||||
IF(sub(coder_type,ACELP_MODE_MAX) >= 0 && (sub(i,1) == 0 || sub(i,3) == 0))
|
||||
{
|
||||
pConfigAcelp->gains_mode[i] = 0;
|
||||
}
|
||||
|
||||
bits = add(bits, ACELP_GAINS_BITS[pConfigAcelp->gains_mode[i]]);
|
||||
|
||||
move16();
|
||||
bits = add(bits, ACELP_LTP_BITS_SFR[pConfigAcelp->ltp_mode][i]);
|
||||
pConfigAcelp->ltp_bits= add( pConfigAcelp->ltp_bits,ACELP_LTP_BITS_SFR[pConfigAcelp->ltp_mode][i]);
|
||||
}
|
||||
|
||||
/*Innovation*/
|
||||
|
||||
if ( sub(bits_frame,bits) < 0)
|
||||
{
|
||||
printf("Warning: bits per frame too low\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
IF( sub(coder_type,RF_ALLPRED) == 0 )
|
||||
{
|
||||
set16_fx(pConfigAcelp->fixed_cdk_index, -1, nb_subfr);
|
||||
}
|
||||
ELSE IF ( sub(coder_type,RF_GENPRED) == 0 )
|
||||
{
|
||||
pConfigAcelp->fixed_cdk_index[0] = 0; /* 7 bits */
|
||||
pConfigAcelp->fixed_cdk_index[1] = -1;
|
||||
pConfigAcelp->fixed_cdk_index[2] = 0; /* 7 bits */
|
||||
pConfigAcelp->fixed_cdk_index[3] = -1;
|
||||
pConfigAcelp->fixed_cdk_index[4] = -1;
|
||||
bits = add(bits,14);
|
||||
}
|
||||
ELSE IF( sub(coder_type,RF_NOPRED) == 0 )
|
||||
{
|
||||
set16_fx(pConfigAcelp->fixed_cdk_index, 0, nb_subfr);
|
||||
bits = add(bits,28);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
bits = add(bits, BITS_ALLOC_adjust_acelp_fixed_cdk(sub(bits_frame,bits), pConfigAcelp->fixed_cdk_index, nb_subfr ));
|
||||
}
|
||||
|
||||
remaining_bits = sub(bits_frame, bits);
|
||||
|
||||
/*Sanity check*/
|
||||
if (remaining_bits<0)
|
||||
{
|
||||
move16();
|
||||
bits = -1;
|
||||
}
|
||||
|
||||
|
||||
return(bits);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
Word16 BITS_ALLOC_adjust_generic(
|
||||
const Word16 bits_frame, /*i: bit budget*/
|
||||
Word16 *fixed_cdk_index,
|
||||
const Word16 nb_subfr,
|
||||
const Word16 *pulseconfigbits,
|
||||
const Word16 pulseconfig_size
|
||||
)
|
||||
{
|
||||
Word16 bits_subframe2, inb_subfr;
|
||||
Word16 sfr, k, bitsused, bits_currsubframe;
|
||||
|
||||
bits_subframe2 = bits_frame;
|
||||
move16();
|
||||
inb_subfr = 8192/*1.0f/NB_SUBFR Q15*/;
|
||||
move16();
|
||||
if ( sub(nb_subfr,NB_SUBFR16k) == 0 )
|
||||
{
|
||||
inb_subfr = 6554/*1.0f/NB_SUBFR16k Q15*/;
|
||||
move16();
|
||||
}
|
||||
|
||||
IF ( sub(bits_subframe2, i_mult2(pulseconfigbits[0], nb_subfr)) < 0 ) /* not in final code - not instrumented */
|
||||
{
|
||||
return add(bits_frame,1); /* Not enough bits for lowest mode. -> trigger alarm*/
|
||||
}
|
||||
|
||||
/* search cdk-index for first subframe */
|
||||
FOR (k=0; k<pulseconfig_size-1; k++)
|
||||
{
|
||||
|
||||
IF (i_mult2(pulseconfigbits[k], nb_subfr) > bits_subframe2)
|
||||
{
|
||||
k = sub(k,1); /* previous mode did not exceed bit-budget */
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_mult2(pulseconfigbits[k], nb_subfr) > bits_subframe2)
|
||||
{
|
||||
k = sub(k,1); /* previous mode did not exceed bit-budget */
|
||||
}
|
||||
|
||||
move16();
|
||||
fixed_cdk_index[0] = k;
|
||||
bitsused = i_mult2(pulseconfigbits[k], nb_subfr);
|
||||
|
||||
FOR (sfr=1; sfr < nb_subfr; sfr++)
|
||||
{
|
||||
/*bits_currsubframe = (int)(((float)sfr+1.0f)*bits_subframe) - bitsused;*/
|
||||
bits_currsubframe = sub(add(i_mult2(sfr, bits_subframe2), bits_subframe2), bitsused);
|
||||
|
||||
/* try increasing mode while below threshold */
|
||||
WHILE ( (sub(k, pulseconfig_size-1) < 0) && (sub(i_mult2(pulseconfigbits[add(k,1)], nb_subfr),bits_currsubframe) <= 0) )
|
||||
{
|
||||
test();
|
||||
k = add(k,1);
|
||||
}
|
||||
|
||||
/* try decreasing mode until below threshold */
|
||||
WHILE (i_mult2(pulseconfigbits[k], nb_subfr) > bits_currsubframe)
|
||||
{
|
||||
k = sub(k,1);
|
||||
|
||||
IF (k == 0)
|
||||
{
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
/* store mode */
|
||||
move16();
|
||||
fixed_cdk_index[sfr] = k;
|
||||
bitsused = add(bitsused, i_mult2(pulseconfigbits[k], nb_subfr));
|
||||
}
|
||||
|
||||
return mult_r(bitsused, inb_subfr);
|
||||
}
|
||||
|
||||
Word16 BITS_ALLOC_adjust_acelp_fixed_cdk(
|
||||
const Word16 bits_frame, /*i: bit budget*/
|
||||
Word16 *fixed_cdk_index,
|
||||
const Word16 nb_subfr
|
||||
)
|
||||
{
|
||||
Word16 bitsused;
|
||||
|
||||
|
||||
bitsused = BITS_ALLOC_adjust_generic(bits_frame, fixed_cdk_index, nb_subfr, ACELP_CDK_BITS, ACELP_FIXED_CDK_NB);
|
||||
|
||||
|
||||
return bitsused;
|
||||
}
|
||||
|
||||
Executable
+2445
File diff suppressed because it is too large
Load Diff
Executable
+134
@@ -0,0 +1,134 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* */
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
/*
|
||||
* E_GAIN_f_pitch_sharpening
|
||||
*
|
||||
* Parameters:
|
||||
* x I/O: impulse response (or algebraic code)
|
||||
* pit_lag I: pitch lag
|
||||
*
|
||||
* Function:
|
||||
* Performs Pitch sharpening routine for one subframe.
|
||||
* pitch sharpening factor is 0.85
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
static void E_GAIN_f_pitch_sharpening(Word16 *x, Word16 pit_lag, Word16 L_subfr)
|
||||
{
|
||||
Word16 i, tmp;
|
||||
|
||||
FOR (i = pit_lag; i < L_subfr; i++)
|
||||
{
|
||||
/*x[i] += x[i - pit_lag] * F_PIT_SHARP;*/
|
||||
tmp = mult_r(x[i - pit_lag], 27853/*F_PIT_SHARP Q15*/);
|
||||
x[i] = add(x[i],tmp);
|
||||
move16();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* cb_shape()
|
||||
*
|
||||
* pre-emphasis, pitch sharpening and formant sharpening of the algebraic codebook
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void cb_shape_fx(
|
||||
const Word16 preemphFlag, /* i : flag for pre-emphasis */
|
||||
const Word16 pitchFlag, /* i : flag for pitch sharpening */
|
||||
const Word16 scramblingFlag, /* i : flag for phase scrambling */
|
||||
const Word16 sharpFlag, /* i : flag for formant sharpening */
|
||||
const Word16 formantTiltFlag, /* i : flag for formant tilt */
|
||||
const Word16 g1, /* i : formant sharpening numerator weighting */
|
||||
const Word16 g2, /* i : formant sharpening denominator weighting */
|
||||
const Word16 *p_Aq, /* i : LP filter coefficients */
|
||||
Word16 *code, /* i/o: signal to shape */
|
||||
const Word16 tilt_code, /* i : tilt of code */
|
||||
const Word16 pt_pitch, /* i : pointer to current subframe fractional pitch */
|
||||
const Word16 shift
|
||||
)
|
||||
{
|
||||
Word16 tmp, buff[L_SUBFR+M], A_num[M+1], A_den[M+1];
|
||||
Word16 i;
|
||||
Word32 L_tmp;
|
||||
Word16 tilt, mu;
|
||||
tmp = 0;
|
||||
move16();
|
||||
|
||||
/* Pre-emphasis */
|
||||
IF( preemphFlag )
|
||||
{
|
||||
preemph_copy_fx(code, code, tilt_code, L_SUBFR, &tmp);
|
||||
}
|
||||
|
||||
/* pitch sharpening */
|
||||
IF( pitchFlag )
|
||||
{
|
||||
E_GAIN_f_pitch_sharpening( code, pt_pitch, L_SUBFR );
|
||||
}
|
||||
|
||||
/* phase scrambling filter */
|
||||
IF( scramblingFlag )
|
||||
{
|
||||
buff[0] = code[0];
|
||||
move16();
|
||||
FOR (i = 1; i < L_SUBFR; i++)
|
||||
{
|
||||
buff[i]=code[i];
|
||||
move16();
|
||||
/*code[i] = 0.7f*buff[i] + buff[i-1] - 0.7f*code[i-1]; */
|
||||
L_tmp = L_mult(22938, buff[i]);
|
||||
tmp = mac_r(L_tmp,-22938, code[i-1]);
|
||||
code[i] = add(tmp,buff[i-1]);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
||||
IF ( sharpFlag || formantTiltFlag )
|
||||
{
|
||||
weight_a_fx( p_Aq, A_num, g1, M );
|
||||
weight_a_fx( p_Aq, A_den, g2, M );
|
||||
set16_fx(buff, 0, M+L_SUBFR);
|
||||
IF( formantTiltFlag )
|
||||
{
|
||||
Copy(A_num, buff+M, M+1);
|
||||
|
||||
E_UTIL_synthesis(1, A_den, buff+M, buff+M, L_SUBFR, buff, 0, M);
|
||||
|
||||
/*Compute tilt of formant enhancement*/
|
||||
tilt = extract_l(L_shr(get_gain(buff+M+1, buff+M, L_SUBFR-1),1));
|
||||
|
||||
/*Combine tilt of code and fe*/
|
||||
tmp = 0;
|
||||
move16();
|
||||
/*mu = 0.5f*tilt_code-0.25f*tilt;*/
|
||||
mu = sub(shr(tilt_code,1),shr(tilt,2));
|
||||
preemph_copy_fx(code, code, mu, L_SUBFR, &tmp);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Copy( code, buff, L_SUBFR );
|
||||
|
||||
Overflow = 0;
|
||||
move16();
|
||||
Residu3_lc_fx(A_num, M, buff, code, L_SUBFR, shift);
|
||||
{
|
||||
syn_filt_s_lc_fx(shift, A_den, code, code, L_SUBFR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Executable
+1701
File diff suppressed because it is too large
Load Diff
Executable
+889
@@ -0,0 +1,889 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
#include "rom_com_fx.h"
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*---------------------------------------------------------------------*/
|
||||
#define A2 6554
|
||||
#define OmA2 (32768-A2)
|
||||
#define GAIN_VAR 11811 /* in Q31 divided by 2 (Q30) */
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* CNG_exc()
|
||||
*
|
||||
* Comfort noise generation routine
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
void CNG_exc_fx(
|
||||
const Word32 core_brate, /* i : core bitrate */
|
||||
const Word16 L_frame, /* i : length of the frame */
|
||||
Word32 *Enew, /* i/o: decoded SID energy Q6 */
|
||||
Word16 *seed, /* i/o: random generator seed */
|
||||
Word16 exc[], /* o : current non-enhanced excitation Q_new */
|
||||
Word16 exc2[], /* o : current enhanced excitation Q_new */
|
||||
Word32 *lp_ener, /* i/o: LP filtered E */
|
||||
const Word32 last_core_brate, /* i : previous frame core bitrate */
|
||||
Word16 *first_CNG, /* i/o: first CNG frame flag for energy init. */
|
||||
Word16 *cng_ener_seed, /* i/o: random generator seed for CNG energy */
|
||||
Word16 bwe_exc[], /* o : excitation for SWB TBE */
|
||||
const Word16 allow_cn_step, /* i : allow CN step */
|
||||
Word16 *last_allow_cn_step, /* i/o: last allow step */
|
||||
const Word16 OldQ_exc, /* i : Old excitation scaling */
|
||||
const Word16 Q_exc /* i : excitation scaling */
|
||||
, const Word16 num_ho /* i : number of selected hangover frames */
|
||||
,Word32 q_env[]
|
||||
,Word32 *lp_env
|
||||
,Word32 *old_env
|
||||
,Word16 *exc_mem
|
||||
,Word16 *exc_mem1
|
||||
,Word16 *sid_bw
|
||||
,Word16 *cng_ener_seed1
|
||||
,Word16 exc3[]
|
||||
,Word16 Opt_AMR_WB
|
||||
)
|
||||
{
|
||||
Word16 i, tmp, tmp2, exp, exp2, Q_ener;
|
||||
Word32 L_tmp_ener, L_tmp;
|
||||
Word16 i_subfr;
|
||||
Word16 pit_max;
|
||||
Word16 ftmp,j;
|
||||
Word16 *ptR,*ptI;
|
||||
Word16 fft_io[L_FRAME16k];
|
||||
Word32 itmp[129];
|
||||
Word32 env[NUM_ENV_CNG];
|
||||
Word32 enr1;
|
||||
Word32 denv[NUM_ENV_CNG];
|
||||
Word16 fra;
|
||||
Word16 temp_lo_fx, temp_hi_fx;
|
||||
Word16 exp_pow;
|
||||
Word32 L_tmp2;
|
||||
Word16 *pt_fft_io;
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Initializations
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
pit_max = PIT16k_MAX;
|
||||
move16();
|
||||
if( sub(L_frame,L_FRAME) == 0 )
|
||||
{
|
||||
pit_max = PIT_MAX;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Initialization of CNG energy for the first CNG frame
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
IF(*first_CNG == 0 )
|
||||
{
|
||||
IF(L_sub(core_brate,FRAME_NO_DATA) == 0 )
|
||||
{
|
||||
/* needed only in decoder when the very first SID frame was erased and this frame is FRAME_NO_DATA frame */
|
||||
/*fenew = dotp( fexc, fexc, pit_max )/pit_max;*/
|
||||
L_tmp_ener = Calc_Energy_Autoscaled(exc-pit_max, OldQ_exc, pit_max, &Q_ener);
|
||||
L_tmp_ener = Mult_32_16(L_tmp_ener, 9079); /* divide by PIT_MAX (in Q15 + Q6 to get output in Q6)*/
|
||||
L_tmp_ener = L_shr(L_tmp_ener, Q_ener); /* -> If we want ener in Q6 */
|
||||
|
||||
if(sub(L_frame, L_FRAME16k) == 0)
|
||||
{
|
||||
L_tmp_ener = Mult_32_16(L_tmp_ener, 26214); /* Compensate for 16kHz */
|
||||
}
|
||||
*Enew = L_tmp_ener;
|
||||
move32();
|
||||
}
|
||||
|
||||
*lp_ener = *Enew;
|
||||
move32();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Update CNG energy
|
||||
*---------------------------------------------------------------------*/
|
||||
test();
|
||||
test();
|
||||
IF( L_sub(last_core_brate,SID_1k75) != 0 && L_sub(last_core_brate,FRAME_NO_DATA) != 0 && L_sub(last_core_brate,SID_2k40) != 0 )
|
||||
{
|
||||
/* Partially reset CNG energy after active speech period */
|
||||
test();
|
||||
IF ( allow_cn_step == 0 && *last_allow_cn_step == 0 )
|
||||
{
|
||||
test();
|
||||
IF( sub(num_ho,3) < 0 || L_sub(Mult_32_16(*Enew,21845 /*1/1.5f, Q15*/), *lp_ener) < 0 )
|
||||
{
|
||||
/**lp_ener = 0.8f * *lp_ener + 0.2f * *Enew;*/
|
||||
L_tmp_ener = Mult_32_16(*lp_ener, 26214);
|
||||
L_tmp_ener = Madd_32_16(L_tmp_ener, *Enew, 6554);
|
||||
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/**lp_ener = 0.95f * *lp_ener + 0.05f * *Enew;*/
|
||||
L_tmp_ener = Mult_32_16(*lp_ener, 31130);
|
||||
L_tmp_ener = Madd_32_16(L_tmp_ener, *Enew, 1638);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_tmp_ener = L_add(0,*Enew);
|
||||
*last_allow_cn_step = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* normal CNG update */
|
||||
IF ( *last_allow_cn_step == 0 )
|
||||
{
|
||||
/**lp_ener = (float)(A2 * *Enew + (1-A2) * *lp_ener);*/
|
||||
L_tmp_ener = Mult_32_16(*Enew, A2);
|
||||
L_tmp_ener = Madd_32_16(L_tmp_ener, *lp_ener, OmA2);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
test();
|
||||
if ( L_sub(core_brate,SID_1k75) == 0 || L_sub(core_brate,SID_2k40) == 0 )
|
||||
{
|
||||
*last_allow_cn_step = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
L_tmp_ener = *Enew;
|
||||
move32();
|
||||
|
||||
}
|
||||
}
|
||||
*lp_ener = L_max(L_tmp_ener,1);
|
||||
move32(); /*To avoid / per 0*/
|
||||
|
||||
if ( sub(allow_cn_step,1) == 0)
|
||||
{
|
||||
*last_allow_cn_step = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Generate white noise vector
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
/*for ( i=0; i<L_frame; i++ )exc2[i] = (float)own_random( seed );*/
|
||||
Random_Fill(seed, L_frame, exc2, 4);
|
||||
/*------------------------------------------------------------*
|
||||
* Insert random variation for excitation energy
|
||||
* (random variation is scaled according to *lp_ener value)
|
||||
*------------------------------------------------------------*/
|
||||
|
||||
FOR ( i_subfr=0; i_subfr<L_frame; i_subfr += L_SUBFR )
|
||||
{
|
||||
/* ener_lp = own_random(cng_ener_seed) * *lp_ener * GAIN_VAR + *lp_ener */
|
||||
/*------------------------------------------------------------*
|
||||
* Insert random variation for excitation energy
|
||||
* (random variation is scaled according to *lp_ener value)
|
||||
*------------------------------------------------------------*/
|
||||
L_tmp = Mult_32_16(*lp_ener, Random(cng_ener_seed));
|
||||
L_tmp = Mult_32_16(L_tmp, GAIN_VAR);
|
||||
L_tmp = L_add(L_tmp, *lp_ener);
|
||||
L_tmp = L_max(L_tmp, 1);
|
||||
|
||||
/* enr = dot_product( exc2, exc2, L_SUBFR ) + 0.01f */
|
||||
tmp = extract_h(Dot_product12(&exc2[i_subfr], &exc2[i_subfr], L_SUBFR, &exp));
|
||||
exp = add(exp, 8-6); /* 8 from Q-4, -6 from L_SUBFR */
|
||||
|
||||
/* enr = (float)sqrt(*lp_ener * L_SUBFR / enr) */
|
||||
exp2 = norm_l(L_tmp);
|
||||
tmp2 = extract_h(L_shl(L_tmp, exp2));
|
||||
exp2 = sub(31-6, exp2); /* in Q15 (L_tmp in Q6)*/
|
||||
|
||||
exp = sub(exp, exp2);
|
||||
|
||||
if (sub(tmp, tmp2) > 0)
|
||||
{
|
||||
exp = add(exp, 1);
|
||||
}
|
||||
if (sub(tmp, tmp2) > 0)
|
||||
{
|
||||
tmp = shr(tmp, 1);
|
||||
}
|
||||
tmp = div_s(tmp, tmp2);
|
||||
|
||||
L_tmp = L_deposit_h(tmp);
|
||||
|
||||
L_tmp = Isqrt_lc(L_tmp, &exp);
|
||||
tmp = extract_h(L_tmp);
|
||||
|
||||
exp = add(exp, 4); /* From Q15 to Q19 */
|
||||
exp = add(exp, Q_exc); /* Q_exc+ Q19 */
|
||||
|
||||
FOR (i=0; i<L_SUBFR; i++)
|
||||
{
|
||||
/* exc2[i] *= enr */
|
||||
L_tmp = L_mult(exc2[i_subfr+i], tmp); /* Q-4 * Q_exc+19 -> Q_exc +16 */
|
||||
exc2[i_subfr+i] = round_fx(L_shl(L_tmp, exp));
|
||||
}
|
||||
}
|
||||
IF ( sub(Opt_AMR_WB,1) != 0 )
|
||||
{
|
||||
Copy( exc2, exc3, L_FRAME16k);
|
||||
|
||||
/* enr1 = (float)log10( *Enew*L_frame + 0.1f ) / (float)log10( 2.0f ); */
|
||||
exp = norm_l(*Enew);
|
||||
L_tmp = L_shl(*Enew,exp); /* Q(exp+6) */
|
||||
L_tmp = Mult_32_16(L_tmp,shl(L_frame,5)); /* Q(exp+6+5-15=exp-4) */
|
||||
L_tmp = L_shr(L_tmp,sub(exp,10)); /* Q6 */
|
||||
|
||||
exp = norm_l(L_tmp);
|
||||
fra = Log2_norm_lc(L_shl(L_tmp,exp));
|
||||
exp = sub(sub(30,exp),6);
|
||||
L_tmp = L_Comp(exp,fra);
|
||||
/* enr1 = round_fx(L_shl(L_tmp,8)); */ /*Q8 */
|
||||
enr1 = L_shr(L_tmp,10);/* Q6 */
|
||||
|
||||
|
||||
IF ( L_sub(core_brate,SID_2k40) == 0 )
|
||||
{
|
||||
IF ( *sid_bw == 0 )
|
||||
{
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* get quantized envelope */
|
||||
/* env[i] = pow(2.0f,(enr1 - q_env[i])); */
|
||||
L_tmp = L_sub(enr1,q_env[i]);/* Q6 */
|
||||
L_tmp = L_shl(L_tmp, 10);/* 16 */
|
||||
temp_lo_fx = L_Extract_lc(L_tmp, &temp_hi_fx);
|
||||
|
||||
exp_pow = sub(14, temp_hi_fx);
|
||||
L_tmp = Pow2(14, temp_lo_fx); /* Qexp_pow */
|
||||
env[i] = L_shl(L_tmp, sub(6, exp_pow));
|
||||
move32();/* Q6 */
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize CNG envelope */
|
||||
test();
|
||||
IF( *first_CNG == 0 && *sid_bw == 0 )
|
||||
{
|
||||
Copy32(env, lp_env, NUM_ENV_CNG);
|
||||
}
|
||||
|
||||
IF ( *sid_bw == 0 )
|
||||
{
|
||||
Copy32(env, old_env, NUM_ENV_CNG);
|
||||
}
|
||||
}
|
||||
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* get AR low-passed envelope */
|
||||
/* lp_env[i] = 0.9f*lp_env[i] + (1-0.9f)*old_env[i]; */
|
||||
L_tmp = Mult_32_16(lp_env[i],29491);
|
||||
lp_env[i] = L_add(L_tmp,Mult_32_16(old_env[i],3277));
|
||||
move32();/* Q6 */
|
||||
}
|
||||
|
||||
/* calculate the spectrum of random excitation signal */
|
||||
Copy(exc2, fft_io, L_frame);
|
||||
|
||||
IF ( sub(L_frame,L_FRAME16k) == 0 )
|
||||
{
|
||||
modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, exc_mem1, 0 );
|
||||
}
|
||||
|
||||
/* fft_rel(fft_io, L_FFT, LOG2_L_FFT); */
|
||||
fft_rel_fx(fft_io, L_FFT, LOG2_L_FFT);/* ??????? */
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[sub(L_FFT,1)];
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
|
||||
L_tmp = L_mult0(*ptR,*ptR);/* 2*Q_exc */
|
||||
L_tmp = L_mac0(L_tmp,*ptI,*ptI);/* 2*Q_exc */
|
||||
L_tmp = L_shr(L_tmp,1);/* 2*Q_exc+6 */
|
||||
tmp = add(Q_exc,Q_exc);
|
||||
env[i] = L_shr(L_tmp,tmp);
|
||||
move32();/* Q6 */
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* denv[i] = lp_env[i] + 2*(*lp_ener) - env[i]; */
|
||||
L_tmp = L_add(*lp_ener,*lp_ener);
|
||||
denv[i] = L_sub(L_add(lp_env[i],L_tmp),env[i]);
|
||||
move32();/* Q6 */
|
||||
|
||||
if ( denv[i] < 0 )
|
||||
{
|
||||
denv[i] = L_deposit_l(0);
|
||||
}
|
||||
}
|
||||
set32_fx(itmp, 0, NUM_ENV_CNG);
|
||||
|
||||
set16_fx(fft_io, 0, L_FFT);
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[sub(L_FFT,1)];
|
||||
FOR (i=0; i<NUM_ENV_CNG; i++)
|
||||
{
|
||||
/* *ptR = own_random( cng_ener_seed1 ); */
|
||||
/* *ptI = own_random( cng_ener_seed1 ); */
|
||||
*ptR = Random( cng_ener_seed1 );
|
||||
*ptI = Random( cng_ener_seed1 );
|
||||
|
||||
/* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
|
||||
L_tmp = L_mult0(*ptR,*ptR);/* Q0 */
|
||||
L_tmp = L_mac0(L_tmp,*ptI,*ptI);/* Q0 */
|
||||
env[i] = L_shr(L_tmp,1);
|
||||
move32(); /* Q6 */
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* itmp[i] += own_random( cng_ener_seed1 )*denv[i]*0.000011f + denv[i]; */
|
||||
L_tmp = Mult_32_16(denv[i], Random(cng_ener_seed1));
|
||||
L_tmp = Mult_32_16(L_tmp, GAIN_VAR);
|
||||
L_tmp = L_add(L_tmp, denv[i]);
|
||||
itmp[i] = L_add(L_tmp, itmp[i]);
|
||||
move32();/* Q6 */
|
||||
|
||||
if (itmp[i] < 0)
|
||||
{
|
||||
itmp[i] = L_deposit_l(0);
|
||||
}
|
||||
}
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[sub(L_FFT,1)];
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* *ptR *= sqrt(itmp[i]/env[i]); */
|
||||
/* *ptI *= sqrt(itmp[i]/env[i]); */
|
||||
L_tmp = L_max(1, itmp[i]); /*Q6*/
|
||||
exp = norm_l(L_tmp);
|
||||
tmp = extract_h(L_shl(L_tmp, exp));
|
||||
exp = sub(31-6, exp); /* in Q15 (L_tmp in Q6)*/
|
||||
|
||||
exp2 = norm_l(env[i]);
|
||||
tmp2 = extract_h(L_shl(env[i], exp2));
|
||||
exp2 = sub(31-6, exp2); /* in Q15 (L_tmp in Q6)*/
|
||||
|
||||
exp = sub(exp2, exp); /* Denormalize and substract */
|
||||
if (sub(tmp2, tmp) > 0)
|
||||
{
|
||||
exp = add(exp, 1);
|
||||
}
|
||||
if (sub(tmp2, tmp) > 0)
|
||||
{
|
||||
tmp2 = shr(tmp2, 1);
|
||||
}
|
||||
tmp = div_s(tmp2, tmp);
|
||||
L_tmp = L_deposit_h(tmp);
|
||||
L_tmp = Isqrt_lc(L_tmp, &exp); /*Q(31-exp)*/
|
||||
|
||||
L_tmp2 = Mult_32_16(L_tmp,*ptR);/*Q(16-exp)*/
|
||||
*ptR = extract_h(L_shl(L_tmp2,add(exp,Q_exc))); /*Q_exc*/
|
||||
L_tmp2 = Mult_32_16(L_tmp,*ptI);/*Q(16-exp)*/
|
||||
*ptI = extract_h(L_shl(L_tmp2,add(exp,Q_exc))); /*Q_exc*/
|
||||
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
ifft_rel_fx(fft_io, L_FFT, LOG2_L_FFT);
|
||||
|
||||
IF ( sub(L_frame,L_FRAME16k) == 0 )
|
||||
{
|
||||
modify_Fs_fx( fft_io, L_FFT, 12800, fft_io, 16000, exc_mem, 0 );
|
||||
}
|
||||
|
||||
/* enr1 = dotp( fft_io, fft_io, L_frame ) / L_frame; */
|
||||
|
||||
enr1 = L_deposit_l(1);
|
||||
pt_fft_io = fft_io;
|
||||
IF( sub(L_frame, L_FRAME) == 0)
|
||||
{
|
||||
FOR (j=0; j<128; j++)
|
||||
{
|
||||
L_tmp = L_mult0(*pt_fft_io, *pt_fft_io);
|
||||
pt_fft_io++;
|
||||
L_tmp = L_mac0(L_tmp, *pt_fft_io, *pt_fft_io); /* 2*(Q_exc) */
|
||||
pt_fft_io++;
|
||||
enr1 = L_add(enr1, L_shr(L_tmp, 7)); /* 2*(Q_exc)+1, divide by L_frame done here */
|
||||
}
|
||||
}
|
||||
ELSE /* L_FRAME16k */
|
||||
{
|
||||
FOR (j=0; j<160; j++)
|
||||
{
|
||||
L_tmp = L_mult0(*pt_fft_io, *pt_fft_io);
|
||||
pt_fft_io++;
|
||||
L_tmp = L_mac0(L_tmp, *pt_fft_io, *pt_fft_io); /* 2*(Q_exc) */
|
||||
pt_fft_io++;
|
||||
enr1 = L_add(enr1, L_shr(Mult_32_16(L_tmp,26214 /* 256/320, Q15 */), 7)); /* 2*(Q_exc)+15+1-16+1, divide by L_frame done here */
|
||||
}
|
||||
}
|
||||
enr1 = L_shr(enr1,sub(add(Q_exc,Q_exc),5));/*Q6*/
|
||||
|
||||
/* add time domain randomization */
|
||||
FOR ( i_subfr=0; i_subfr<L_frame; i_subfr += L_SUBFR )
|
||||
{
|
||||
|
||||
L_tmp = Mult_32_16(enr1, Random(cng_ener_seed1));
|
||||
L_tmp = Mult_32_16(L_tmp, GAIN_VAR);
|
||||
L_tmp = L_add(L_tmp, enr1);
|
||||
L_tmp = L_max(L_tmp, 1);
|
||||
|
||||
/* enr = dot_product( fft_io, fft_io, L_SUBFR ) + 0.01f */
|
||||
tmp = extract_h(Dot_product12(&fft_io[i_subfr], &fft_io[i_subfr], L_SUBFR, &exp));
|
||||
exp = add(exp, sub(-6, add(Q_exc, Q_exc))); /* -2*Q_exc from fft_io, -6 from L_SUBFR */
|
||||
|
||||
/* enr = (float)sqrt( ener_lp*L_SUBFR / enr ) */
|
||||
exp2 = norm_l(L_tmp);
|
||||
tmp2 = extract_h(L_shl(L_tmp, exp2));
|
||||
exp2 = sub(31-6, exp2); /* in Q15 (L_tmp in Q6)*/
|
||||
|
||||
exp = sub(exp, exp2);
|
||||
|
||||
if (sub(tmp, tmp2) > 0)
|
||||
{
|
||||
exp = add(exp, 1);
|
||||
}
|
||||
if (sub(tmp, tmp2) > 0)
|
||||
{
|
||||
tmp = shr(tmp, 1);
|
||||
}
|
||||
tmp = div_s(tmp, tmp2);
|
||||
|
||||
L_tmp = L_deposit_h(tmp);
|
||||
L_tmp = Isqrt_lc(L_tmp, &exp);/*Q(31-exp)*/
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF( L_sub(last_core_brate,SID_2k40) != 0 && L_sub(last_core_brate,SID_1k75) != 0 && L_sub(last_core_brate,FRAME_NO_DATA) != 0 && L_sub(core_brate,SID_2k40) == 0 )
|
||||
{
|
||||
IF ( L_sub(L_tmp,L_shl(1,sub(31,exp))) > 0 )
|
||||
{
|
||||
L_tmp = L_shl(1,sub(31,exp));
|
||||
}
|
||||
}
|
||||
|
||||
tmp = extract_h(L_tmp);
|
||||
FOR (i=0; i<L_SUBFR; i++)
|
||||
{
|
||||
/* fft_io[i] *= enr */
|
||||
L_tmp = L_mult(fft_io[i_subfr+i], tmp); /* Q_exc + 16 - exp */
|
||||
fft_io[i_subfr+i] = round_fx(L_shl(L_tmp, exp));/*Q_exc*/
|
||||
}
|
||||
}
|
||||
|
||||
FOR ( i=0; i<L_frame; i++ )
|
||||
{
|
||||
/* fft_io[i] = 0.75f*fft_io[i] + exc2[i];*/
|
||||
tmp = mult(fft_io[i],24576);
|
||||
fft_io[i] = add(tmp,exc2[i]);
|
||||
move16();/*Q_exc*/
|
||||
}
|
||||
|
||||
/* enr = (dotp( fft_io, fft_io, L_frame ) / L_frame) + 0.01f */
|
||||
|
||||
L_tmp2 = L_deposit_l(1);
|
||||
pt_fft_io = fft_io;
|
||||
IF( sub(L_frame, L_FRAME) == 0)
|
||||
{
|
||||
FOR (j=0; j<128; j++)
|
||||
{
|
||||
L_tmp = L_mult0(*pt_fft_io, *pt_fft_io);
|
||||
pt_fft_io++;
|
||||
L_tmp = L_mac0(L_tmp, *pt_fft_io, *pt_fft_io); /* 2*(Q_exc) */
|
||||
pt_fft_io++;
|
||||
L_tmp2 = L_add(L_tmp2, L_shr(L_tmp, 7)); /* 2*(Q_exc)+1, divide by L_frame done here */
|
||||
}
|
||||
}
|
||||
ELSE /* L_FRAME16k */
|
||||
{
|
||||
FOR (j=0; j<160; j++)
|
||||
{
|
||||
L_tmp = L_mult0(*pt_fft_io, *pt_fft_io);
|
||||
pt_fft_io++;
|
||||
L_tmp = L_mac0(L_tmp, *pt_fft_io, *pt_fft_io); /* 2*(Q_exc) */
|
||||
pt_fft_io++;
|
||||
L_tmp2 = L_add(L_tmp2, L_shr(Mult_32_16(L_tmp,26214 /* 256/320, Q15 */), 7)); /* 2*(Q_exc)+15+1-16+1, divide by L_frame done here */
|
||||
}
|
||||
}
|
||||
L_tmp2 = L_shr(L_tmp2,sub(add(Q_exc,Q_exc),5));/*Q6*/
|
||||
|
||||
|
||||
/* enr = (*lp_ener)/enr; */
|
||||
/* ftmp = sqrt(enr); */
|
||||
L_tmp = L_max(1, *lp_ener); /*Q6*/
|
||||
exp = norm_l(L_tmp);
|
||||
tmp = extract_h(L_shl(L_tmp, exp));
|
||||
exp = sub(31-6, exp); /* in Q15 (L_tmp in Q6)*/
|
||||
|
||||
exp2 = norm_l(L_tmp2);
|
||||
tmp2 = extract_h(L_shl(L_tmp2, exp2));
|
||||
exp2 = sub(31-6, exp2); /* in Q15 (L_tmp in Q6)*/
|
||||
|
||||
exp = sub(exp2, exp); /* Denormalize and substract */
|
||||
if (sub(tmp2, tmp) > 0)
|
||||
{
|
||||
exp = add(exp, 1);
|
||||
}
|
||||
if (sub(tmp2, tmp) > 0)
|
||||
{
|
||||
tmp2 = shr(tmp2, 1);
|
||||
}
|
||||
tmp = div_s(tmp2, tmp);
|
||||
L_tmp = L_deposit_h(tmp);
|
||||
L_tmp = Isqrt_lc(L_tmp, &exp); /*Q(31-exp)*/
|
||||
|
||||
ftmp = extract_h(L_shl(L_tmp,exp));/* Q15 */
|
||||
FOR (i=0; i<L_frame; i++)
|
||||
{
|
||||
/* fft_io[i] *= ftmp;*/
|
||||
fft_io[i] = mult(fft_io[i],ftmp);
|
||||
move16();/* Q_exc */
|
||||
}
|
||||
Copy( fft_io, exc2, L_frame );
|
||||
}
|
||||
IF ( sub(Opt_AMR_WB,1) != 0 )
|
||||
{
|
||||
Copy( exc3, exc, L_frame );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Copy( exc2, exc, L_frame );
|
||||
}
|
||||
|
||||
IF( sub(L_frame,L_FRAME) == 0)
|
||||
{
|
||||
interp_code_5over2_fx( exc2, bwe_exc, L_FRAME );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
interp_code_4over2_fx( exc2, bwe_exc, L_frame );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* cng_params_postupd_fx
|
||||
*
|
||||
* Post-update of CNG parameters
|
||||
*-------------------------------------------------------*/
|
||||
void cng_params_postupd_fx(
|
||||
const Word16 ho_circ_ptr, /* i : pointer for CNG averaging buffers Q0 */
|
||||
Word16 *cng_buf_cnt, /* i/o: counter for CNG store buffers Q0 */
|
||||
const Word16 *const cng_exc2_buf, /* i : Excitation buffer Q_exc */
|
||||
const Word16 *const cng_Qexc_buf, /* i : Q_exc buffer Q0 */
|
||||
const Word32 *const cng_brate_buf, /* i : bit rate buffer Q0 */
|
||||
Word32 ho_env_circ[] /* i/o: Envelope buffer */
|
||||
)
|
||||
{
|
||||
Word16 i, j;
|
||||
Word16 Q_exc;
|
||||
const Word16 *exc2;
|
||||
Word16 fft_io[L_FFT];
|
||||
Word32 sp[129];
|
||||
Word16 *ptR,*ptI;
|
||||
Word32 env[NUM_ENV_CNG];
|
||||
Word32 L_tmp;
|
||||
Word16 tmp;
|
||||
Word16 temp_lo_fx, temp_hi_fx;
|
||||
Word16 exp_pow;
|
||||
Word16 exp1;
|
||||
Word16 CNG_mode;
|
||||
Word16 ptr;
|
||||
Word32 last_active_brate;
|
||||
|
||||
ptr = add( sub(ho_circ_ptr, *cng_buf_cnt), 1);
|
||||
if( ptr < 0 )
|
||||
{
|
||||
ptr = add(ptr, HO_HIST_SIZE);
|
||||
}
|
||||
|
||||
FOR( j = 0; j < *cng_buf_cnt; j++ )
|
||||
{
|
||||
exc2 = &cng_exc2_buf[ptr*L_FFT];
|
||||
Q_exc = cng_Qexc_buf[ptr];
|
||||
last_active_brate = cng_brate_buf[ptr];
|
||||
|
||||
/* calculate the spectrum of residual signal */
|
||||
Copy(exc2, fft_io, L_FFT);
|
||||
|
||||
fft_rel_fx(fft_io, L_FFT, LOG2_L_FFT);
|
||||
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[L_FFT-1];
|
||||
FOR (i=0; i<NUM_ENV_CNG; i++)
|
||||
{
|
||||
/* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
|
||||
L_tmp = L_mult(*ptR,*ptR);/* 2*Q_exc+1 */
|
||||
L_tmp = L_add(L_tmp,L_mult(*ptI,*ptI));/* 2*Q_exc+1 */
|
||||
L_tmp = L_add(L_tmp,L_tmp);/* 2*Q_exc+1 */
|
||||
L_tmp = Mult_32_16(L_tmp,128);/* 2*Q_exc+1 */
|
||||
tmp = add(add(Q_exc,Q_exc),1);
|
||||
sp[i] = L_shr(L_tmp,sub(tmp,6));
|
||||
move32();/* Q6 */
|
||||
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
Copy32(sp,env,NUM_ENV_CNG);
|
||||
IF( L_sub(last_active_brate,ACELP_13k20) > 0 )
|
||||
{
|
||||
CNG_mode = 4;
|
||||
}
|
||||
ELSE IF( L_sub(last_active_brate,ACELP_9k60) > 0 )
|
||||
{
|
||||
CNG_mode = 3;
|
||||
}
|
||||
ELSE IF( L_sub(last_active_brate,ACELP_8k00) > 0 )
|
||||
{
|
||||
CNG_mode = 2;
|
||||
}
|
||||
ELSE IF( L_sub(last_active_brate,ACELP_7k20) > 0 )
|
||||
{
|
||||
CNG_mode = 1;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
CNG_mode = 0;
|
||||
}
|
||||
|
||||
/* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
|
||||
L_tmp = L_shl(L_deposit_l(ENR_ATT_fx[CNG_mode]), 8);/* 16 */
|
||||
temp_lo_fx = L_Extract_lc(L_tmp, &temp_hi_fx);
|
||||
|
||||
exp_pow = sub(14, temp_hi_fx);
|
||||
L_tmp = Pow2(14, temp_lo_fx); /* Qexp_pow */
|
||||
L_tmp = L_shl(L_tmp, sub(13, exp_pow)); /* Q13 */
|
||||
tmp = extract_l(L_tmp);/* Q13 */
|
||||
|
||||
exp1 = norm_s(tmp);
|
||||
tmp = shl(tmp, exp1);/*Q(exp1+13) */
|
||||
tmp = div_s(16384,tmp); /*Q(15+14-exp1-13) */
|
||||
tmp = shr(tmp,sub(1,exp1));/* Q15 */
|
||||
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
env[i] = Mult_32_16(env[i],tmp);
|
||||
move32();
|
||||
}
|
||||
|
||||
/* update the circular buffer of old residual envelope */
|
||||
Copy32( env, &(ho_env_circ[(ptr)*NUM_ENV_CNG]), NUM_ENV_CNG );
|
||||
|
||||
ptr = add(ptr, 1);
|
||||
if(sub(ptr, HO_HIST_SIZE) == 0)
|
||||
{
|
||||
ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*cng_buf_cnt = 0;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* cng_params_upd_fx()
|
||||
*
|
||||
* update CNG parameters
|
||||
*-------------------------------------------------------*/
|
||||
void cng_params_upd_fx(
|
||||
const Word16 lsp_new[], /* i : LSP aprameters Q15 */
|
||||
const Word16 exc2[], /* i : current enhanced excitation Q_exc */
|
||||
const Word16 L_frame, /* i : frame length Q0 */
|
||||
Word16 *ho_circ_ptr, /* i/o: pointer for CNG averaging buffers Q0 */
|
||||
Word32 ho_ener_circ[], /* o : energy buffer for CNG averaging Q6 */
|
||||
Word16 *ho_circ_size, /* i/o: size of DTX hangover history buffer for averaging Q0 */
|
||||
Word16 ho_lsp_circ[], /* o : old LSP buffer for CNG averaging Q15 */
|
||||
const Word16 Q_exc, /* i : Q value of excitation */
|
||||
const Word16 enc_dec_flag, /* i : Flag indicating encoder or decoder (ENC,DEC) */
|
||||
Word32 ho_env_circ[], /* i/o: Envelope buffer */
|
||||
Word16 *cng_buf_cnt, /* i/o: Counter of postponed FFT-processing instances */
|
||||
Word16 cng_exc2_buf[], /* i/o: Excitation buffer Q_exc */
|
||||
Word16 cng_Qexc_buf[], /* i/o: Q_exc buffer Q0 */
|
||||
Word32 cng_brate_buf[], /* i/o: last_active_brate buffer Q0 */
|
||||
const Word32 last_active_brate /* i : Last active bit rate Q0 */
|
||||
)
|
||||
{
|
||||
Word32 L_ener, L_tmp;
|
||||
Word16 i, j;
|
||||
const Word16 *pt_exc2;
|
||||
Word16 tmpv, maxv, scale;
|
||||
Word16 fft_io[L_FRAME16k];
|
||||
Word32 sp[129];
|
||||
Word16 *ptR,*ptI;
|
||||
Word32 env[NUM_ENV_CNG];
|
||||
Word16 exp1;
|
||||
Word16 CNG_mode;
|
||||
Word16 tmp;
|
||||
Word16 temp_lo_fx, temp_hi_fx;
|
||||
Word16 exp_pow;
|
||||
|
||||
|
||||
/* update the pointer to circular buffer of old LSP vectors */
|
||||
*ho_circ_ptr = add(*ho_circ_ptr,1);
|
||||
|
||||
if( sub(*ho_circ_ptr, HO_HIST_SIZE) == 0 )
|
||||
{
|
||||
*ho_circ_ptr = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
/* update the circular buffer of old LSP vectors with the new LSP vector */
|
||||
Copy( lsp_new, &(ho_lsp_circ[(*ho_circ_ptr)*M]), M );
|
||||
|
||||
/* calculate the residual signal energy */
|
||||
/*enr = dotp( exc2, exc2, L_frame ) / L_frame; */
|
||||
|
||||
maxv = 0;
|
||||
move16();
|
||||
FOR(i = 0; i < L_frame; i++)
|
||||
{
|
||||
maxv = s_max(maxv, abs_s(exc2[i]));
|
||||
}
|
||||
scale = norm_s(maxv);
|
||||
|
||||
pt_exc2 = exc2;
|
||||
move16();
|
||||
L_ener = L_deposit_l(0);
|
||||
IF( sub(L_frame, L_FRAME) == 0)
|
||||
{
|
||||
FOR (j=0; j<128; j++)
|
||||
{
|
||||
tmpv = shl(*pt_exc2,scale);
|
||||
L_tmp = L_mult0(tmpv, tmpv); /* 2*(Q_exc+scale) */
|
||||
pt_exc2++;
|
||||
tmpv = shl(*pt_exc2,scale);
|
||||
L_tmp = L_mac0(L_tmp, tmpv, tmpv);
|
||||
pt_exc2++;
|
||||
L_ener = L_add(L_ener, L_shr(L_tmp, 7)); /* Q(2*(Q_exc+scale)+1) ,division by L_frame done here */
|
||||
}
|
||||
}
|
||||
ELSE /* L_FRAME16k */
|
||||
{
|
||||
FOR (j=0; j<160; j++)
|
||||
{
|
||||
tmpv = shl(*pt_exc2,scale);
|
||||
L_tmp = L_mult0(tmpv, tmpv); /* 2*(Q_exc+scale) */
|
||||
pt_exc2++;
|
||||
tmpv = shl(*pt_exc2,scale);
|
||||
L_tmp = L_mac0(L_tmp, tmpv, tmpv);
|
||||
pt_exc2++;
|
||||
L_ener = L_add(L_ener, L_shr( Mult_32_16(L_tmp,26214 /* 256/320, Q15 */), 7)); /* Q(2*(Q_exc+scale)+15+1-16+1) ,division by L_frame done here */
|
||||
}
|
||||
}
|
||||
L_ener = L_shr(L_ener, sub(shl(add(Q_exc,scale),1),5)); /* Q6 (2*(Q_exc+scale)+1-2*(Q_exc+scale)+5) */
|
||||
|
||||
/* update the circular buffer of old energies */
|
||||
ho_ener_circ[*ho_circ_ptr] = L_ener;
|
||||
move32();
|
||||
|
||||
IF( sub(enc_dec_flag, ENC) == 0 )
|
||||
{
|
||||
/* Store residual signal for postponed FFT-processing*/
|
||||
*cng_buf_cnt = add(*cng_buf_cnt,1);
|
||||
if( sub(*cng_buf_cnt, HO_HIST_SIZE) > 0 )
|
||||
{
|
||||
*cng_buf_cnt = HO_HIST_SIZE;
|
||||
move16();
|
||||
}
|
||||
Copy( exc2, &(cng_exc2_buf[(*ho_circ_ptr)*L_FFT]), L_FFT );
|
||||
cng_Qexc_buf[*ho_circ_ptr] = Q_exc;
|
||||
move16();
|
||||
cng_brate_buf[*ho_circ_ptr] = last_active_brate;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* calculate the spectrum of residual signal */
|
||||
Copy(exc2, fft_io, L_frame);
|
||||
|
||||
fft_rel_fx(fft_io, L_FFT, LOG2_L_FFT);
|
||||
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[L_FFT-1];
|
||||
FOR (i=0; i<NUM_ENV_CNG; i++)
|
||||
{
|
||||
/* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
|
||||
L_tmp = L_mult(*ptR,*ptR);/* 2*Q_exc+1 */
|
||||
L_tmp = L_add(L_tmp,L_mult(*ptI,*ptI));/* 2*Q_exc+1 */
|
||||
L_tmp = L_add(L_tmp,L_tmp);/* 2*Q_exc+1 */
|
||||
L_tmp = Mult_32_16(L_tmp,128);/* 2*Q_exc+1 */
|
||||
tmp = add(add(Q_exc,Q_exc),1);
|
||||
sp[i] = L_shr(L_tmp,sub(tmp,6));
|
||||
move32();/* Q6 */
|
||||
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
Copy32(sp,env,NUM_ENV_CNG);
|
||||
IF( L_sub(last_active_brate,ACELP_13k20) > 0 )
|
||||
{
|
||||
CNG_mode = 4;
|
||||
}
|
||||
ELSE IF( L_sub(last_active_brate,ACELP_9k60) > 0 )
|
||||
{
|
||||
CNG_mode = 3;
|
||||
}
|
||||
ELSE IF( L_sub(last_active_brate,ACELP_8k00) > 0 )
|
||||
{
|
||||
CNG_mode = 2;
|
||||
}
|
||||
ELSE IF( L_sub(last_active_brate,ACELP_7k20) > 0 )
|
||||
{
|
||||
CNG_mode = 1;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
CNG_mode = 0;
|
||||
}
|
||||
|
||||
/* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
|
||||
L_tmp = L_shl(L_deposit_l(ENR_ATT_fx[CNG_mode]), 8);/* 16 */
|
||||
temp_lo_fx = L_Extract_lc(L_tmp, &temp_hi_fx);
|
||||
|
||||
exp_pow = sub(14, temp_hi_fx);
|
||||
L_tmp = Pow2(14, temp_lo_fx); /* Qexp_pow */
|
||||
L_tmp = L_shl(L_tmp, sub(13, exp_pow)); /* Q13 */
|
||||
tmp = extract_l(L_tmp);/* Q13 */
|
||||
|
||||
exp1 = norm_s(tmp);
|
||||
tmp = shl(tmp, exp1);/*Q(exp1+13) */
|
||||
tmp = div_s(16384,tmp); /*Q(15+14-exp1-13) */
|
||||
tmp = shr(tmp,sub(1,exp1));/* Q15 */
|
||||
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
env[i] = Mult_32_16(env[i],tmp);
|
||||
move32();
|
||||
}
|
||||
|
||||
/* update the circular buffer of old residual envelope */
|
||||
/* Copy32( env, &(ho_env_circ[add(shl(*ho_circ_ptr,4),shl(*ho_circ_ptr,2))]), NUM_ENV_CNG ); */
|
||||
Copy32( env, &(ho_env_circ[(*ho_circ_ptr)*NUM_ENV_CNG]), NUM_ENV_CNG );
|
||||
}
|
||||
*ho_circ_size = add(*ho_circ_size,1);
|
||||
if( sub(*ho_circ_size,HO_HIST_SIZE) > 0 )
|
||||
{
|
||||
*ho_circ_size = HO_HIST_SIZE;
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+2371
File diff suppressed because it is too large
Load Diff
Executable
+288
@@ -0,0 +1,288 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "prot_fx.h"
|
||||
#include "options.h"
|
||||
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "rom_basop_util.h"
|
||||
#define inv_int InvIntTable
|
||||
|
||||
|
||||
|
||||
Word16 tcxGetNoiseFillingTilt(Word16 A[], Word16 lpcorder, Word16 L_frame, Word16 mode, Word16 *noiseTiltFactor)
|
||||
{
|
||||
Word16 firstLine;
|
||||
Word32 tmp;
|
||||
Word16 As[M+1];
|
||||
|
||||
|
||||
IF (mode != 0)
|
||||
{
|
||||
firstLine = idiv1616U(L_frame, 6);
|
||||
*noiseTiltFactor = 18432/*0.5625f Q15*/;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
firstLine = shr(L_frame, 3);
|
||||
|
||||
Copy_Scale_sig( A, As, lpcorder+1, sub(norm_s(A[0]),2) );
|
||||
tmp = get_gain(As+1, As, lpcorder);
|
||||
BASOP_SATURATE_WARNING_OFF;
|
||||
*noiseTiltFactor = add(round_fx(L_shl(tmp, 15)), 3072/*0.09375f Q15*/);
|
||||
move16();
|
||||
BASOP_SATURATE_WARNING_ON;
|
||||
}
|
||||
|
||||
|
||||
return firstLine;
|
||||
}
|
||||
|
||||
|
||||
void tcxFormantEnhancement(
|
||||
Word16 xn_buf[],
|
||||
Word16 gainlpc[], Word16 gainlpc_e[],
|
||||
Word32 spectrum[], Word16 *spectrum_e,
|
||||
Word16 L_frame,
|
||||
Word16 L_frameTCX
|
||||
)
|
||||
{
|
||||
Word16 i, j, k, l, n;
|
||||
Word16 fac, fac0, fac1, fac_e, d, tmp;
|
||||
Word16 xn_buf_e, xn_one, m, e;
|
||||
|
||||
|
||||
k = shr(L_frame, 6); /* FDNS_NPTS = 64 */
|
||||
l = 0;
|
||||
move16();
|
||||
|
||||
/* get exponent */
|
||||
xn_buf_e = 0;
|
||||
move16();
|
||||
FOR (i = 0; i < FDNS_NPTS; i++)
|
||||
{
|
||||
xn_buf_e = s_max(xn_buf_e, gainlpc_e[i]);
|
||||
}
|
||||
xn_buf_e = shr(add(xn_buf_e, 1), 1); /* max exponent after sqrt */
|
||||
xn_one = shr(0x4000, sub(xn_buf_e, 1)); /* 1.0 scaled to xn_buf_e */
|
||||
|
||||
/* Formant enhancement via square root of the LPC gains */
|
||||
e = gainlpc_e[0];
|
||||
move16();
|
||||
m = Sqrt16(gainlpc[0], &e);
|
||||
xn_buf[0] = shl(m, sub(e, xn_buf_e));
|
||||
move16();
|
||||
|
||||
e = gainlpc_e[1];
|
||||
move16();
|
||||
m = Sqrt16(gainlpc[1], &e);
|
||||
xn_buf[1] = shl(m, sub(e, xn_buf_e));
|
||||
move16();
|
||||
|
||||
fac0 = s_min(xn_buf[0], xn_buf[1]);
|
||||
fac_e = xn_buf_e;
|
||||
move16();
|
||||
fac0 = Inv16(fac0, &fac_e);
|
||||
|
||||
FOR (i = 1; i < FDNS_NPTS-1; i++)
|
||||
{
|
||||
e = gainlpc_e[i+1];
|
||||
move16();
|
||||
m = Sqrt16(gainlpc[i+1], &e);
|
||||
xn_buf[i+1] = shl(m, sub(e, xn_buf_e));
|
||||
move16();
|
||||
|
||||
test();
|
||||
IF ((sub(xn_buf[i-1], xn_buf[i]) <= 0) && (sub(xn_buf[i+1], xn_buf[i]) <= 0))
|
||||
{
|
||||
m = s_max(xn_buf[i-1], xn_buf[i+1]);
|
||||
e = xn_buf_e;
|
||||
move16();
|
||||
m = Inv16(m, &e);
|
||||
|
||||
fac1 = m;
|
||||
move16();
|
||||
tmp = sub(e, fac_e);
|
||||
|
||||
if (tmp > 0) fac0 = shr(fac0, tmp);
|
||||
if (tmp < 0) fac1 = shl(fac1, tmp);
|
||||
|
||||
if (tmp > 0)
|
||||
{
|
||||
fac_e = e;
|
||||
move16();
|
||||
}
|
||||
|
||||
d = sub(fac1, fac0);
|
||||
n = sub(i, l);
|
||||
assert(n <= 64);
|
||||
|
||||
xn_buf[l] = xn_one;
|
||||
move16();
|
||||
FOR (j = 1; j < n; j++)
|
||||
{
|
||||
fac = add(fac0, mult(d, extract_l(L_mult0(j, inv_int[n]))));
|
||||
BASOP_SATURATE_WARNING_OFF;
|
||||
xn_buf[l+j] = s_min(xn_one, shl(mult(xn_buf[l+j], fac), fac_e));
|
||||
move16();
|
||||
BASOP_SATURATE_WARNING_ON;
|
||||
}
|
||||
|
||||
l = i;
|
||||
move16();
|
||||
|
||||
fac0 = m;
|
||||
move16();
|
||||
fac_e = e;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
/* i = FDNS_NPTS - 1; Completing changes to gains */
|
||||
m = s_min(xn_buf[i-1], xn_buf[i]);
|
||||
e = xn_buf_e;
|
||||
move16();
|
||||
m = Inv16(m, &e);
|
||||
|
||||
fac1 = m;
|
||||
move16();
|
||||
tmp = sub(e, fac_e);
|
||||
|
||||
if (tmp > 0) fac0 = shr(fac0, tmp);
|
||||
if (tmp < 0) fac1 = shl(fac1, tmp);
|
||||
|
||||
if (tmp > 0)
|
||||
{
|
||||
fac_e = e;
|
||||
move16();
|
||||
}
|
||||
|
||||
d = sub(fac1, fac0);
|
||||
n = sub(i, l);
|
||||
assert(n <= 64);
|
||||
|
||||
xn_buf[l] = xn_one;
|
||||
move16();
|
||||
FOR (j = 1; j < n; j++)
|
||||
{
|
||||
fac = add(fac0, mult(d, extract_l(L_mult0(j, inv_int[n]))));
|
||||
BASOP_SATURATE_WARNING_OFF;
|
||||
xn_buf[l+j] = s_min(xn_one, shl(mult(xn_buf[l+j], fac), fac_e));
|
||||
move16();
|
||||
BASOP_SATURATE_WARNING_ON;
|
||||
}
|
||||
|
||||
xn_buf[i] = xn_one;
|
||||
move16();
|
||||
|
||||
/* Application of changed gains onto decoded MDCT lines */
|
||||
FOR (i = 0; i < L_frame; i += k)
|
||||
{
|
||||
FOR (l = 0; l < k; l++)
|
||||
{
|
||||
*spectrum = Mpy_32_16_1(*spectrum, *xn_buf);
|
||||
move32();
|
||||
spectrum++;
|
||||
}
|
||||
xn_buf++;
|
||||
}
|
||||
|
||||
tmp = sub(L_frameTCX, L_frame);
|
||||
FOR (i = 0; i < tmp; i++)
|
||||
{
|
||||
spectrum[i] = L_shr(spectrum[i], xn_buf_e);
|
||||
move32();
|
||||
}
|
||||
*spectrum_e = add(*spectrum_e, xn_buf_e);
|
||||
move16();
|
||||
|
||||
}
|
||||
|
||||
void tcxInvertWindowGrouping(TCX_config *tcx_cfg,
|
||||
Word32 xn_buf[],
|
||||
Word32 spectrum[],
|
||||
Word16 L_frame,
|
||||
Word8 fUseTns,
|
||||
Word16 last_core,
|
||||
Word16 index,
|
||||
Word16 frame_cnt,
|
||||
Word16 bfi)
|
||||
{
|
||||
Word16 i, L_win, L_spec;
|
||||
Word32 *p;
|
||||
|
||||
|
||||
L_win = shr(L_frame, 1);
|
||||
L_spec = tcx_cfg->tnsConfig[0][0].iFilterBorders[0];
|
||||
move16();
|
||||
|
||||
test();
|
||||
test();
|
||||
if ((frame_cnt != 0) && (bfi == 0) && (last_core != ACELP_CORE)) /* fix sub-window overlap */
|
||||
{
|
||||
tcx_cfg->tcx_last_overlap_mode = tcx_cfg->tcx_curr_overlap_mode;
|
||||
move16();
|
||||
}
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF (((bfi==0) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) ||
|
||||
((tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP) && (frame_cnt == 0) && (index == 0))))
|
||||
||
|
||||
((bfi!=0) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) &&
|
||||
!(tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP))))
|
||||
{
|
||||
/* ungroup sub-windows: deinterleave MDCT bins into separate windows */
|
||||
p = xn_buf;
|
||||
FOR (i = 1; i < L_win; i += 2)
|
||||
{
|
||||
*p++ = spectrum[i];
|
||||
move32();
|
||||
}
|
||||
|
||||
p = spectrum;
|
||||
FOR (i = 0; i < L_frame; i += 2)
|
||||
{
|
||||
*p++ = spectrum[i];
|
||||
move32();
|
||||
}
|
||||
|
||||
p = spectrum + L_frame - 1;
|
||||
FOR (i = sub(L_frame, 1); i > L_win; i -= 2)
|
||||
{
|
||||
*p-- = spectrum[i];
|
||||
move32();
|
||||
}
|
||||
Copy32(xn_buf, spectrum + L_win, shr(L_win, 1));
|
||||
|
||||
test();
|
||||
test();
|
||||
IF ((tcx_cfg->fIsTNSAllowed != 0) && (bfi == 0) && (fUseTns != 0))
|
||||
{
|
||||
/* rearrange LF sub-window lines prior to TNS synthesis filtering */
|
||||
IF (sub(L_spec, L_frame) < 0)
|
||||
{
|
||||
Copy32(spectrum+8, spectrum+16, sub(shr(L_spec,1),8));
|
||||
Copy32(spectrum+L_frame/2, spectrum+8, 8);
|
||||
Copy32(spectrum+L_frame/2+8, spectrum+L_spec/2+8, sub(shr(L_spec,1),8));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Copy32(spectrum+L_win, xn_buf, 8);
|
||||
Copy32(spectrum+8, spectrum+16, sub(L_win, 8));
|
||||
Copy32(xn_buf, spectrum+8, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+471
@@ -0,0 +1,471 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "options.h"
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
#include "prot_fx.h"
|
||||
#include "rom_com_fx.h"
|
||||
|
||||
|
||||
Word8 getTcxonly(const Word32 bitrate)
|
||||
{
|
||||
|
||||
Word8 tcxonly;
|
||||
|
||||
tcxonly = 0;
|
||||
move16();
|
||||
if( L_sub(bitrate,32000) > 0 )
|
||||
{
|
||||
tcxonly = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return tcxonly;
|
||||
}
|
||||
|
||||
Word8 getCtxHm(const Word32 bitrate, const Word16 rf_flag)
|
||||
{
|
||||
|
||||
Word8 ctx_hm;
|
||||
|
||||
ctx_hm = 0;
|
||||
move16();
|
||||
test();
|
||||
if( (bitrate > LPC_SHAPED_ARI_MAX_RATE) && (bitrate <= 64000) && !rf_flag)
|
||||
{
|
||||
|
||||
ctx_hm = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return ctx_hm;
|
||||
}
|
||||
|
||||
|
||||
Word8 getResq(const Word32 bitrate)
|
||||
{
|
||||
|
||||
Word8 resq;
|
||||
|
||||
resq = 0;
|
||||
move16();
|
||||
if (L_sub(bitrate,64000) <= 0)
|
||||
{
|
||||
resq = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return resq;
|
||||
}
|
||||
|
||||
|
||||
Word8 getTnsAllowed(const Word32 bitrate
|
||||
,const Word16 igf
|
||||
)
|
||||
{
|
||||
Word8 tnsAllowed;
|
||||
|
||||
tnsAllowed = 0;
|
||||
move16();
|
||||
IF ( igf != 0 )
|
||||
{
|
||||
if( L_sub(bitrate, HQ_16k40) > 0 )
|
||||
{
|
||||
tnsAllowed = 1;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
if( L_sub(bitrate, HQ_32k) > 0)
|
||||
{
|
||||
tnsAllowed = 1;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
return tnsAllowed;
|
||||
}
|
||||
|
||||
|
||||
Word8 getRestrictedMode(const Word32 bitrate, const Word16 Opt_AMR_WB)
|
||||
{
|
||||
|
||||
Word8 restrictedMode;
|
||||
|
||||
restrictedMode = 3;
|
||||
move16();
|
||||
|
||||
test();
|
||||
IF ( (Opt_AMR_WB == 0) && (L_sub(bitrate,32000) > 0 ) )
|
||||
{
|
||||
restrictedMode = 6;
|
||||
move16();
|
||||
}
|
||||
ELSE IF( Opt_AMR_WB )
|
||||
{
|
||||
restrictedMode = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return restrictedMode;
|
||||
}
|
||||
|
||||
|
||||
Word16 sr2fscale(const Word32 sr)
|
||||
{
|
||||
Word16 fscale;
|
||||
|
||||
SWITCH(sr)
|
||||
{
|
||||
case 8000:
|
||||
fscale = (FSCALE_DENOM*8000)/12800;
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case 12800:
|
||||
fscale = FSCALE_DENOM;
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case 16000:
|
||||
fscale = (FSCALE_DENOM*16000)/12800;
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case 25600:
|
||||
fscale = (FSCALE_DENOM*25600)/12800;
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case 32000:
|
||||
fscale = (FSCALE_DENOM*32000)/12800;
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case 48000:
|
||||
fscale = (FSCALE_DENOM*48000)/12800;
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
fscale = 0; /* just to avoid compiler warning */
|
||||
BREAK;
|
||||
}
|
||||
return fscale;
|
||||
}
|
||||
|
||||
Word32 getCoreSamplerateMode2(const Word32 bitrate, const Word16 bandwidth, const Word16 rf_mode)
|
||||
{
|
||||
|
||||
Word32 sr_core;
|
||||
sr_core = -1; /* to suppress MSVC warning */ move32();
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
|
||||
IF( L_sub( bandwidth,NB) == 0 )
|
||||
{
|
||||
sr_core = 12800;
|
||||
move32();
|
||||
}
|
||||
|
||||
ELSE IF ( L_and(L_sub(bandwidth,WB)==0, L_sub(bitrate,13200)<0) ||
|
||||
L_and(L_sub(bandwidth,SWB)==0, L_sub(bitrate,13200)<=0) || sub(rf_mode,1) == 0 )
|
||||
|
||||
{
|
||||
sr_core = 12800;
|
||||
move32();
|
||||
}
|
||||
ELSE IF (L_sub(bandwidth,WB)==0 || ( (L_sub(bitrate,32000)<=0) && ((L_sub(bandwidth,SWB)==0) || (L_sub(bandwidth,FB)==0)) ) )
|
||||
{
|
||||
sr_core = 16000;
|
||||
move32();
|
||||
}
|
||||
ELSE IF ( ((L_sub(bandwidth,SWB)==0) || (L_sub(bandwidth,FB)==0)) && (L_sub(bitrate,64000)<=0) )
|
||||
{
|
||||
sr_core = 25600;
|
||||
move32();
|
||||
}
|
||||
ELSE IF (L_sub(bandwidth,SWB)==0 || L_sub(bandwidth,FB)==0)
|
||||
{
|
||||
sr_core = 32000;
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return sr_core;
|
||||
}
|
||||
|
||||
Word16 getTcxBandwidth(const Word16 bandwidth)
|
||||
{
|
||||
|
||||
Word16 tcxBandwidth;
|
||||
|
||||
tcxBandwidth = 16384/*0.5f Q15*/;
|
||||
move16();
|
||||
if(sub(bandwidth, NB) == 0)
|
||||
{
|
||||
tcxBandwidth = 10240/*0.3125f Q15*/;
|
||||
move16();
|
||||
|
||||
}
|
||||
|
||||
return tcxBandwidth;
|
||||
}
|
||||
|
||||
|
||||
Word8 getIgfPresent(
|
||||
const Word32 bitrate,
|
||||
const Word16 bandwidth
|
||||
,const Word16 rf_mode
|
||||
)
|
||||
{
|
||||
Word8 igfPresent;
|
||||
|
||||
igfPresent = 0;
|
||||
move16();
|
||||
|
||||
test();
|
||||
test();
|
||||
if( (sub(bandwidth, SWB) == 0) && (L_sub(bitrate, ACELP_9k60) >= 0) && (L_sub(bitrate, HQ_96k) < 0) )
|
||||
{
|
||||
igfPresent = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
test();
|
||||
if( sub(bandwidth, FB) == 0 && (L_sub(bitrate, ACELP_16k40) >= 0))
|
||||
{
|
||||
igfPresent = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
test();
|
||||
if( (sub(bandwidth, WB) == 0) && (L_sub(bitrate, ACELP_9k60) == 0) )
|
||||
{
|
||||
igfPresent = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
if( ((sub(bandwidth, WB) == 0) || (sub(bandwidth, SWB) == 0)) && (sub(rf_mode, 1) == 0) && (L_sub(bitrate, ACELP_13k20) == 0) )
|
||||
{
|
||||
igfPresent = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return igfPresent;
|
||||
}
|
||||
|
||||
|
||||
Word8 getCnaPresent(
|
||||
const Word32 bitrate,
|
||||
const Word16 bandwidth
|
||||
)
|
||||
{
|
||||
Word8 flag_cna = 0;
|
||||
|
||||
flag_cna = 0;
|
||||
move16();
|
||||
test();
|
||||
if( sub(bandwidth, NB) == 0 && (L_sub(bitrate, ACELP_13k20) <= 0) )
|
||||
{
|
||||
flag_cna = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
test();
|
||||
if( (sub(bandwidth, WB) == 0) && (L_sub(bitrate, ACELP_13k20) <= 0) )
|
||||
{
|
||||
flag_cna = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
test();
|
||||
if( (sub(bandwidth, SWB) == 0) && (L_sub(bitrate, ACELP_13k20) <= 0) )
|
||||
{
|
||||
flag_cna = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return flag_cna;
|
||||
}
|
||||
|
||||
Word8 getTcxLtp(const Word32 sr_core)
|
||||
{
|
||||
|
||||
Word8 tcxltp = 0;
|
||||
|
||||
tcxltp = 0;
|
||||
move16();
|
||||
test();
|
||||
if ( (L_sub(sr_core, 25600) <= 0) )
|
||||
{
|
||||
tcxltp = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return tcxltp;
|
||||
}
|
||||
|
||||
|
||||
Word16 initPitchLagParameters(
|
||||
const Word32 sr_core,
|
||||
Word16 *pit_min,
|
||||
Word16 *pit_fr1,
|
||||
Word16 *pit_fr1b,
|
||||
Word16 *pit_fr2,
|
||||
Word16 *pit_max
|
||||
)
|
||||
{
|
||||
|
||||
Word16 pit_res_max;
|
||||
|
||||
IF (L_sub(sr_core, 12800) == 0)
|
||||
{
|
||||
|
||||
*pit_min = PIT_MIN_12k8;
|
||||
move16();
|
||||
*pit_max = PIT_MAX_12k8;
|
||||
move16();
|
||||
*pit_fr2 = PIT_FR2_12k8;
|
||||
move16();
|
||||
*pit_fr1 = PIT_FR1_12k8;
|
||||
move16();
|
||||
*pit_fr1b = PIT_FR1_8b_12k8;
|
||||
move16();
|
||||
pit_res_max = 4;
|
||||
move16();
|
||||
|
||||
}
|
||||
ELSE IF (L_sub(sr_core, 16000) == 0)
|
||||
{
|
||||
|
||||
*pit_min = PIT_MIN_16k;
|
||||
move16();
|
||||
*pit_max = PIT_MAX_16k;
|
||||
move16();
|
||||
*pit_fr2 = PIT_FR2_16k;
|
||||
move16();
|
||||
*pit_fr1 = PIT_FR1_16k;
|
||||
move16();
|
||||
*pit_fr1b = PIT_FR1_8b_16k;
|
||||
move16();
|
||||
pit_res_max = 6;
|
||||
move16();
|
||||
|
||||
}
|
||||
ELSE IF (L_sub(sr_core, 25600) == 0)
|
||||
{
|
||||
|
||||
*pit_min = PIT_MIN_25k6;
|
||||
move16();
|
||||
*pit_max = PIT_MAX_25k6;
|
||||
move16();
|
||||
*pit_fr2 = PIT_FR2_25k6;
|
||||
move16();
|
||||
*pit_fr1 = PIT_FR1_25k6;
|
||||
move16();
|
||||
*pit_fr1b = PIT_FR1_8b_25k6;
|
||||
move16();
|
||||
pit_res_max = 4;
|
||||
move16();
|
||||
}
|
||||
ELSE /* sr_core==32000 */
|
||||
{
|
||||
|
||||
*pit_min = PIT_MIN_32k;
|
||||
move16();
|
||||
*pit_max = PIT_MAX_32k;
|
||||
move16();
|
||||
*pit_fr2 = PIT_FR2_32k;
|
||||
move16();
|
||||
*pit_fr1 = PIT_FR1_32k;
|
||||
move16();
|
||||
*pit_fr1b = PIT_FR1_8b_32k;
|
||||
move16();
|
||||
pit_res_max = 6;
|
||||
move16();
|
||||
|
||||
}
|
||||
|
||||
return pit_res_max;
|
||||
}
|
||||
|
||||
Word16 getNumTcxCodedLines(const Word16 bwidth)
|
||||
{
|
||||
|
||||
Word16 tcx_coded_lines;
|
||||
|
||||
tcx_coded_lines = 0;
|
||||
move16();
|
||||
|
||||
if(sub(bwidth, NB) == 0)
|
||||
{
|
||||
tcx_coded_lines = 160;
|
||||
move16();
|
||||
}
|
||||
|
||||
if(sub(bwidth, WB) == 0)
|
||||
{
|
||||
tcx_coded_lines = 320;
|
||||
move16();
|
||||
}
|
||||
|
||||
if(sub(bwidth, SWB) == 0)
|
||||
{
|
||||
tcx_coded_lines = 640;
|
||||
move16();
|
||||
}
|
||||
|
||||
if(sub(bwidth, FB) == 0)
|
||||
{
|
||||
tcx_coded_lines = 960;
|
||||
move16();
|
||||
}
|
||||
|
||||
return tcx_coded_lines;
|
||||
}
|
||||
|
||||
Word16 getTcxLpcShapedAri(
|
||||
const Word32 total_brate,
|
||||
const Word16 bwidth
|
||||
,const Word16 rf_mode
|
||||
)
|
||||
{
|
||||
Word16 tcx_lpc_shaped_ari = 0;
|
||||
move16();
|
||||
|
||||
(void) bwidth;
|
||||
|
||||
test();
|
||||
if( (L_sub(total_brate, LPC_SHAPED_ARI_MAX_RATE) <= 0) || rf_mode )
|
||||
{
|
||||
tcx_lpc_shaped_ari = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return tcx_lpc_shaped_ari;
|
||||
}
|
||||
Executable
+136
@@ -0,0 +1,136 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
/*========================================================================*/
|
||||
/* FUNCTION : deemph_fx() */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* PURPOSE : Deemphasis: filtering through 1/(1-mu z^-1) */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16) mu : deemphasis factor Q15 */
|
||||
/* _ (Word16) L : vector size */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*) signal : signal Q_syn2-1 */
|
||||
/* _ (Word16*) mem : memory (y[-1]) Q_syn2-1 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*========================================================================*/
|
||||
void deemph_fx(
|
||||
Word16 *signal, /* i/o: signal Qx */
|
||||
const Word16 mu, /* i : deemphasis factor Q15 */
|
||||
const Word16 L, /* i : vector size Q0 */
|
||||
Word16 *mem /* i/o: memory (y[-1]) Qx */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 L_tmp;
|
||||
|
||||
L_tmp = L_deposit_h(signal[0]);
|
||||
L_tmp = L_mac(L_tmp, *mem, mu);
|
||||
signal[0] = round_fx(L_tmp);
|
||||
|
||||
FOR (i = 1; i < L; i++)
|
||||
{
|
||||
L_tmp = L_deposit_h(signal[i]);
|
||||
L_tmp = L_mac(L_tmp, signal[i - 1], mu);
|
||||
signal[i] = round_fx(L_tmp);
|
||||
}
|
||||
|
||||
*mem = signal[L - 1];
|
||||
move16();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Deeemph2 :
|
||||
*
|
||||
* Deemphasis: filtering through 1/(1-mu z^-1)
|
||||
* Output divided by 2
|
||||
*-------------------------------------------------------------------*/
|
||||
void Deemph2(
|
||||
Word16 x[], /* i/o: input signal overwritten by the output Qx/Qx-1 */
|
||||
const Word16 mu, /* i : deemphasis factor Q15 */
|
||||
const Word16 L, /* i : vector size Q0 */
|
||||
Word16 *mem /* i/o: memory (y[-1]) Qx-1 */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 L_tmp;
|
||||
|
||||
/* saturation can occur in L_mac() */
|
||||
|
||||
L_tmp = L_mult(x[0], 16384);
|
||||
x[0] = mac_r(L_tmp, *mem, mu);
|
||||
move16();
|
||||
|
||||
FOR (i = 1; i < L; i++)
|
||||
{
|
||||
L_tmp = L_mult(x[i], 16384);
|
||||
x[i] = mac_r(L_tmp, x[i - 1], mu);
|
||||
move16();
|
||||
}
|
||||
|
||||
*mem = x[L - 1];
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* E_UTIL_deemph2
|
||||
*
|
||||
* Parameters:
|
||||
* shift I: scale output
|
||||
* x I/O: signal Qx/Qx-shift
|
||||
* mu I: deemphasis factor Qx
|
||||
* L I: vector size
|
||||
* mem I/O: memory (signal[-1]) Qx
|
||||
*
|
||||
* Function:
|
||||
* Filtering through 1/(1-mu z^-1)
|
||||
* Signal is divided by 2.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void E_UTIL_deemph2(Word16 shift, Word16 *x, const Word16 mu, const Word16 L, Word16 *mem)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 L_tmp;
|
||||
|
||||
/* signal[0] = signal[0] + mu * (*mem); */
|
||||
L_tmp = L_deposit_h(*mem);
|
||||
IF(shift >= 0)
|
||||
{
|
||||
shift = shr(-32768, shift);
|
||||
FOR (i = 0; i < L; i++)
|
||||
{
|
||||
L_tmp = L_msu(Mpy_32_16_1(L_tmp, mu), x[i],shift);
|
||||
x[i] = round_fx(L_tmp);
|
||||
}
|
||||
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
FOR (i = 0; i < L; i++)
|
||||
{
|
||||
L_tmp = L_msu(Mpy_32_16_1(L_tmp, mu), shr(x[i],shift),-32768);
|
||||
x[i] = round_fx(L_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
*mem = x[L - 1];
|
||||
move16();
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h"
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* get_delay_fx()
|
||||
*
|
||||
* Function returns various types of delays in the codec in ms.
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
Word32 get_delay_fx( /* o : delay value in ms */
|
||||
const Word16 what_delay, /* i : what delay? (ENC or DEC) */
|
||||
const Word32 io_fs /* i : input/output sampling frequency */
|
||||
)
|
||||
{
|
||||
Word32 delay = 0;
|
||||
|
||||
IF( sub(what_delay,ENC) == 0 )
|
||||
{
|
||||
delay = (DELAY_FIR_RESAMPL_NS + ACELP_LOOK_NS);
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
IF( L_sub(io_fs,8000) == 0 )
|
||||
{
|
||||
delay = DELAY_CLDFB_NS;
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
delay = DELAY_BWE_TOTAL_NS;
|
||||
move32();
|
||||
}
|
||||
}
|
||||
|
||||
return delay;
|
||||
}
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "disclaimer.h"
|
||||
#include "options.h"
|
||||
#include "stl.h"
|
||||
|
||||
/* WMC_TOOL_SKIP_FILE */
|
||||
|
||||
int print_disclaimer(FILE *fPtr)
|
||||
{
|
||||
|
||||
fprintf(fPtr, "\n==============================================================================\n");
|
||||
fprintf(fPtr, " EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0\n");
|
||||
fprintf(fPtr, "==============================================================================\n\n\n");
|
||||
return 0;
|
||||
}
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __INCLUDED_DISCLAIMER_H
|
||||
#define __INCLUDED_DISCLAIMER_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int print_disclaimer(FILE *fPtr);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __INCLUDED_DISCLAIMER_H */
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
/* Header files */
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h"
|
||||
|
||||
void dlpc_bfi(
|
||||
const Word16 L_frame,
|
||||
Word16 *lsf_q, /* o : quantized LSFs */
|
||||
const Word16 *lsfold, /* i : past quantized LSF */
|
||||
const Word16 last_good, /* i : last good received frame */
|
||||
const Word16 nbLostCmpt, /* i : counter of consecutive bad frames */
|
||||
Word16 mem_MA[], /* i/o: quantizer memory for MA model */
|
||||
Word16 mem_AR[], /* i/o: quantizer memory for AR model */
|
||||
Word16 *stab_fac, /* i : LSF stability factor */
|
||||
Word16 *lsf_adaptive_mean,/* i : LSF adaptive mean, updated when BFI==0 */
|
||||
Word16 numlpc, /* i : Number of division per superframe */
|
||||
Word16 lsf_cng[],
|
||||
Word8 plcBackgroundNoiseUpdated,
|
||||
Word16 *lsf_q_cng, /* o : quantized LSFs */
|
||||
Word16 *old_lsf_q_cng, /* o : old quantized LSFs for background noise */
|
||||
const Word16* lsfBase, /* i : base for differential LSF coding */
|
||||
Word8 tcxonly
|
||||
)
|
||||
{
|
||||
|
||||
lsf_dec_bfi(
|
||||
MODE2,
|
||||
&lsf_q[0], lsfold, lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac,
|
||||
0, L_frame, last_good, nbLostCmpt,
|
||||
plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, tcxonly
|
||||
,0
|
||||
|
||||
);
|
||||
IF ( sub(numlpc,2)==0 )
|
||||
{
|
||||
/* Decode the second LPC */
|
||||
lsf_dec_bfi(
|
||||
MODE2,
|
||||
&lsf_q[M], &lsf_q[0], lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac,
|
||||
0, L_frame, last_good, nbLostCmpt+1,
|
||||
plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, tcxonly
|
||||
,0
|
||||
);
|
||||
}
|
||||
/**/ /*No local variabvles defined*/
|
||||
}
|
||||
|
||||
Executable
+426
@@ -0,0 +1,426 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
#include "math_32.h"
|
||||
|
||||
static Word16 const * get_edct_table(Word16 length, Word16 *q)
|
||||
{
|
||||
Word16 const * edct_table = NULL;
|
||||
SWITCH (length)
|
||||
{
|
||||
case 1200:
|
||||
edct_table = edct_table_600_fx;
|
||||
move16();
|
||||
*q = add(*q, 2);
|
||||
BREAK;
|
||||
case 960 :
|
||||
edct_table = edct_table_480_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 640 :
|
||||
edct_table = edct_table_320_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 320 :
|
||||
edct_table = edct_table_160_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 256 :
|
||||
edct_table = edct_table_128_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 240 :
|
||||
edct_table = edct_table_120_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 200 :
|
||||
edct_table = edct_table_100_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 160 :
|
||||
edct_table = edct_table_80_fx ;
|
||||
move16();
|
||||
BREAK;
|
||||
case 40 :
|
||||
edct_table = edct_table_20_fx ;
|
||||
move16();
|
||||
BREAK;
|
||||
case 800 :
|
||||
edct_table = edct_table_400_fx;
|
||||
move16();
|
||||
*q = add(*q, 2);
|
||||
BREAK;
|
||||
case 512 :
|
||||
edct_table = edct_table_256_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 480 :
|
||||
edct_table = edct_table_240_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 400 :
|
||||
edct_table = edct_table_200_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 128 :
|
||||
edct_table = edct_table_64_fx ;
|
||||
move16();
|
||||
BREAK;
|
||||
case 80 :
|
||||
edct_table = edct_table_40_fx ;
|
||||
move16();
|
||||
BREAK;
|
||||
default:
|
||||
BREAK;
|
||||
}
|
||||
return edct_table;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* FUNCTION : edct_fx()
|
||||
*
|
||||
* PURPOSE : DCT transform
|
||||
*
|
||||
* INPUT ARGUMENTS :
|
||||
* _ (Word16) length : length
|
||||
* _ (Word16*) x : input signal Qx
|
||||
* _ (Word16*) edct_table_128_fx : edct table Q16
|
||||
*
|
||||
* OUTPUT ARGUMENTS :
|
||||
* _ (Word16[]) y : output transform Qx
|
||||
*-------------------------------------------------------------------------*/
|
||||
void edct_fx(
|
||||
const Word32 *x, /* i : input signal Qq */
|
||||
Word32 *y, /* o : output transform Qq */
|
||||
Word16 length, /* i : length */
|
||||
Word16 *q /* i : Q value of input signal */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 re;
|
||||
Word32 im;
|
||||
const Word16 *edct_table = 0; /*Q16 */
|
||||
Word32 re2[L_FRAME48k/2+240];
|
||||
Word32 im2[L_FRAME48k/2+240];
|
||||
Word32 L_tmp;
|
||||
Word16 tmp;
|
||||
Word16 len1;
|
||||
|
||||
edct_table = get_edct_table(length, q);
|
||||
len1 = shr(length, 1);
|
||||
/* Twiddling and Pre-rotate */
|
||||
FOR (i = 0; i < len1; i++)
|
||||
{
|
||||
L_tmp = Mult_32_16(x[2*i], edct_table[i]); /*Q(q+1) */
|
||||
re2[i] = Madd_32_16(L_tmp, x[length-1-2*i], edct_table[len1-1-i]); /*Q(q+1) */ move32();
|
||||
|
||||
L_tmp = Mult_32_16(x[length-1-2*i], edct_table[i]); /*Q(q+1) */
|
||||
|
||||
im2[i] = Msub_32_16(L_tmp, x[2*i], edct_table[len1-1-i]); /*Q(q+1) */ move32();
|
||||
}
|
||||
|
||||
*q = sub(15, *q);
|
||||
BASOP_cfft(re2, im2, len1, 1, q, y);
|
||||
|
||||
tmp = div_s(1, length); /*Q15 */
|
||||
tmp = round_fx(L_shl(L_mult(tmp, 19302), 2)); /*Q15 */
|
||||
FOR (i = 0; i < len1; i++)
|
||||
{
|
||||
re = Msub_32_16(re2[i], im2[i], tmp);
|
||||
im = Madd_32_16(im2[i], re2[i], tmp);
|
||||
y[2 * i] = L_add(Mult_32_16(re, edct_table[i]), Mult_32_16(im, edct_table[len1 - 1 - i]));
|
||||
move32();
|
||||
y[length - 1 - 2 * i] = L_sub(Mult_32_16(re, edct_table[len1 - 1 - i]), Mult_32_16(im, edct_table[i]));
|
||||
move32();
|
||||
} /*Q(q-2) */
|
||||
|
||||
*q = sub(15+2, *q);
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* FUNCTION : edst_fx()
|
||||
*
|
||||
* PURPOSE : DST_IV transform
|
||||
*
|
||||
* INPUT ARGUMENTS :
|
||||
* _ (Word16) length : length
|
||||
* _ (Word16*) x : input signal Qx
|
||||
* _ (Word16*) edct_table_128_fx : edct table Q16
|
||||
*
|
||||
* OUTPUT ARGUMENTS :
|
||||
* _ (Word16[]) y : output transform Qx
|
||||
*-------------------------------------------------------------------------*/
|
||||
void edst_fx(
|
||||
const Word32 *x, /* i : input signal Qq */
|
||||
Word32 *y, /* o : output transform Qq */
|
||||
Word16 length, /* i : length */
|
||||
Word16 *q /* i : Q value of input signal */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 re;
|
||||
Word32 im;
|
||||
const Word16 *edct_table = 0; /*Q16 */
|
||||
Word32 re2[L_FRAME48k/2+240];
|
||||
Word32 im2[L_FRAME48k/2+240];
|
||||
Word32 L_tmp;
|
||||
Word16 tmp;
|
||||
Word16 len1;
|
||||
|
||||
edct_table = get_edct_table(length, q);
|
||||
len1 = shr(length, 1);
|
||||
/* Twiddling and Pre-rotate */
|
||||
FOR (i = 0; i < len1; i++)
|
||||
{
|
||||
L_tmp = Mult_32_16(x[length-1-2*i], edct_table[i]);
|
||||
re2[i] = Madd_32_16(L_tmp, x[2*i], edct_table[len1-1-i]);
|
||||
move32();
|
||||
|
||||
L_tmp = Mult_32_16(x[2*i], edct_table[i]);
|
||||
im2[i] = Msub_32_16(L_tmp, x[length-1-2*i], edct_table[len1-1-i]);
|
||||
move32();
|
||||
}
|
||||
|
||||
*q = sub(15, *q);
|
||||
BASOP_cfft(re2, im2, len1, 1, q, y);
|
||||
|
||||
tmp = div_s(1, length); /*Q15 */
|
||||
tmp = round_fx(L_shl(L_mult(tmp, 19302), 2)); /*Q15 */
|
||||
FOR (i = 0; i < len1; i++)
|
||||
{
|
||||
re = Msub_32_16(re2[i], im2[i], tmp);
|
||||
im = Madd_32_16(im2[i], re2[i], tmp);
|
||||
y[2 * i] = L_add(Mult_32_16(re, edct_table[i]), Mult_32_16(im, edct_table[len1 - 1 - i]));
|
||||
move32();
|
||||
y[length - 1 - 2 * i] = L_sub(Mult_32_16(im, edct_table[i]), Mult_32_16(re, edct_table[len1 - 1 - i]));
|
||||
move32();
|
||||
} /*Q(q) */
|
||||
|
||||
*q = sub(15+2, *q);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*========================================================================*/
|
||||
/* FUNCTION : edct_fx() */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* PURPOSE : DCT transform */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16) length : length */
|
||||
/* _ (Word16*) x : input signal Qx */
|
||||
/* _ (Word16*) edct_table_128_fx : edct table Q15 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16[]) y : output transform Qx */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*========================================================================*/
|
||||
void edct_16fx(
|
||||
const Word16 *x, /* i : input signal Qx */
|
||||
Word16 *y, /* o : output transform Qx */
|
||||
Word16 length, /* i : length */
|
||||
Word16 bh /* bit-headroom */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word16 re[L_FRAME48k/2];
|
||||
Word16 im[L_FRAME48k/2];
|
||||
const Word16 *edct_table = 0;
|
||||
Word16 re2[L_FRAME48k/2];
|
||||
Word16 im2[L_FRAME48k/2];
|
||||
|
||||
Word32 L_tmp, Lacc, Lmax;
|
||||
Word16 tmp, fact;
|
||||
Word16 Q_edct;
|
||||
Word16 Len2, i2;
|
||||
const Word16 *px, *pt;
|
||||
Word16 *py;
|
||||
|
||||
/*COMPLETE: some eDCT sub function are missing */
|
||||
|
||||
IF (sub(length,L_FRAME32k) == 0)
|
||||
{
|
||||
edct_table = &edct_table_320_16fx[0];
|
||||
move16();
|
||||
}
|
||||
ELSE IF (sub(length,L_FRAME) == 0)
|
||||
{
|
||||
edct_table = &edct_table_128_16fx[0];
|
||||
move16();
|
||||
}
|
||||
ELSE IF (sub(length,L_FRAME16k) == 0)
|
||||
{
|
||||
edct_table = &edct_table_160_16fx[0];
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
}
|
||||
|
||||
/* Twiddling and Pre-rotate */
|
||||
Lmax = L_deposit_l(0);
|
||||
Len2 = shr(length,1);
|
||||
px = x + length - 1;
|
||||
pt = edct_table + Len2 - 1;
|
||||
FOR (i = 0; i < Len2; i++)
|
||||
{
|
||||
i2 = shl(i,1);
|
||||
L_tmp = L_mult(x[i2],edct_table[i]);/*Q(Qx+16) */
|
||||
|
||||
Lacc = L_mac(L_tmp,*px,*pt);/*Q(Qx+16) */
|
||||
|
||||
Lmax = L_max(Lmax, Lacc);
|
||||
|
||||
L_tmp = L_mult(*px,edct_table[i]);/*Q(Qx+16) */
|
||||
Lacc = L_msu(L_tmp,x[i2],*pt);/*Q(Qx+16) */
|
||||
Lmax = L_max(Lmax, Lacc);
|
||||
|
||||
px -= 2;
|
||||
pt--;
|
||||
}
|
||||
|
||||
tmp = 31;
|
||||
if( Lmax != 0 )
|
||||
{
|
||||
tmp = norm_l(Lmax);
|
||||
}
|
||||
Q_edct = sub(tmp,bh); /*creating a bit-headroom */
|
||||
|
||||
px = x + length - 1;
|
||||
pt = edct_table + Len2 - 1;
|
||||
FOR (i = 0; i < Len2; i++)
|
||||
{
|
||||
i2 = shl(i,1);
|
||||
|
||||
L_tmp = L_mult(x[i2],edct_table[i]);/*Q(Qx+16) */
|
||||
Lacc = L_mac(L_tmp,*px,*pt);/*Q(Qx+16) */
|
||||
re2[i] = round_fx(L_shl(Lacc, Q_edct)); /* Q(Qx+Q_edct) */
|
||||
|
||||
L_tmp = L_mult(*px,edct_table[i]);/*Q(Qx+16) */
|
||||
Lacc = L_msu(L_tmp,x[i2],*pt);/*Q(Qx+16) */
|
||||
im2[i] = round_fx(L_shl(Lacc, Q_edct)); /* Q(Qx+Q_edct) */
|
||||
|
||||
px -= 2;
|
||||
pt--;
|
||||
}
|
||||
IF (sub(length,L_FRAME32k) == 0)
|
||||
{
|
||||
DoRTFT320_16fx(re2, im2);
|
||||
}
|
||||
ELSE IF (sub(length,L_FRAME )== 0)
|
||||
{
|
||||
DoRTFT128_16fx(re2, im2);
|
||||
}
|
||||
ELSE IF (sub(length,L_FRAME16k) == 0)
|
||||
{
|
||||
DoRTFT160_16fx(re2, im2);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
}
|
||||
tmp = div_s(1,length); /*Q15 */
|
||||
L_tmp = L_mult(tmp,19302); /*Q29, (3*PI/4) in Q13 */
|
||||
fact = round_fx(L_shl(L_tmp,2)); /*Q15 */
|
||||
FOR (i = 0; i < length/2; i++)
|
||||
{
|
||||
tmp = mult_r(im2[i],fact); /*Q(Qx+Q_edct) */
|
||||
re[i] = sub(re2[i],tmp); /*Q(Qx+Q_edct) */ move16();
|
||||
|
||||
tmp = mult_r(re2[i],fact); /*Q(Qx+Q_edct) */
|
||||
im[i] = add(im2[i],tmp); /*Q(Qx+Q_edct) */ move16();
|
||||
}
|
||||
|
||||
/* Post-rotate and obtain the output data */
|
||||
py = y + length - 1;
|
||||
pt = edct_table + Len2 - 1;
|
||||
FOR (i = 0; i < Len2; i++)
|
||||
{
|
||||
i2 = shl(i,1);
|
||||
|
||||
L_tmp = L_mult(re[i],edct_table[i]);/*Q(Qx+Q_edct+16) */
|
||||
Lacc = L_mac(L_tmp,im[i],*pt);/*Q(Qx+Q_edct+16) */
|
||||
y[i2] = round_fx(L_shr(Lacc,Q_edct)); /* Q(Qx) */
|
||||
|
||||
L_tmp = L_mult(re[i],edct_table[length/2-1-i]);/*Q(Qx+Q_edct+16) */
|
||||
Lacc = L_msu(L_tmp,im[i],edct_table[i]);/*Q(Qx+Q_edct+16) */
|
||||
*py = round_fx(L_shr(Lacc,Q_edct)); /* Q(Qx) */
|
||||
|
||||
py -= 2;
|
||||
pt--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* iedct_short_fx()
|
||||
*
|
||||
* Inverse EDCT for short frames
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
void iedct_short_fx(
|
||||
const Word32 *in, /* i : input vector */
|
||||
Word16 *Q, /* i/o: Q value of input */
|
||||
Word32 *out, /* o : output vector */
|
||||
const Word16 segment_length /* i : length */
|
||||
)
|
||||
{
|
||||
Word32 alias[MAX_SEGMENT_LENGTH];
|
||||
Word16 seg_len_div2, seg_len_div4, seg_len_3mul_div4;
|
||||
Word16 i;
|
||||
Word16 qtmp, tmp;
|
||||
|
||||
qtmp = *Q;
|
||||
move16();
|
||||
tmp = 0;
|
||||
move16();
|
||||
seg_len_div2 = shr(segment_length, 1);
|
||||
seg_len_div4 = shr(segment_length, 2);
|
||||
seg_len_3mul_div4 = add(seg_len_div2, seg_len_div4);
|
||||
|
||||
edct_fx(in, alias, seg_len_div2, Q);
|
||||
FOR (i = 0; i < seg_len_div2; i++)
|
||||
{
|
||||
IF (alias[i] != 0)
|
||||
{
|
||||
tmp = 1;
|
||||
move16();
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
if (tmp == 0)
|
||||
{
|
||||
*Q = qtmp;
|
||||
move16();
|
||||
}
|
||||
FOR (i = 0; i < seg_len_div4; i++)
|
||||
{
|
||||
out[i] = alias[seg_len_div4 + i];
|
||||
move32();
|
||||
out[seg_len_div4 + i] = L_negate(alias[seg_len_div2 - 1 - i]);
|
||||
move32();
|
||||
out[seg_len_div2 + i] = L_negate(alias[seg_len_div4 - 1 - i]);
|
||||
move32();
|
||||
out[seg_len_3mul_div4 + i] = L_negate(alias[i]);
|
||||
move32();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+678
@@ -0,0 +1,678 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*---------------------------------------------------------------------*/
|
||||
#define pitch_0_9 14746 /* 0.9 in Q14 */
|
||||
#define pitch_0_6 9830 /* 0.6 in Q14 */
|
||||
#define SIZE 64
|
||||
#define SIZE2 32
|
||||
#define NUM_STAGES 5
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Local functions
|
||||
*---------------------------------------------------------------------*/
|
||||
static void phase_dispersion_fx(Word32 gain_code,Word16 gain_pit,Word16 code[],Word16 mode,struct dispMem_fx *dm_fx);
|
||||
static void agc2_fx(const Word16 *sig_in,Word16 *sig_out,const Word16 l_trm);
|
||||
|
||||
/*======================================================================================*/
|
||||
/* FUNCTION : enhancer_fx() */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* PURPOSE : Enhancement of the excitation signal before synthesis */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word32) core_brate : decoder bitrate */
|
||||
/* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode */
|
||||
/* _ (Word16) coder_type : coder type */
|
||||
/* _ (Word16) i_subfr : subframe number */
|
||||
/* _ (Word16) voice_fac : subframe voicing estimation (Q15) */
|
||||
/* _ (Word16) stab_fac : LP filter stablility measure (Q15) */
|
||||
/* _ (Word32) norm_gain_code : normalised innovative cb. gain (Q16) */
|
||||
/* _ (Word16) gain_inov : gain of the unscaled innovation (Q12) */
|
||||
/* _ (Word16) gain_pit_fx : Pitch gain (Q14) */
|
||||
/* _ (Word16) Q_exc : Q of the excitation */
|
||||
/* _ (Word16) Enc : Encoder = 1; decoder = 0 */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*) voice_factors_fx : TBE voicing factor (Q15) */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word32*) gc_threshold : gain code threshold (Q16) */
|
||||
/* _ (Word16*[]) code : innovation (Q12) */
|
||||
/* _ (Word16*[]) exc2 : adapt. excitation/total exc (Q0) */
|
||||
/* _ (struct dispMem_fx*) dm_fx : phase dispersion algorithm memory */
|
||||
/* (a[0]->Q0,a[1]->Q16,a[2-7]->Q14) */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*======================================================================================*/
|
||||
void enhancer_fx(
|
||||
const Word32 core_brate, /* i : decoder bitrate */
|
||||
const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */
|
||||
const Word16 coder_type, /* i : coder type */
|
||||
const Word16 i_subfr, /* i : subframe number */
|
||||
const Word16 L_frame, /* i : frame size */
|
||||
const Word16 voice_fac, /* i : subframe voicing estimation Q15 */
|
||||
const Word16 stab_fac, /* i : LP filter stablility measure Q15 */
|
||||
Word32 norm_gain_code, /* i : normalised innovative cb. gain Q16 */
|
||||
const Word16 gain_inov, /* i : gain of the unscaled innovation Q12 */
|
||||
Word32 *gc_threshold,/* i/o: gain code threshold Q16 */
|
||||
Word16 *code, /* i/o: innovation Q12 */
|
||||
Word16 *exc2, /* i/o: adapt. excitation/total exc. Q_exc*/
|
||||
const Word16 gain_pit, /* i : quantized pitch gain Q14 */
|
||||
struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory */
|
||||
const Word16 Q_exc /* i : Q of the excitation */
|
||||
)
|
||||
{
|
||||
Word16 tmp, fac, *pt_exc2;
|
||||
Word16 i;
|
||||
Word32 L_tmp;
|
||||
Word16 gain_code_hi;
|
||||
Word16 pit_sharp, tmp16;
|
||||
Word16 excp[L_SUBFR], sc;
|
||||
|
||||
pit_sharp = gain_pit;
|
||||
move16(); /* to remove gcc warning */
|
||||
pt_exc2 = exc2 + i_subfr;
|
||||
move16();
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* Phase dispersion to enhance noise at low bit rate
|
||||
*------------------------------------------------------------*/
|
||||
|
||||
i = 2;
|
||||
move16(); /* no dispersion */
|
||||
IF (Opt_AMR_WB)
|
||||
{
|
||||
IF ( L_sub(core_brate,ACELP_6k60) <= 0)
|
||||
{
|
||||
i = 0;
|
||||
move16(); /* high dispersion */
|
||||
}
|
||||
ELSE if ( L_sub(core_brate,ACELP_8k85) <= 0)
|
||||
{
|
||||
i = 1;
|
||||
move16(); /* low dispersion */
|
||||
}
|
||||
}
|
||||
ELSE IF( sub(coder_type,UNVOICED) != 0)
|
||||
|
||||
{
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF ( L_sub(core_brate,ACELP_7k20) <= 0 )
|
||||
{
|
||||
i = 0;
|
||||
move16(); /* high dispersion */
|
||||
}
|
||||
ELSE if ( ( sub(coder_type,GENERIC) == 0 || sub(coder_type,TRANSITION) == 0 || sub(coder_type,AUDIO) == 0 || sub(coder_type,INACTIVE) == 0 ) && L_sub(core_brate,ACELP_9k60) <= 0 )
|
||||
{
|
||||
i = 1;
|
||||
move16(); /* low dispersion */
|
||||
}
|
||||
}
|
||||
phase_dispersion_fx(norm_gain_code, gain_pit, code, i, dm_fx);
|
||||
|
||||
/*------------------------------------------------------------
|
||||
* 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 decreases by 3 dB noise energy variation.
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
/* tmp = 0.5f * (1.0f - voice_fac) */
|
||||
tmp = msu_r(0x40000000, voice_fac, 16384); /*Q15 */ /* 1=unvoiced, 0=voiced */
|
||||
/* fac = stab_fac * tmp */
|
||||
fac = mult(stab_fac, tmp); /*Q15*/
|
||||
|
||||
IF (L_sub(norm_gain_code, *gc_threshold) < 0)
|
||||
{
|
||||
L_tmp = Madd_32_16(norm_gain_code, norm_gain_code, 6226);/*Q16 */
|
||||
L_tmp = L_min(L_tmp, *gc_threshold);/*Q16 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_tmp = Mult_32_16(norm_gain_code, 27536);/*Q16 */
|
||||
L_tmp = L_max(L_tmp, *gc_threshold); /*Q16 */
|
||||
}
|
||||
*gc_threshold = L_tmp;
|
||||
move32(); /*Q16 */
|
||||
|
||||
/* gain_code = (fac * tmp) + (1.0 - fac) * gain_code ==> fac * (tmp - gain_code) + gain_code */
|
||||
L_tmp = L_sub(L_tmp, norm_gain_code); /*Q16 */
|
||||
norm_gain_code = Madd_32_16(norm_gain_code, L_tmp, fac);/*Q16 */
|
||||
|
||||
/* gain_code *= gain_inov - Inverse the normalization */
|
||||
L_tmp = Mult_32_16(norm_gain_code, gain_inov); /*Q13*/ /* gain_inov in Q12 */
|
||||
|
||||
sc = 6;
|
||||
move16();
|
||||
|
||||
gain_code_hi = round_fx(L_shl(L_tmp, add(Q_exc, 3))); /* in Q_exc */
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* pitch enhancer
|
||||
*
|
||||
* - Enhance excitation on voiced. (HP filtering of code)
|
||||
* On voiced signal, filtering of code by a smooth fir HP
|
||||
* filter to decrease energy of code at low frequency.
|
||||
*------------------------------------------------------------*/
|
||||
test();
|
||||
IF( !Opt_AMR_WB && sub(coder_type,UNVOICED) == 0 )
|
||||
{
|
||||
/* Copy(code, exc2, L_SUBFR) */
|
||||
FOR (i = 0; i < L_SUBFR; i++)
|
||||
{
|
||||
pt_exc2[i] = round_fx(L_shl(L_mult(gain_code_hi, code[i]), sc)); /*Q0 */ /* code in Q12 (Q9 for encoder) */
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
test();
|
||||
test();
|
||||
IF ( Opt_AMR_WB && ( L_sub(core_brate,ACELP_8k85) == 0|| L_sub(core_brate,ACELP_6k60) == 0 ) )
|
||||
{
|
||||
pit_sharp = shl(gain_pit, 1); /* saturation can occur here Q14 -> Q15 */
|
||||
|
||||
/* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */
|
||||
IF (sub(pit_sharp, 16384) > 0)
|
||||
{
|
||||
tmp16 = mult(pit_sharp, 8192);
|
||||
FOR (i = 0; i < L_SUBFR; i++)
|
||||
{
|
||||
/* excp[i] = pt_exc2[i] * pit_sharp * 0.25 */
|
||||
excp[i] = mult_r(pt_exc2[i], tmp16);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IF ( sub(L_frame, L_FRAME16k) == 0 )
|
||||
{
|
||||
/* tmp = 0.150 * (1.0 + voice_fac) */
|
||||
/* 0.30=voiced, 0=unvoiced */
|
||||
tmp = mac_r(0x10000000L, voice_fac, 4915);/*Q15 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* tmp = 0.125 * (1.0 + voice_fac) */
|
||||
/* 0.25=voiced, 0=unvoiced */
|
||||
tmp = mac_r(0x10000000L, voice_fac, 4096);/*Q15 */
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* Do a simple noncasual "sharpening": effectively an FIR
|
||||
* filter with coefs [-tmp 1.0 -tmp] where tmp=0...0.25.
|
||||
* This is applied to code and add_fxed to exc2
|
||||
*-----------------------------------------------------------------*/
|
||||
/* pt_exc2[0] += code[0] - tmp * code[1] */
|
||||
L_tmp = L_deposit_h(code[0]); /* if Enc :Q9 * Q15 -> Q25 */
|
||||
L_tmp = L_msu(L_tmp, code[1], tmp); /* Q12 * Q15 -> Q28 */
|
||||
L_tmp = L_shl(L_mult(gain_code_hi, extract_h(L_tmp)), sc);
|
||||
pt_exc2[0] = msu_r(L_tmp, -32768, pt_exc2[0]);
|
||||
move16();/* in Q_exc */
|
||||
|
||||
FOR (i = 1; i < L_SUBFR-1; i++)
|
||||
{
|
||||
/* pt_exc2[i] += code[i] - tmp * code[i-1] - tmp * code[i+1] */
|
||||
L_tmp = L_msu(-32768, code[i], -32768);
|
||||
L_tmp = L_msu(L_tmp, code[i + 1], tmp);
|
||||
tmp16 = msu_r(L_tmp, code[i - 1], tmp);
|
||||
L_tmp = L_shl(L_mult(gain_code_hi, tmp16), sc);
|
||||
pt_exc2[i] = msu_r(L_tmp, -32768, pt_exc2[i]);
|
||||
move16(); /* in Q_exc */
|
||||
}
|
||||
|
||||
/* pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - tmp * code[L_SUBFR-2] */
|
||||
L_tmp = L_deposit_h(code[L_SUBFR - 1]);/*Q28 */
|
||||
L_tmp = L_msu(L_tmp, code[L_SUBFR - 2], tmp);/*Q28 */
|
||||
L_tmp = L_shl(L_mult(gain_code_hi, extract_h(L_tmp)), sc);
|
||||
pt_exc2[L_SUBFR - 1] = msu_r(L_tmp, -32768, pt_exc2[L_SUBFR - 1]);
|
||||
move16();/* in Q_exc */
|
||||
test();
|
||||
test();
|
||||
IF ( Opt_AMR_WB && ( L_sub(core_brate,ACELP_8k85) == 0 || L_sub(core_brate,ACELP_6k60) == 0 ) )
|
||||
{
|
||||
IF (sub(pit_sharp, 16384) > 0)
|
||||
{
|
||||
FOR (i = 0; i < L_SUBFR; i++)
|
||||
{
|
||||
/* excp[i] += pt_exc2[i] */
|
||||
excp[i] = add(excp[i], pt_exc2[i]);
|
||||
move16();
|
||||
}
|
||||
agc2_fx(pt_exc2, excp, L_SUBFR);
|
||||
Copy(excp, pt_exc2, L_SUBFR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*
|
||||
* Enhancement of the excitation signal before synthesis
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
Word16 E_UTIL_enhancer(
|
||||
Word16 voice_fac, /* i : subframe voicing estimation Q15 */
|
||||
Word16 stab_fac, /* i : LP filter stability measure Q15 */
|
||||
Word32 gain_code, /* i : innovative cb. gain 15Q16 */
|
||||
Word16 gain_inov, /* i : gain of the unscaled innovation Q11 */
|
||||
Word32 *gc_threshold, /* i/o: gain code threshold 15Q16 */
|
||||
Word16 *code, /* i/o: innovation(in: Q9) code_exp */
|
||||
Word16 *exc2, /* i/o: adapt. excitation/total exc. */
|
||||
Word16 gain_pit, /* i : Quantized pitch gain 1Q14 */
|
||||
Word32 *prev_gain_code, /* i/o: previous codebook gain 15Q16 */
|
||||
Word16 prev_gain_pit[], /* i/o: previous pitch gain, size=6 1Q14 */
|
||||
Word16 *prev_state, /* i/o: Phase dispersion algorithm memory Q0 */
|
||||
Word16 coder_type, /* i : coder type */
|
||||
Word16 cdk_index, /* i : */
|
||||
Word16 L_subfr, /* i : length of subframe */
|
||||
Word16 L_frame, /* i : frame size */
|
||||
Word16 Q_new
|
||||
)
|
||||
{
|
||||
Word16 disp_mode, i;
|
||||
Word16 tmp, fac, gain;
|
||||
Word32 L_tmp;
|
||||
Word16 code_exp, exc2_exp;
|
||||
Word16 max_cdk_index_uv;
|
||||
|
||||
move16();
|
||||
code_exp = 15-9;
|
||||
exc2_exp = 15-Q_new;
|
||||
gain_inov = shr(gain_inov,1);
|
||||
/*-----------------------------------------------------------------*
|
||||
* Phase dispersion to enhance noise at low bit rates
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
max_cdk_index_uv = 10;
|
||||
move16();
|
||||
if ( sub(L_frame, L_FRAME16k) == 0 )
|
||||
{
|
||||
max_cdk_index_uv = 14;
|
||||
move16();
|
||||
}
|
||||
disp_mode = 2; /* any=off */ move16();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF ( ( (sub(coder_type, VOICED) != 0) && (sub(cdk_index, 2) <= 0) ) || ( (sub(coder_type, UNVOICED) == 0) && (sub(cdk_index, max_cdk_index_uv) <= 0) ) )
|
||||
{
|
||||
disp_mode = 0; /* high */ move16();
|
||||
}
|
||||
ELSE IF ( (sub(coder_type, VOICED) != 0) && (sub(cdk_index, 7) <= 0) )
|
||||
{
|
||||
disp_mode = 1; /* low */ move16();
|
||||
}
|
||||
|
||||
phase_dispersion(gain_code, gain_pit,code, &code_exp, disp_mode, prev_gain_code, prev_gain_pit, prev_state, L_subfr);
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* 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. *
|
||||
*------------------------------------------------------------*/
|
||||
fac = 0;
|
||||
move16();
|
||||
|
||||
/* if gain_code is computed function of energy, noise enhancer is by-passed.*/
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
tmp = msu_r(1073741824l/*0.5f Q31*/, 16384/*0.5f Q15*/, voice_fac); /* 1=unvoiced, 0=voiced */
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
fac = mult_r(stab_fac, tmp); /* fac in Q15 */
|
||||
|
||||
L_tmp = L_add(0,gain_code); /* L_tmp in 15Q16 */
|
||||
|
||||
IF (L_sub(L_tmp,*gc_threshold) < 0)
|
||||
{
|
||||
L_tmp = L_shl(Mpy_32_32(L_tmp, 1277752832l/*1.19f/2.0f Q31*/),1);
|
||||
L_tmp = L_min(L_tmp, *gc_threshold);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_tmp = Mpy_32_32(L_tmp, 1804608000l/*1.0f/1.19f Q31*/);
|
||||
L_tmp = L_max(L_tmp, *gc_threshold);
|
||||
}
|
||||
move32();
|
||||
*gc_threshold = L_tmp; /* in 15Q16 */
|
||||
|
||||
/* gain = ( (fac * L_tmp) + (gain_code - fac*gain_code) ) * gain_inov */
|
||||
/* exponent of L_tmp: 31-16 + 15-11 */
|
||||
L_tmp = Mpy_32_16_1(L_add(Mpy_32_16_1(L_tmp, fac), L_sub(gain_code, Mpy_32_16_1(gain_code, fac))), gain_inov);
|
||||
|
||||
/* exponent gain: 31-16 + 15-11 - tmp */
|
||||
tmp = norm_l(L_tmp);
|
||||
|
||||
/* exponent of code: 31-16 + 15-11 - tmp + code_exp */
|
||||
move16();
|
||||
code_exp = sub(add(31-16 + 15-11, code_exp), tmp);
|
||||
|
||||
L_tmp = L_shl(L_tmp, tmp);
|
||||
gain = round_fx(L_tmp);
|
||||
|
||||
FOR (i=0; i<L_subfr; i++)
|
||||
{
|
||||
code[i] = mult_r(code[i], gain);
|
||||
move16();
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* 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. *
|
||||
*------------------------------------------------------------*/
|
||||
|
||||
/* exponent difference of code and exc2. +1 accounts for headroom required below. */
|
||||
gain = add(sub(code_exp, exc2_exp), 1);
|
||||
|
||||
tmp = mac_r(268435456l/*0.125f Q31*/, 4096/*0.125f Q15*/, voice_fac); /* 0.25=voiced, 0=unvoiced */
|
||||
if ( sub(L_frame, L_FRAME16k) == 0 )
|
||||
{
|
||||
tmp = mac_r(322122560l/*0.150f Q31*/, 4915/*0.150f Q15*/, voice_fac); /* 0.30=voiced, 0=unvoiced */
|
||||
}
|
||||
|
||||
/* exc2[0] = exc2[0] + code[0] - tmp*code[1]; */
|
||||
L_tmp = L_mult(code[0], 16384);
|
||||
L_tmp = L_msu0(L_tmp,tmp,code[1]);
|
||||
if (gain)
|
||||
{
|
||||
L_tmp = L_shl(L_tmp,gain);
|
||||
}
|
||||
exc2[0] = msu_r(L_tmp,-32768, exc2[0]);
|
||||
move16();
|
||||
|
||||
FOR (i=1; i<L_subfr-1; i++)
|
||||
{
|
||||
/* exc2[i] = exc2[i] + code[i] - tmp*(code[i+1]+code[i-1]); */
|
||||
L_tmp = L_mult(code[i], 16384);
|
||||
L_tmp = L_msu0(L_tmp,tmp,code[i-1]);
|
||||
L_tmp = L_msu0(L_tmp,tmp,code[i+1]);
|
||||
if (gain)
|
||||
{
|
||||
L_tmp = L_shl(L_tmp,gain);
|
||||
}
|
||||
exc2[i] = msu_r(L_tmp,-32768, exc2[i]);
|
||||
move16();
|
||||
}
|
||||
/* exc2[L_subfr-1] = exc2[L_subfr-1] + code[L_subfr-1] - tmp*code[L_subfr-2]; */
|
||||
L_tmp = L_mult(code[i], 16384);
|
||||
L_tmp = L_msu0(L_tmp,tmp,code[i-1]);
|
||||
if (gain)
|
||||
{
|
||||
L_tmp = L_shl(L_tmp,gain);
|
||||
}
|
||||
|
||||
exc2[i] = msu_r(L_tmp,-32768, exc2[i]);
|
||||
move16();
|
||||
|
||||
return code_exp;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*
|
||||
* Phase_dispersion:
|
||||
*
|
||||
* post-processing to enhance noise in low bit rate.
|
||||
*-----------------------------------------------------------------------*/
|
||||
/*======================================================================================*/
|
||||
/* FUNCTION : phase_dispersion_fx() */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* PURPOSE : post-processing to enhance noise in low bit rate. */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word32) gain_code : gain of code Q16 */
|
||||
/* _ (Word16) gain_pit : gain of pitch Q14 */
|
||||
/* _ (Word16) mode : level, 0=hi, 1=lo, 2=off */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16[]) code : code vector (Q12) */
|
||||
/* _ (struct dispMem_fx*) dm_fx : static memory (size = 8) */
|
||||
/* (a[0]->Q0,a[1]->Q16,a[2-7]->Q14) */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*======================================================================================*/
|
||||
static void phase_dispersion_fx(
|
||||
Word32 gain_code, /* i : gain of code Q16 */
|
||||
Word16 gain_pit, /* i : gain of pitch Q14 */
|
||||
Word16 code[], /* i/o: code vector */
|
||||
Word16 mode, /* i : level, 0=hi, 1=lo, 2=off */
|
||||
struct dispMem_fx *dm_fx /* i/o: static memory (size = 8) */
|
||||
)
|
||||
{
|
||||
Word16 i, j, state;
|
||||
Word16 *prev_gain_pit, *prev_state;
|
||||
Word32 *prev_gain_code;
|
||||
Word16 *code2_real, *code2_imag;
|
||||
Word16 *code_real, *code_imag;
|
||||
const Word16 *h_real, *h_imag;
|
||||
|
||||
Word16 code2[2 * L_SUBFR];
|
||||
|
||||
prev_state = &(dm_fx->prev_state);
|
||||
prev_gain_code = &(dm_fx->prev_gain_code);
|
||||
prev_gain_pit = dm_fx->prev_gain_pit;
|
||||
|
||||
state = 2;
|
||||
move16();
|
||||
if (sub(gain_pit, pitch_0_9) < 0)
|
||||
{
|
||||
state = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
if (sub(gain_pit, pitch_0_6) < 0)
|
||||
{
|
||||
state = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 5; i > 0; i--)
|
||||
{
|
||||
prev_gain_pit[i] = prev_gain_pit[i - 1];
|
||||
move16();
|
||||
}
|
||||
prev_gain_pit[0] = gain_pit;
|
||||
move16();
|
||||
|
||||
IF (L_sub(L_sub(gain_code, *prev_gain_code), L_shl(*prev_gain_code, 1)) > 0)
|
||||
{
|
||||
state = s_min(add(state, 1), 2);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
j = 0;
|
||||
move16();
|
||||
|
||||
FOR (i = 0; i < 6; i++)
|
||||
{
|
||||
j = sub(j, shr(sub(prev_gain_pit[i], pitch_0_6), 15));
|
||||
}
|
||||
|
||||
if (sub(j, 2) > 0)
|
||||
{
|
||||
state = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
if (sub(sub(state, *prev_state), 1) > 0)
|
||||
{
|
||||
state = sub(state, 1);
|
||||
}
|
||||
}
|
||||
|
||||
*prev_gain_code = gain_code;
|
||||
move32();
|
||||
*prev_state = state;
|
||||
move16();
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* circular convolution
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
state = add(state, mode); /* level of dispersion */
|
||||
|
||||
IF (sub(state, 2) < 0)
|
||||
{
|
||||
r_fft_fx_lc(phs_tbl_dec, SIZE, SIZE2, NUM_STAGES, code, code2, 1);
|
||||
|
||||
h_real = Mid_H_phasedisp;
|
||||
move16();
|
||||
if (state == 0)
|
||||
{
|
||||
h_real = Low_H_phasedisp;
|
||||
move16();
|
||||
}
|
||||
|
||||
/* FFT Coefs are in code2 */
|
||||
code2_real = code2;
|
||||
move16();
|
||||
code2_imag = code2 + L_SUBFR - 1;
|
||||
move16();
|
||||
|
||||
code_real = code;
|
||||
move16();
|
||||
code_imag = code + L_SUBFR - 1;
|
||||
move16();
|
||||
|
||||
h_imag = h_real + L_SUBFR - 1;
|
||||
move16();
|
||||
|
||||
*code_real++ = mult(*code2_real++, *h_real++);
|
||||
move16(); /* DC */
|
||||
|
||||
FOR (i=1; i<L_SUBFR/2; i++)
|
||||
{
|
||||
*code_real++ = msu_r(L_mult(*code2_real, *h_real), *code2_imag, *h_imag);
|
||||
move16();
|
||||
*code_imag-- = mac_r(L_mult(*code2_real, *h_imag), *code2_imag, *h_real);
|
||||
move16();
|
||||
|
||||
code2_real++;
|
||||
h_imag--;
|
||||
h_real++;
|
||||
code2_imag--;
|
||||
}
|
||||
*code_real++ = mult(*code2_real++, *h_real++);
|
||||
move16(); /* DC */
|
||||
|
||||
r_fft_fx_lc(phs_tbl_dec, SIZE, SIZE2, NUM_STAGES, code, code2, 0);
|
||||
|
||||
FOR (i = 0; i < L_SUBFR; i++)
|
||||
{
|
||||
/* saturation can occur here */
|
||||
code[i] = shl(code2[i], 1); /*Q12 */ move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*======================================================================================*/
|
||||
/* FUNCTION : agc2_fx() */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* PURPOSE : AGC post-processing for lower G722.2 modes */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16*[]) sig_in : postfilter input signal (Q0) */
|
||||
/* _ (Word16) l_trm : subframe size */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*[]) sig_out : postfilter output signal (Q0) */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*======================================================================================*/
|
||||
static void agc2_fx(
|
||||
const Word16 *sig_in, /* i : postfilter input signal */
|
||||
Word16 *sig_out, /* i/o: postfilter output signal */
|
||||
const Word16 l_trm /* i : subframe size */
|
||||
)
|
||||
{
|
||||
|
||||
Word16 i, exp;
|
||||
Word16 gain_in, gain_out, g0;
|
||||
Word32 s;
|
||||
|
||||
Word16 temp;
|
||||
|
||||
/* calculate gain_out with exponent */
|
||||
temp = shr(sig_out[0], 2);
|
||||
s = L_mult0(temp, temp);
|
||||
FOR (i = 1; i < l_trm; i++)
|
||||
{
|
||||
temp = shr(sig_out[i], 2);
|
||||
s = L_mac0(s, temp, temp);
|
||||
}
|
||||
IF (s != 0)
|
||||
{
|
||||
exp = sub(norm_l(s), 1);
|
||||
gain_out = round_fx(L_shl(s, exp));
|
||||
|
||||
/* calculate gain_in with exponent */
|
||||
temp = shr(sig_in[0], 2);
|
||||
s = L_mult0(temp, temp);
|
||||
FOR (i = 1; i < l_trm; i++)
|
||||
{
|
||||
temp = shr(sig_in[i], 2);
|
||||
s = L_mac0(s, temp, temp);
|
||||
}
|
||||
|
||||
g0 = 0;
|
||||
move16();
|
||||
IF (s != 0)
|
||||
{
|
||||
i = norm_l(s);
|
||||
gain_in = round_fx(L_shl(s, i));
|
||||
exp = sub(exp, i);
|
||||
|
||||
/*---------------------------------------------------*
|
||||
* g0 = sqrt(gain_in / gain_out)
|
||||
*---------------------------------------------------*/
|
||||
s = L_mult0(128, div_s(gain_out, gain_in)); /* s = gain_out / gain_in */
|
||||
s = L_shr(s, exp); /* add exponent */
|
||||
|
||||
s = Isqrt(s);
|
||||
g0 = round_fx(L_shl(s, 9));
|
||||
}
|
||||
|
||||
/* sig_out(n) = gain(n) sig_out(n) */
|
||||
FOR (i = 0; i < l_trm; i++)
|
||||
{
|
||||
sig_out[i] = round_fx(L_shl(L_mac(-8192, sig_out[i], g0), 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Enr_1_Az_fx_12Q3()
|
||||
*
|
||||
* Find Energy of the 1/A(z) impulse response
|
||||
*-------------------------------------------------------------------*/
|
||||
Word16 Enr_1_Az_fx( /* o : impulse response energy Q3 */
|
||||
const Word16 Aq[], /* i : LP filter coefs Qx based on the fact that Aq[0] == 1.0 */
|
||||
const Word16 len /* i : impulse response length Q0 */
|
||||
)
|
||||
{
|
||||
Word16 h1[2*L_SUBFR];
|
||||
Word16 *y;
|
||||
Word16 i, j, a0, q;
|
||||
Word32 L_tmp, L_tmp2;
|
||||
|
||||
/* Find the impulse response */
|
||||
|
||||
q = sub( 3, norm_s(Aq[0]) );
|
||||
a0 = shr(Aq[0], q); /* Q11 */
|
||||
q = sub(4, q);
|
||||
|
||||
/*-----------------------------------------------------------------------*
|
||||
* Do the filtering (first two iters unrolled to avoid multiplies with 0)
|
||||
*-----------------------------------------------------------------------*/
|
||||
|
||||
y = h1;
|
||||
/* h1_in Q11, h1_out Q10 */
|
||||
L_tmp = L_mult(a0, 1<<13); /* Q25 = L_mult(Q11,Q13) */
|
||||
*y = round_fx(L_tmp); /* Q25 to Q9 */
|
||||
L_tmp2 = L_mult(*y, *y); /* Q19 = L_mult(Q9,Q9) */
|
||||
y++;
|
||||
|
||||
L_tmp = L_msu(0, Aq[1], y[-1]); /* Q23 = L_mult(Q14,Q9) */
|
||||
L_tmp = L_shl(L_tmp, q);
|
||||
*y = round_fx(L_tmp); /* Q25 to Q9 */
|
||||
L_tmp2 = L_mac(L_tmp2, *y, *y); /* Q19 = L_mult(Q9,Q9) */
|
||||
y++;
|
||||
|
||||
/* Skip Zeros */
|
||||
FOR (i = 2; i < M; i++)
|
||||
{
|
||||
L_tmp = L_msu(0, Aq[1], y[-1]);
|
||||
FOR (j = 2; j <= i; j++)
|
||||
{
|
||||
L_tmp = L_msu(L_tmp, Aq[j], y[-j]);
|
||||
}
|
||||
|
||||
L_tmp = L_shl(L_tmp, q);
|
||||
*y = round_fx(L_tmp);
|
||||
L_tmp2 = L_mac(L_tmp2, *y, *y);
|
||||
y++;
|
||||
}
|
||||
/* Normal Filtering */
|
||||
FOR (; i < len; i++)
|
||||
{
|
||||
L_tmp = L_msu(0, Aq[1], y[-1]);
|
||||
FOR (j = 2; j <= M; j++)
|
||||
{
|
||||
L_tmp = L_msu(L_tmp, Aq[j], y[-j]);
|
||||
}
|
||||
|
||||
L_tmp = L_shl(L_tmp, q);
|
||||
*y = round_fx(L_tmp);
|
||||
L_tmp2 = L_mac(L_tmp2, *y, *y);
|
||||
y++;
|
||||
}
|
||||
|
||||
return round_fx(L_tmp2); /* Q19 to Q3 */
|
||||
}
|
||||
Executable
+158
@@ -0,0 +1,158 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required by wmc_tool */
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* env_adj()
|
||||
*
|
||||
* Adjust the band energies of noise-fill and low resolution bands
|
||||
*--------------------------------------------------------------------------*/
|
||||
void env_adj_fx
|
||||
(
|
||||
const Word16 *pulses, /* i : number of pulses per band Q0 */
|
||||
const Word16 length, /* i : length of spectrum Q0 */
|
||||
const Word16 last_sfm, /* i : index of the last band Q0 */
|
||||
Word16 *adj, /* o : adjustment factors for the envelope Q15 */
|
||||
const Word16 env_stab, /* i : envelope stability Q15 */
|
||||
const Word16 *sfmsize /* i : subband sizes Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i, j, group;
|
||||
Word16 npul;
|
||||
Word16 att_state;
|
||||
Word16 start, len;
|
||||
Word16 tmp, tmp_diff;
|
||||
Word16 gain_adj;
|
||||
Word16 idx;
|
||||
|
||||
att_state = 0;
|
||||
move16();
|
||||
len = 0;
|
||||
move16();
|
||||
start = 0;
|
||||
move16();
|
||||
|
||||
/* Find attenuation levels */
|
||||
FOR( i = 0; i <= last_sfm ; i++ )
|
||||
{
|
||||
group = sub(shr(sfmsize[i],3),1);
|
||||
npul = pulses[i];
|
||||
move16();
|
||||
|
||||
IF( sub(length, L_FRAME32k) == 0 )
|
||||
{
|
||||
|
||||
IF( npul == 0 )
|
||||
{
|
||||
/* Noise filled band */
|
||||
IF ( sub(group,1) <= 0 )
|
||||
{
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF ( i > 0 && pulses[i-1] != 0 && pulses[i+1] != 0 )
|
||||
{
|
||||
adj[i] = 11796; /* Q15, 0.36f */ move16();
|
||||
}
|
||||
ELSE IF ( i > 0 && ( pulses[i-1] == 0 || pulses[i+1] == 0) )
|
||||
{
|
||||
adj[i] = 17695; /* Q15, 0.54f */ move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adj[i] = 23593; /* Q15, 0.72f */ move16();
|
||||
}
|
||||
}
|
||||
ELSE IF ( sub(i,last_sfm) < 0 )
|
||||
{
|
||||
test();
|
||||
IF ( pulses[i-1] != 0 && pulses[i+1] != 0 )
|
||||
{
|
||||
adj[i] = 17695; /* Q15, 0.54f */ move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adj[i] = 23593; /* Q15, 0.72f */ move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adj[i] = 23593; /* Q15, 0.72f */ move16();
|
||||
}
|
||||
|
||||
if( att_state == 0 )
|
||||
{
|
||||
start = i;
|
||||
move16();
|
||||
}
|
||||
|
||||
len = add(len,1);
|
||||
move16();
|
||||
att_state = 1;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adj[i] = MAX_16; /* Q15, 1.0f (saturated) */
|
||||
IF( sub(att_state, 1) == 0 ) /* End of attenuation region found */
|
||||
{
|
||||
/* tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL)); */
|
||||
tmp = round_fx(L_shl(L_mult0(s_max( 0, sub(len, ENV_ADJ_START_FX)), ENV_ADJ_INV_INCL_FX),16)); /* Q15 (15+16-16) */
|
||||
tmp_diff = sub(MAX_16, tmp); /* Q15 */ move16();
|
||||
FOR( j = start; j < i ; j++ )
|
||||
{
|
||||
/* adj[j] = max(tmp + (1-tmp)*adj[j],env_stab); */
|
||||
adj[j] = s_max(add(tmp, mult(tmp_diff, adj[j])), env_stab); /* Q15 (15+15-15) */ move16();
|
||||
}
|
||||
len = 0;
|
||||
move16();
|
||||
att_state = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
/* length == L_FRAME16k */
|
||||
ELSE
|
||||
{
|
||||
|
||||
/* Calculate low accuracy band attenuation */
|
||||
gain_adj = 32767; /* Q15, 1.0f (saturated) */ move16();
|
||||
|
||||
test();
|
||||
IF( npul > 0 && sub(npul, MAX_P_ATT) < 0 )
|
||||
{
|
||||
/*idx = (short)(npul * att_step[group] + 0.5f) - 1; */
|
||||
idx = sub(mult_r(shl(npul,2),att_step_fx[group]), 1); /* Q0 (2+13+1-16) */
|
||||
if( sub(idx, MAX_P_ATT) < 0 )
|
||||
{
|
||||
gain_adj = gain_att_fx[idx]; /* Q15 */ move16();
|
||||
}
|
||||
}
|
||||
adj[i] = gain_adj;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the sequence ended with an attenuation region */
|
||||
IF( sub(att_state, 1) == 0 )
|
||||
{
|
||||
/* tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL)); */
|
||||
tmp = round_fx(L_shl(L_mult0(s_max( 0, sub(len, ENV_ADJ_START_FX)), ENV_ADJ_INV_INCL_FX),16)); /* Q15 (15+16-16) */
|
||||
tmp_diff = sub(MAX_16, tmp); /* Q15 */ move16();
|
||||
FOR( j = start; j < i ; j++ )
|
||||
{
|
||||
|
||||
/* adj[j] = max(tmp + (1-tmp)*adj[j],env_stab); */
|
||||
adj[j] = s_max(add(tmp, mult(tmp_diff, adj[j])), env_stab); /* Q15 (15+15-15) */ move16();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+188
@@ -0,0 +1,188 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "stl.h" /* required by wmc_tool */
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*--------------------------------------------------------------------------*/
|
||||
#define ENV_STAB_SMO_HO 10 /* number of hangover frames when switching from music to speech state */
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Function env_stability_fx */
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~ */
|
||||
/* */
|
||||
/* Envelope stability measure */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
Word16 env_stability_fx( /* in Q15 */
|
||||
const Word16 *ynrm, /*i: Norm vector for current frame */
|
||||
const Word16 nb_sfm, /*i: Number of sub-bands */
|
||||
Word16 *mem_norm, /*i/o: Norm vector memory from past frame */
|
||||
Word16 *mem_env_delta /*i/o: Envelope stability memory for smoothing in Q12 */
|
||||
)
|
||||
{
|
||||
Word16 env_delta;
|
||||
Word16 env_stab;
|
||||
Word16 tmp, tmp_stab;
|
||||
Word16 i;
|
||||
|
||||
Word16 exp, exp2;
|
||||
Word32 L_tmp, L_env_delta;
|
||||
Word16 inv_nb_sfm;
|
||||
|
||||
/* Calculate envelope stability parameter */
|
||||
L_env_delta = L_deposit_l(0);
|
||||
FOR (i = 0; i < nb_sfm; i++)
|
||||
{
|
||||
tmp = sub(mem_norm[i],ynrm[i]);
|
||||
L_env_delta = L_mac0(L_env_delta, tmp, tmp);
|
||||
mem_norm[i] = ynrm[i];
|
||||
move16();
|
||||
}
|
||||
|
||||
inv_nb_sfm = 19418; /* Q19 */ move16();
|
||||
if (nb_sfm == 26)
|
||||
{
|
||||
inv_nb_sfm = 20165; /* Q19 */ move16();
|
||||
}
|
||||
exp = norm_l(L_env_delta);
|
||||
L_env_delta = Mult_32_16(L_shl(L_env_delta, exp), inv_nb_sfm); /* 0+exp+19-15 */
|
||||
|
||||
L_tmp = Sqrt_l(L_env_delta, &exp2); /* exp+4+31+exp2 */
|
||||
|
||||
exp = add(35, add(exp, exp2));
|
||||
if ( sub(s_and(exp, 1), 1) == 0 )
|
||||
{
|
||||
L_tmp = Mult_32_16(L_tmp, 23170); /* 1/sqrt(2) in Q15 */
|
||||
}
|
||||
exp = shr(exp, 1);
|
||||
|
||||
env_delta = round_fx(L_shl(L_tmp, sub(26, exp))); /* Q10 */
|
||||
|
||||
L_tmp = L_mult0(26214, env_delta); /* 26214 is 0.1 in Q18. Q28 */
|
||||
L_tmp = L_mac(L_tmp, 29491, *mem_env_delta); /* 29491 is 0.9 in Q15. Q28 */
|
||||
|
||||
*mem_env_delta = round_fx(L_tmp); /* Q12 */
|
||||
Overflow = 0;
|
||||
move16();
|
||||
env_delta = round_fx(L_shl(L_tmp, 1)); /* Q13 */
|
||||
|
||||
IF (Overflow != 0) /* Saturated due to the above up-shifting operation. */
|
||||
{
|
||||
return stab_trans_fx[L_STAB_TBL-1]; /* The highest quantized index. */
|
||||
}
|
||||
|
||||
/* If tmp_stab > (D_STAB_TBL*L_STAB_TBL + M_STAB_TBL), i.e., 0.103138*10+2.51757=3.603137,
|
||||
* the quantized index is equal to 9. Hence, we only need to worry about any tmpStab < 4.
|
||||
* In this case, Q13 is good enough.
|
||||
*/
|
||||
tmp_stab = sub(env_delta, M_STAB_TBL_FX); /* in Q13 */
|
||||
tmp_stab = abs_s(tmp_stab);
|
||||
|
||||
/* Table lookup for smooth transitions
|
||||
* First, find the quantization level, i, of tmpStab. */
|
||||
#if L_STAB_TBL > 10
|
||||
#error env_stability_fx: Use more efficient usquant()
|
||||
#endif
|
||||
tmp_stab = sub(tmp_stab, HALF_D_STAB_TBL_FX); /* in Q13 */
|
||||
FOR (i = 0; i < L_STAB_TBL-1; i++)
|
||||
{
|
||||
IF (tmp_stab < 0)
|
||||
{
|
||||
BREAK;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp_stab = sub(tmp_stab, D_STAB_TBL_FX); /* in Q13 */
|
||||
}
|
||||
}
|
||||
|
||||
env_stab = stab_trans_fx[i];
|
||||
move16();
|
||||
if(sub(env_delta, M_STAB_TBL_FX) < 0)
|
||||
{
|
||||
env_stab = sub(0x7FFF,stab_trans_fx[i]);
|
||||
}
|
||||
|
||||
return env_stab;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* env_stab_smo_fx()
|
||||
*
|
||||
*
|
||||
*--------------------------------------------------------------------------*/
|
||||
Word16 env_stab_smo_fx( /* Q0 */
|
||||
Word16 env_stab, /*i : env_stab value Q15 */
|
||||
Word16 *env_stab_state_p, /*i/o: env_stab state probabilities Q15 */
|
||||
Word16 *ho_cnt /*i/o: hangover counter for speech state */
|
||||
)
|
||||
{
|
||||
Word16 state, prev_state;
|
||||
Word16 maxval, pp[NUM_ENV_STAB_PLC_STATES], pa[NUM_ENV_STAB_PLC_STATES];
|
||||
Word16 i;
|
||||
Word16 tmp, sum, exp;
|
||||
|
||||
/* get previous state */
|
||||
prev_state = maximum_fx(env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval);
|
||||
|
||||
/* assume two states: speech(0), music(1) */
|
||||
/* set a posteriori likelihoods for the two states according to env_stab */
|
||||
/* re-scale. Unclear if needed */
|
||||
/* env_stab = (env_stab - stab_trans_fx[L_STAB_TBL-1])/(1-2*stab_trans_fx[L_STAB_TBL-1]); */
|
||||
tmp = sub(env_stab, stab_trans_fx[L_STAB_TBL-1]);
|
||||
tmp = round_fx(L_shl(L_mult(tmp, INV_STAB_TRANS_FX), 1)); /* Q15 */
|
||||
|
||||
pp[0] = sub(32767, tmp);
|
||||
move16(); /* 1 in Q15 */
|
||||
pp[1] = tmp;
|
||||
move16();
|
||||
|
||||
/* calculate a priori likelihoods */
|
||||
pa[0] = round_fx(Dot_product(env_stab_tp_fx[0], env_stab_state_p, NUM_ENV_STAB_PLC_STATES)); /* Q15*/
|
||||
pa[1] = round_fx(Dot_product(env_stab_tp_fx[1], env_stab_state_p, NUM_ENV_STAB_PLC_STATES));
|
||||
|
||||
/* multiply elementwise with a posteriori likelihoods */
|
||||
sum = 0;
|
||||
move16();
|
||||
FOR (i = 0; i < NUM_ENV_STAB_PLC_STATES; i++)
|
||||
{
|
||||
env_stab_state_p[i] = mult_r(pa[i], pp[i]);
|
||||
move16(); /* Q15 */
|
||||
sum = add(sum, env_stab_state_p[i]);
|
||||
}
|
||||
|
||||
/* renormalize state probabilities */
|
||||
exp = norm_s(sum);
|
||||
tmp = div_s(16384, shl(sum, exp)); /* Q(14-exp) */
|
||||
/*tmp = shl(tmp, add(exp, 1));*/ /* Q15 */
|
||||
FOR (i = 0; i < NUM_ENV_STAB_PLC_STATES; i++)
|
||||
{
|
||||
env_stab_state_p[i] = round_fx(L_shl(L_mult(env_stab_state_p[i], tmp), add(exp, 1))); /* Q15 */
|
||||
}
|
||||
|
||||
/* find maximum index as return value */
|
||||
state = maximum_fx(env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval);
|
||||
|
||||
/* apply some hangover for speech */
|
||||
test();
|
||||
if (state == 0 && sub(prev_state, 1) == 0)
|
||||
{
|
||||
*ho_cnt = ENV_STAB_SMO_HO;
|
||||
move16();
|
||||
}
|
||||
|
||||
IF (*ho_cnt > 0)
|
||||
{
|
||||
*ho_cnt = sub(*ho_cnt, 1);
|
||||
move16();
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "math_op.h" /* WMOPS macros */
|
||||
#include "stl.h" /* required by wmc_tool */
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* env_stab_transient_detect()
|
||||
*
|
||||
* Transient detector for envelope stability measure
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void env_stab_transient_detect_fx(
|
||||
const Word16 is_transient, /* i: Transient flag */
|
||||
const Word16 length, /* i : Length of spectrum (32 or 48 kHz) */
|
||||
const Word16 norm[], /* i : quantization indices for norms */
|
||||
Word16 *no_att_hangover, /* i/o: Frame counter for attenuation hangover (Q0) */
|
||||
Word32 *L_energy_lt, /* i/o: Long-term energy measure for transient detection (Q13) */
|
||||
const Word16 HQ_mode, /* i : HQ coding mode */
|
||||
const Word16 bin_th, /* i : HVQ cross-over frequency bin */
|
||||
const Word32 *L_coeff, /* i : Coded spectral coefficients */
|
||||
const Word16 Qcoeff /* i : Q of coded spectral coefficients */
|
||||
)
|
||||
{
|
||||
Word16 i, blk, norm_ind, sqrt_exp, bin_th_1, temp, sh;
|
||||
Word32 L_e_frame, L_temp, L_d_max;
|
||||
Word32 L_energy_lt_local;
|
||||
Word32 L_E_sub[4];
|
||||
Word32 L_delta_e_sub;
|
||||
|
||||
L_energy_lt_local = *L_energy_lt;
|
||||
move32();
|
||||
|
||||
L_d_max = L_deposit_l(0);
|
||||
L_e_frame = L_deposit_l(0);
|
||||
temp = 32;
|
||||
move16();
|
||||
|
||||
IF( sub(HQ_mode,HQ_HVQ) == 0 )
|
||||
{
|
||||
FOR (i = 0; i < bin_th; i++) /* find adaptive shift */
|
||||
{
|
||||
temp = s_min(temp,norm_l(L_coeff[i]));
|
||||
}
|
||||
sh = sub(temp,2); /* scale such that 2 msbs are not used, the resulting adaptive Qcoeff will be: Qcoeff+sh-16 */
|
||||
FOR (i = 0; i < bin_th; i++) /* Maximum number of loop runs 320 */
|
||||
{
|
||||
temp = extract_h(L_shl(L_coeff[i],sh));
|
||||
L_e_frame = L_mac(L_e_frame,temp,temp); /* Q(2*(Qcoeff+sh-16)+1)=Q(2*(Qcoeff+sh)-31 */
|
||||
}
|
||||
|
||||
bin_th_1 = INV_HVQ_THRES_BIN_24k;
|
||||
move16();
|
||||
if (sub(bin_th, HVQ_THRES_BIN_32k) == 0)
|
||||
{
|
||||
bin_th_1 = INV_HVQ_THRES_BIN_32k;
|
||||
move16();
|
||||
}
|
||||
L_temp = Mult_32_16(L_e_frame,bin_th_1); /* Q(2*(Qcoeff-16+sh)+1+21-15) -> Q(2*(Qcoeff+sh)-25) */
|
||||
L_e_frame = Sqrt_l(L_temp,&sqrt_exp);
|
||||
L_e_frame = L_shr(L_e_frame, add(sub(add(sh,Qcoeff),10),shr(sqrt_exp,1))); /* Adjust by (Qcoeff+sh-10) to fixed Q13: Qcoeff+sh+(-25+31)/2 - (Qcoeff+sh-10) -> Q13 */
|
||||
|
||||
IF ( L_sub(L_e_frame, ENERGY_TH_FX) > 0 )
|
||||
{
|
||||
L_energy_lt_local = Mult_32_16(*L_energy_lt, ENERGY_LT_BETA_FX);
|
||||
L_temp = Mult_32_16(L_e_frame, ENERGY_LT_BETA_1_FX);
|
||||
*L_energy_lt = L_add(L_energy_lt_local,L_temp);
|
||||
move32();
|
||||
}
|
||||
|
||||
IF (*no_att_hangover > 0)
|
||||
{
|
||||
(*no_att_hangover) = sub((*no_att_hangover), 1);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_e_frame = L_deposit_l(0);
|
||||
|
||||
test();
|
||||
IF (is_transient && sub(length,L_FRAME32k) == 0)
|
||||
{
|
||||
/* Measure subframe energies */
|
||||
FOR (blk = 0; blk < NUM_SUBFRAMES; blk++)
|
||||
{
|
||||
L_E_sub[blk] = L_deposit_l(0); /* Q9 */
|
||||
|
||||
FOR (i=0; i<BANDS_PER_SUBFRAMES; i++) /* 9 times -> < 2^4 */
|
||||
{
|
||||
norm_ind = subf_norm_groups_fx[blk][i];
|
||||
move16();
|
||||
L_E_sub[blk] = L_add(L_E_sub[blk],L_shr(dicn_fx[norm[norm_ind]],4));
|
||||
move32(); ; /* Q10 */
|
||||
}
|
||||
|
||||
L_E_sub[blk] = Mult_32_16(L_E_sub[blk], INV_BANDS_PER_SUBFRAMES);
|
||||
move32(); /* Q(10+17-15) -> Q12 */
|
||||
|
||||
L_e_frame = L_add(L_e_frame,L_E_sub[blk]); /* Q12 */
|
||||
}
|
||||
|
||||
/* Test for transient */
|
||||
/* if (e_frame > ENERGY_TH * NUM_SUBFRAMES) */
|
||||
IF (L_sub(L_e_frame, ENERGY_TH_NUM_SUBFRAMES) > 0)
|
||||
{
|
||||
FOR (blk = 0; blk < NUM_SUBFRAMES-1; blk++)
|
||||
{
|
||||
L_delta_e_sub = L_sub(L_E_sub[blk+1],L_E_sub[blk]); /* Q12 */
|
||||
if (L_sub(L_delta_e_sub,L_d_max)>0)
|
||||
{
|
||||
L_d_max = L_add(L_delta_e_sub,0); /* L_d_max is NOT normalized with *energy_lt */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* Update long-term energy measure */
|
||||
L_e_frame = L_deposit_l(0); /* Q9 */
|
||||
FOR (i = 0; i < SFM_N_ENV_STAB; i++) /* 27 times -> < 2^5 */
|
||||
{
|
||||
L_e_frame = L_add(L_e_frame,L_shr(dicn_fx[norm[i]],5));
|
||||
/* Q9 */
|
||||
}
|
||||
|
||||
L_e_frame = Mult_32_16(L_e_frame, INV_SFM_N_ENV_STAB); /* Q(9+19-15) -> Q13 */
|
||||
|
||||
IF ( L_sub(L_e_frame, ENERGY_TH_FX) > 0 )
|
||||
{
|
||||
L_energy_lt_local = Mult_32_16(*L_energy_lt, ENERGY_LT_BETA_FX);
|
||||
L_temp = Mult_32_16(L_e_frame, ENERGY_LT_BETA_1_FX);
|
||||
*L_energy_lt = L_add(L_energy_lt_local,L_temp);
|
||||
move32();
|
||||
}
|
||||
}
|
||||
|
||||
/* Add hang-over for conservative application of stability dependent attenuation */
|
||||
/* -> Note: L_d_max not normalized with *energy_lt */
|
||||
/* Hence, we compare L_d_max/DELTA_TH with *energy_lt */
|
||||
IF (L_sub(Mult_32_16(L_d_max, INV_DELTA_TH),L_energy_lt_local) > 0) /* Q13 = Q(12 + 16 -15) */
|
||||
{
|
||||
*no_att_hangover = ATT_LIM_HANGOVER;
|
||||
move16();
|
||||
}
|
||||
ELSE if (*no_att_hangover > 0)
|
||||
{
|
||||
*no_att_hangover = sub(*no_att_hangover,1);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Executable
+265
@@ -0,0 +1,265 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
#include "basop_mpy.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
|
||||
/*======================================================================*/
|
||||
/* FUNCTION : est_tilt_fx() */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PURPOSE : Estimate spectral tilt based on the relative E of adaptive */
|
||||
/* and innovative excitations */
|
||||
/* */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16 *) exc : adaptive excitation vector Q0 */
|
||||
/* _ (Word16) gain_pit : adaptive gain Q14 */
|
||||
/* _ (Word16 *) code : algebraic exctitation vector Q12 */
|
||||
/* _ (Word32) gain_code : algebraic code gain Q16 */
|
||||
/* _ (Word16) Q_exc : Scaling factor of excitation Q0 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16 *) voice_fac : voicing factor Q15 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* INPUT OUTPUT ARGUMENTS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ (Word16) tolt_code : tilt of the code Q15 */
|
||||
/*=======================================================================*/
|
||||
Word16 est_tilt_fx( /* o : tilt of the code Q15 */
|
||||
const Word16 *exc, /* i : adaptive excitation vector Qx */
|
||||
const Word16 gain_pit, /* i : adaptive gain Q14 */
|
||||
const Word16 *code, /* i : algebraic exctitation vector Q9 */
|
||||
const Word32 gain_code, /* i : algebraic code gain Q16 */
|
||||
Word16 *voice_fac, /* o : voicing factor Q15 */
|
||||
const Word16 Q_exc /* i : Scaling factor of excitation Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i, tmp, exp, ener1, exp1, ener2, exp2;
|
||||
Word32 L_tmp;
|
||||
Word16 tilt_code;
|
||||
|
||||
ener1 = extract_h(Dot_product12(exc, exc, L_SUBFR, &exp1));
|
||||
exp1 = sub(exp1, add(Q_exc, Q_exc));
|
||||
L_tmp = L_mult(gain_pit, gain_pit); /* energy of pitch excitation */
|
||||
exp = norm_l(L_tmp);
|
||||
tmp = extract_h(L_shl(L_tmp, exp));
|
||||
ener1 = mult(ener1, tmp);
|
||||
exp1 = sub(sub(exp1, exp), 10); /* 10 -> gain_pit Q14 to Q9 */
|
||||
|
||||
ener2 = extract_h(Dot_product12(code, code, L_SUBFR, &exp2));
|
||||
|
||||
exp = norm_l(gain_code);
|
||||
tmp = extract_h(L_shl(gain_code, exp));
|
||||
tmp = mult(tmp, tmp); /* energy of innovative code excitation */
|
||||
ener2 = mult(ener2, tmp);
|
||||
exp2 = sub(exp2, add(exp, exp));
|
||||
|
||||
i = sub(exp1, exp2);
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
ener1 = shr(ener1, sub(1, s_min(i, 0)));
|
||||
ener2 = shr(ener2, add(s_max(0, i), 1));
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
tmp = sub(ener1, ener2);
|
||||
ener1 = add(add(ener1, ener2), 1);
|
||||
|
||||
/* find voice factor (1=voiced, -1=unvoiced) */
|
||||
exp = div_s(abs_s(tmp), ener1);
|
||||
if (tmp < 0)
|
||||
{
|
||||
exp = negate(exp);
|
||||
}
|
||||
*voice_fac = exp;
|
||||
move16();
|
||||
|
||||
/* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */
|
||||
|
||||
/* tilt_code = (float)(0.25*(1.0 + *voice_fac)) */
|
||||
tilt_code = mac_r(8192L*65536-0x8000, *voice_fac, 8192); /*Q15 */
|
||||
|
||||
return tilt_code;
|
||||
}
|
||||
/*-------------------------------------------------------------------*
|
||||
* Est_tilt2:
|
||||
*
|
||||
* Estimate spectral tilt based on the relative E of adaptive
|
||||
* and innovative excitations
|
||||
*-------------------------------------------------------------------*/
|
||||
Word16 Est_tilt2( /* o : tilt of the code */
|
||||
const Word16 *exc, /* i : adaptive excitation vector Qx */
|
||||
const Word16 gain_pit, /* i : adaptive gain Q14 */
|
||||
const Word16 *code, /* i : algebraic exctitation vector Q9 */
|
||||
const Word32 gain_code, /* i : algebraic code gain Q16 */
|
||||
Word16 *voice_fac, /* o : voicing factor Q15 */
|
||||
const Word16 Q_exc /* i : Scaling factor of excitation Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i, tmp, exp, ener1, exp1, ener2, exp2;
|
||||
Word32 L_tmp;
|
||||
Word16 tilt_code;
|
||||
|
||||
/* Scale exc to avoid overflow */
|
||||
ener1 = extract_h(Energy_scale(exc, L_SUBFR, Q_exc, &exp1));
|
||||
|
||||
exp1 = sub(exp1, add(Q_exc, Q_exc));
|
||||
L_tmp = L_mult(gain_pit, gain_pit); /* energy of pitch excitation */
|
||||
exp = norm_l(L_tmp);
|
||||
tmp = extract_h(L_shl(L_tmp, exp));
|
||||
ener1 = mult(ener1, tmp);
|
||||
exp1 = sub(sub(exp1, exp), 10); /* 10 -> gain_pit Q14 to Q9 */
|
||||
|
||||
ener2 = extract_h(Dot_product12(code, code, L_SUBFR, &exp2));
|
||||
|
||||
exp = norm_l(gain_code);
|
||||
tmp = extract_h(L_shl(gain_code, exp));
|
||||
tmp = mult(tmp, tmp); /* energy of innovative code excitation */
|
||||
ener2 = mult(ener2, tmp);
|
||||
exp2 = sub(exp2, add(exp, exp));
|
||||
|
||||
i = sub(exp1, exp2);
|
||||
ener1 = shr(ener1, sub(1, s_min(i, 0)));
|
||||
ener2 = shr(ener2, add(s_max(0, i), 1));
|
||||
|
||||
tmp = sub(ener1, ener2);
|
||||
ener1 = add(add(ener1, ener2), 1);
|
||||
|
||||
/* find voice factor (1=voiced, -1=unvoiced) */
|
||||
exp = div_s(abs_s(tmp), ener1);
|
||||
if (tmp < 0)
|
||||
{
|
||||
exp = negate(exp);
|
||||
}
|
||||
*voice_fac = exp;
|
||||
move16();
|
||||
|
||||
/* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */
|
||||
|
||||
/* tilt_code = (float)(0.25*(1.0 + *voice_fac)) */
|
||||
tilt_code = mac_r(8192L*65536-0x8000, *voice_fac, 8192);
|
||||
|
||||
return tilt_code;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*
|
||||
* Find voice factor and tilt code *
|
||||
*---------------------------------------------------------*/
|
||||
void E_UTIL_voice_factor( Word16 *exc, /* i : pointer to the excitation frame Q_new */
|
||||
Word16 i_subfr, /* i : subframe index */
|
||||
Word16 *code, /* i : innovative codebook Q9 */
|
||||
Word16 gain_pit, /* i : adaptive codebook gain 1Q14 */
|
||||
Word32 gain_code, /* i : innovative cb. gain 15Q16 */
|
||||
Word16 *voice_fac, /* o : subframe voicing estimation Q15 */
|
||||
Word16 *tilt_code, /* o : tilt factor Q15 */
|
||||
Word16 L_subfr, /* i : subframe length */
|
||||
Word16 flag_tilt, /* i : Flag for triggering new voice factor tilt*/
|
||||
Word16 Q_new, /* i : excitation buffer format */
|
||||
Word16 shift /* i : scaling to get 12bit */
|
||||
)
|
||||
{
|
||||
Word16 i, e, e2, stmp, exp_ener, fac;
|
||||
Word32 ener, tmp, num;
|
||||
|
||||
BASOP_SATURATE_ERROR_ON;
|
||||
|
||||
IF(shift != 0)
|
||||
{
|
||||
fac = shl(0x4000,add(1,shift));
|
||||
/* energy of pitch excitation */
|
||||
stmp = mult_r(exc[0+i_subfr], fac); /* remove fac bits */
|
||||
ener = L_mac0(0L,stmp, stmp);
|
||||
FOR (i=1; i<L_subfr; i++)
|
||||
{
|
||||
stmp = mult_r(exc[i+i_subfr], fac); /* remove fac bits */
|
||||
ener = L_mac0(ener, stmp, stmp);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
ener = L_mult0(exc[0+i_subfr], exc[0+i_subfr]);
|
||||
FOR (i=1; i<L_subfr; i++)
|
||||
{
|
||||
ener = L_mac0(ener, exc[i+i_subfr], exc[i+i_subfr]); /* Q_new -> exponent = (15-Q_new)*2+1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* exponent of ener: (2*(15-Q_new+shift)+1+2-exp_ener-2*e2) */
|
||||
exp_ener = norm_l(ener);
|
||||
if(ener == 0)
|
||||
{
|
||||
exp_ener = 31;
|
||||
move16();
|
||||
}
|
||||
ener = L_shl(ener,exp_ener);
|
||||
e2 = norm_s(gain_pit);
|
||||
gain_pit = shl(gain_pit,e2);
|
||||
ener = Mpy_32_16_1(ener, mult_r(gain_pit, gain_pit));
|
||||
|
||||
|
||||
/* energy of innovative code excitation */
|
||||
tmp = L_deposit_l(1);
|
||||
|
||||
FOR (i=0; i<L_subfr; i++)
|
||||
{
|
||||
tmp = L_mac0(tmp, code[i], code[i]); /* 6Q9 -> 13Q18 */
|
||||
}
|
||||
/* exponent of tmp: 2*(15-9)+1+2*(15-e)) */
|
||||
e = norm_l(gain_code);
|
||||
gain_code = L_shl(gain_code, e);
|
||||
tmp = Mpy_32_32(tmp, Mpy_32_32(gain_code,gain_code));
|
||||
|
||||
/* find voice factor (1=voiced, -1=unvoiced) */
|
||||
/*i = (2*(15-Q_new+shift)+1+2-exp_ener-2*e2) - (2*(15-9)+1 + 2*(15-e));*/
|
||||
i = sub(sub(sub(sub(sub(33,add(shift,shift)),add(Q_new,Q_new)),exp_ener),add(e2,e2)),sub(43,add(e,e)));
|
||||
IF(i >= 0)
|
||||
{
|
||||
ener = L_shr(ener,1);
|
||||
tmp = L_shr(tmp, add(1,i));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp = L_shr(tmp,1);
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
ener = L_shr(ener, sub(1,i));
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
}
|
||||
|
||||
*voice_fac = 0;
|
||||
move16();
|
||||
num = L_sub(ener, tmp);
|
||||
IF(num != 0)
|
||||
{
|
||||
BASOP_SATURATE_WARNING_OFF /* Allow saturating the voice factor because if has a limited range by definition. */
|
||||
*voice_fac = divide3232(num, L_add(ener, tmp));
|
||||
move16();
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
}
|
||||
|
||||
/* find tilt of code for next subframe */
|
||||
IF (flag_tilt==0)
|
||||
{
|
||||
/*Between 0 (=unvoiced) and 0.5 (=voiced)*/
|
||||
move16();
|
||||
*tilt_code = add(8192/*0.25f Q15*/, mult_r(8192/*0.25f Q15*/, *voice_fac));
|
||||
}
|
||||
ELSE IF (flag_tilt==1)
|
||||
{
|
||||
/*Between 0.25 (=unvoiced) and 0.5 (=voiced)*/
|
||||
move16();
|
||||
*tilt_code = add(mult_r(4096/*0.125f Q15*/, *voice_fac), 12288/*0.125f+0.25f Q15*/);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/*Between 0.28 (=unvoiced) and 0.56 (=voiced)*/
|
||||
move16();
|
||||
*tilt_code = add(mult_r(4588/*0.14f Q15*/, *voice_fac), 13763/*0.14f+0.28f Q15*/);
|
||||
}
|
||||
BASOP_SATURATE_ERROR_OFF;
|
||||
}
|
||||
Executable
+1809
File diff suppressed because it is too large
Load Diff
Executable
+3827
File diff suppressed because it is too large
Load Diff
Executable
+2832
File diff suppressed because it is too large
Load Diff
Executable
+431
@@ -0,0 +1,431 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* This is an implementation of decimation-in-time FFT algorithm for
|
||||
* real sequences. The techniques used here can be found in several
|
||||
* books, e.g., i) Proakis and Manolakis, "Digital Signal Processing",
|
||||
* 2nd Edition, Chapter 9, and ii) W.H. Press et. al., "Numerical
|
||||
* Recipes in C", 2nd Edition, Chapter 12.
|
||||
*
|
||||
* Input - There are two inputs to this function:
|
||||
*
|
||||
* 1) An integer pointer to the input data array
|
||||
* 2) An integer value which should be set as +1 for FFT
|
||||
* and some other value, e.g., -1 for ifFT
|
||||
*
|
||||
* Output - There is no return value.
|
||||
* The input data are replaced with transformed data. if the
|
||||
* input is a real time domain sequence, it is replaced with
|
||||
* the complex FFT for positive frequencies. The FFT value
|
||||
* for DC and the foldover frequency are combined to form the
|
||||
* first complex number in the array. The remaining complex
|
||||
* numbers correspond to increasing frequencies. if the input
|
||||
* is a complex frequency domain sequence arranged as above,
|
||||
* it is replaced with the corresponding time domain sequence.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* 1) This function is designed to be a part of a noise supp-
|
||||
* ression algorithm that requires 128-point FFT of real
|
||||
* sequences. This is achieved here through a 64-point
|
||||
* complex FFT. Consequently, the FFT size information is
|
||||
* not transmitted explicitly. However, some flexibility
|
||||
* is provided in the function to change the size of the
|
||||
* FFT by specifying the size information through "define"
|
||||
* statements.
|
||||
*
|
||||
* 2) The values of the complex sinusoids used in the FFT
|
||||
* algorithm are computed once (i.e., the first time the
|
||||
* r_fft function is called) and stored in a table. To
|
||||
* further speed up the algorithm, these values can be
|
||||
* precomputed and stored in a ROM table in actual DSP
|
||||
* based implementations.
|
||||
*
|
||||
* 3) In the c_fft function, the FFT values are divided by
|
||||
* 2 after each stage of computation thus dividing the
|
||||
* final FFT values by 64. No multiplying factor is used
|
||||
* for the ifFT. This is somewhat different from the usual
|
||||
* definition of FFT where the factor 1/N, i.e., 1/64, is
|
||||
* used for the ifFT and not the FFT. No factor is used in
|
||||
* the r_fft function.
|
||||
*
|
||||
* 4) Much of the code for the FFT and ifFT parts in r_fft
|
||||
* and c_fft functions are similar and can be combined.
|
||||
* They are, however, kept separate here to speed up the
|
||||
* execution.
|
||||
*------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------*
|
||||
* c_fft_fx:
|
||||
*
|
||||
* Computes the complex part of the split-radix FFT
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
static void c_fft_fx(
|
||||
const Word16 *phs_tbl, /* i : Table of phases */
|
||||
Word16 SIZE, /* i : Size of the FFT */
|
||||
Word16 NUM_STAGE, /* i : Number of stages */
|
||||
const Word16 *in_ptr, /* i : coefficients in the order re[0], re[n/2], re[1], im[1], ..., re[n/2-1], im[n/2-1] */
|
||||
Word16 *out_ptr, /* o : coefficients in the order re[0], re[n/2], re[1], im[1], ..., re[n/2-1], im[n/2-1] */
|
||||
/* in_ptr & out_ptr must not overlap! */
|
||||
const Word16 isign) /* i : 1=fft, otherwise it is ifft*/
|
||||
{
|
||||
Word16 i, j, k, ii, jj, kk, ji, kj;
|
||||
Word32 L_tmp1, L_tmp2;
|
||||
Word16 tmp1,tmp2,tmp3,tmp4;
|
||||
const Word16 *table_ptr;
|
||||
const Word16 *input_ptr1,*input_ptr2,*input_ptr3,*input_ptr4;
|
||||
|
||||
/* Setup Reorder Variables */
|
||||
table_ptr = NULL;
|
||||
SWITCH (SIZE)
|
||||
{
|
||||
case 1024:
|
||||
table_ptr = FFT_REORDER_1024;
|
||||
BREAK;
|
||||
case 512:
|
||||
table_ptr = FFT_REORDER_512;
|
||||
BREAK;
|
||||
case 256:
|
||||
table_ptr = FFT_reorder_256;
|
||||
BREAK;
|
||||
case 128:
|
||||
table_ptr = FFT_REORDER_128;
|
||||
BREAK;
|
||||
case 64:
|
||||
table_ptr = FFT_reorder_64;
|
||||
BREAK;
|
||||
}
|
||||
/* The FFT part */
|
||||
IF (isign != 0)
|
||||
{
|
||||
/* Unrolled 1st/2nd Stage
|
||||
* 1) to take advantage of Table Values (0 & +/- 16384)
|
||||
* 2) to perform reordering of Input Values
|
||||
*/
|
||||
FOR (k = 0; k < SIZE; k += 8)
|
||||
{
|
||||
/*
|
||||
* This loop use:
|
||||
* 4 Word16 (tmp1...tmp4)
|
||||
* 2 Word32 (L_tmp1 & L_tmp2)
|
||||
* 4 Pointers (table_ptr, input_ptr1, input_ptr2, input_ptr3)
|
||||
*
|
||||
* The addition of 'in_ptr' + and index value from 'reorder_ptr'
|
||||
* is counted as a move16()
|
||||
*/
|
||||
|
||||
input_ptr1 = in_ptr + *table_ptr++;
|
||||
|
||||
L_tmp1 = L_mult(*input_ptr1++, 16384);
|
||||
L_tmp2 = L_mult(*input_ptr1, 16384);
|
||||
|
||||
input_ptr1 = in_ptr + *table_ptr++;
|
||||
|
||||
tmp1 = msu_r(L_tmp1, *input_ptr1, 16384);
|
||||
tmp3 = mac_r(L_tmp1, *input_ptr1++, 16384);
|
||||
|
||||
input_ptr2 = in_ptr + *table_ptr++;
|
||||
input_ptr3 = in_ptr + *table_ptr++;
|
||||
|
||||
L_tmp1 = L_mult(*input_ptr2++, 16384);
|
||||
tmp2 = mac_r(L_tmp1, *input_ptr3, 16384);
|
||||
tmp4 = msu_r(L_tmp1, *input_ptr3++, 16384);
|
||||
|
||||
L_tmp1 = L_mult(tmp3, 16384);
|
||||
out_ptr[k] = mac_r(L_tmp1, tmp2, 16384);
|
||||
move16();
|
||||
out_ptr[k+4] = msu_r(L_tmp1, tmp2, 16384);
|
||||
move16();
|
||||
|
||||
tmp2 = mac_r(L_tmp2, *input_ptr1, 16384);
|
||||
tmp3 = msu_r(L_tmp2, *input_ptr1, 16384);
|
||||
|
||||
L_tmp2 = L_mult(*input_ptr2, 16384);
|
||||
|
||||
L_tmp1 = L_mult(tmp1, 16384);
|
||||
tmp1 = msu_r(L_tmp2, *input_ptr3, 16384);
|
||||
out_ptr[k+2] = mac_r(L_tmp1, tmp1, 16384);
|
||||
move16();
|
||||
out_ptr[k+6] = msu_r(L_tmp1, tmp1, 16384);
|
||||
move16();
|
||||
|
||||
L_tmp1 = L_mult(tmp2, 16384);
|
||||
tmp2 = mac_r(L_tmp2, *input_ptr3, 16384);
|
||||
out_ptr[k+1] = mac_r(L_tmp1, tmp2, 16384);
|
||||
move16();
|
||||
out_ptr[k+5] = msu_r(L_tmp1, tmp2, 16384);
|
||||
move16();
|
||||
|
||||
L_tmp1 = L_mult(tmp3, 16384);
|
||||
out_ptr[k+3] = msu_r(L_tmp1, tmp4, 16384);
|
||||
move16();
|
||||
out_ptr[k+7] = mac_r(L_tmp1, tmp4, 16384);
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Remaining Stages */
|
||||
FOR (i = 2; i < NUM_STAGE; i++)
|
||||
{
|
||||
/* i is stage counter */
|
||||
jj = shl(2, i); /* FFT size */
|
||||
kk = shl(jj, 1); /* 2 * FFT size */
|
||||
ii = shr(SIZE, i);
|
||||
ji = 0;
|
||||
move16(); /* ji is phase table index */
|
||||
|
||||
FOR (j = 0; j < jj; j += 2)
|
||||
{
|
||||
/* j is sample counter */
|
||||
FOR (k = j; k < SIZE; k += kk)
|
||||
{
|
||||
/* k is butterfly top */
|
||||
kj = add(k, jj); /* kj is butterfly bottom */
|
||||
|
||||
/* Butterfly computations */
|
||||
L_tmp1 = L_msu(L_mult(*(out_ptr + kj), phs_tbl[ji]),
|
||||
*(out_ptr + kj + 1), phs_tbl[ji + 1]);
|
||||
L_tmp2 = L_mac(L_mult(*(out_ptr + kj + 1), phs_tbl[ji]),
|
||||
*(out_ptr + kj), phs_tbl[ji + 1]);
|
||||
|
||||
out_ptr[kj] = mac_r(L_negate(L_tmp1), out_ptr[k], 16384);
|
||||
move16();
|
||||
out_ptr[kj+1] = mac_r(L_negate(L_tmp2), out_ptr[k+1], 16384);
|
||||
move16();
|
||||
out_ptr[k] = mac_r(L_tmp1, out_ptr[k], 16384);
|
||||
move16();
|
||||
out_ptr[k+1] = mac_r(L_tmp2, out_ptr[k+1], 16384);
|
||||
move16();
|
||||
}
|
||||
ji = add(ji, ii);
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE /* The ifFT part */
|
||||
{
|
||||
/* Unrolled 1st/2nd Stage
|
||||
* 1) to take advantage of Table Values (0 & +/- 16384)
|
||||
* 2) to perform reordering of Input Values
|
||||
*/
|
||||
FOR (k = 0; k < SIZE; k += 8)
|
||||
{
|
||||
/*
|
||||
* This loop use:
|
||||
* 4 Word16 (tmp1...tmp4)
|
||||
* 2 Word32 (L_tmp1 & L_tmp2)
|
||||
* 5 Pointers (reorder_ptr, input_ptr1...input_ptr4)
|
||||
*
|
||||
* The addition of 'in_ptr' + and index value from 'reorder_ptr'
|
||||
* is counted as a move16()
|
||||
*/
|
||||
|
||||
input_ptr1 = in_ptr + *table_ptr++;
|
||||
input_ptr2 = in_ptr + *table_ptr++;
|
||||
|
||||
input_ptr3 = in_ptr + *table_ptr++;
|
||||
input_ptr4 = in_ptr + *table_ptr++;
|
||||
|
||||
tmp3 = sub(*input_ptr1, *input_ptr2);
|
||||
tmp4 = add(*input_ptr1++, *input_ptr2++);
|
||||
|
||||
tmp2 = sub(input_ptr3[0], input_ptr4[0]);
|
||||
tmp1 = sub(input_ptr3[1], input_ptr4[1]);
|
||||
|
||||
out_ptr[k+2] = sub(tmp3, tmp1);
|
||||
move16();
|
||||
out_ptr[k+6] = add(tmp3, tmp1);
|
||||
move16();
|
||||
|
||||
tmp1 = sub(*input_ptr1, *input_ptr2);
|
||||
out_ptr[k+3] = add(tmp1, tmp2);
|
||||
move16();
|
||||
out_ptr[k+7] = sub(tmp1, tmp2);
|
||||
move16();
|
||||
|
||||
tmp1 = add(input_ptr3[0], input_ptr4[0]);
|
||||
tmp3 = add(input_ptr3[1], input_ptr4[1]);
|
||||
|
||||
out_ptr[k] = add(tmp4, tmp1);
|
||||
move16();
|
||||
out_ptr[k+4] = sub(tmp4, tmp1);
|
||||
move16();
|
||||
|
||||
tmp4 = add(*input_ptr1, *input_ptr2);
|
||||
out_ptr[k+1] = add(tmp4, tmp3);
|
||||
move16();
|
||||
out_ptr[k+5] = sub(tmp4, tmp3);
|
||||
move16();
|
||||
}
|
||||
|
||||
table_ptr = phs_tbl + SIZE; /* access part of table that is scaled by 2 */
|
||||
|
||||
/* Remaining Stages */
|
||||
FOR (i = 2; i < NUM_STAGE; i++)
|
||||
{
|
||||
/* i is stage counter */
|
||||
jj = shl(2, i); /* FFT size */
|
||||
kk = shl(jj, 1); /* 2 * FFT size */
|
||||
ii = shr(SIZE, i);
|
||||
ji = 0;
|
||||
move16(); /* ji is phase table index */
|
||||
|
||||
FOR (j = 0; j < jj; j += 2)
|
||||
{
|
||||
/* j is sample counter */
|
||||
/* This can be computed by successive add_fxitions of ii to ji, starting from 0
|
||||
hence line-count it as a one-line add (still need to increment op count!!) */
|
||||
|
||||
FOR (k = j; k < SIZE; k += kk)
|
||||
{
|
||||
/* k is butterfly top */
|
||||
kj = add(k, jj); /* kj is butterfly bottom */
|
||||
|
||||
/* Butterfly computations */
|
||||
tmp1 = mac_r(L_mult(out_ptr[kj], table_ptr[ji]),
|
||||
out_ptr[kj+1], table_ptr[ji + 1]);
|
||||
|
||||
tmp2 = msu_r(L_mult(out_ptr[kj+1], table_ptr[ji]),
|
||||
out_ptr[kj], table_ptr[ji+1]);
|
||||
|
||||
out_ptr[kj] = sub(out_ptr[k], tmp1);
|
||||
move16();
|
||||
out_ptr[kj+1] = sub(out_ptr[k+1], tmp2);
|
||||
move16();
|
||||
out_ptr[k] = add(out_ptr[k], tmp1);
|
||||
move16();
|
||||
out_ptr[k+1] = add(out_ptr[k+1], tmp2);
|
||||
move16();
|
||||
}
|
||||
ji = add(ji, ii);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------*
|
||||
* r_fft_fx:
|
||||
*
|
||||
* Perform FFT fixed-point for real-valued sequences of length 32, 64 or 128
|
||||
*--------------------------------------------------------------------------------*/
|
||||
void r_fft_fx_lc(
|
||||
const Word16 *phs_tbl, /* i : Table of phase */
|
||||
const Word16 SIZE, /* i : Size of the FFT */
|
||||
const Word16 SIZE2, /* i : Size / 2 */
|
||||
const Word16 NUM_STAGE, /* i : Number of stage */
|
||||
const Word16 *in_ptr, /* i : coefficients in the order re[0], re[1], ... re[n/2], im[n/2-1], im[n/2-2], ..., im[1] */
|
||||
Word16 *out_ptr, /* o : coefficients in the order re[0], re[1], ... re[n/2], im[n/2-1], im[n/2-2], ..., im[1] */
|
||||
const Word16 isign /* i : 1=fft, otherwize it's ifft */
|
||||
)
|
||||
{
|
||||
Word16 tmp2_real, tmp2_imag;
|
||||
Word32 Ltmp1_real, Ltmp1_imag;
|
||||
Word16 i;
|
||||
Word32 Ltmp1;
|
||||
const Word16 *phstbl_ptrDn;
|
||||
Word16 *ptrDn;
|
||||
Word16 temp[1024]; /* Accommodates real input FFT size up to 1024. */
|
||||
|
||||
/* Setup Pointers */
|
||||
phstbl_ptrDn = &phs_tbl[SIZE-1];
|
||||
|
||||
/* The FFT part */
|
||||
IF (isign != 0)
|
||||
{
|
||||
Word16 *ptRealUp, *ptRealDn, *ptImaUp, *ptImaDn;
|
||||
|
||||
/* Perform the complex FFT */
|
||||
c_fft_fx(phs_tbl, SIZE, NUM_STAGE, in_ptr, temp, isign);
|
||||
|
||||
/* First, handle the DC and foldover frequencies */
|
||||
out_ptr[SIZE2] = sub(temp[0], temp[1]);
|
||||
move16();
|
||||
out_ptr[0] = sub(add(temp[0], temp[1]), shr(NUM_STAGE, 1));
|
||||
move16();/* DC have a small offset */
|
||||
|
||||
ptrDn = &temp[SIZE-1];
|
||||
|
||||
ptImaDn = &out_ptr[SIZE-1];
|
||||
ptRealUp = &out_ptr[1];
|
||||
ptImaUp = &out_ptr[SIZE2+1];
|
||||
ptRealDn = &out_ptr[SIZE2-1];
|
||||
|
||||
/* Now, handle the remaining positive frequencies */
|
||||
FOR (i = 2; i <= SIZE2; i += 2)
|
||||
{
|
||||
Ltmp1_imag = L_mult(temp[i+1], 16384);
|
||||
Ltmp1_imag = L_msu(Ltmp1_imag, *ptrDn, 16384);
|
||||
tmp2_real = add(temp[i+1], *ptrDn--);
|
||||
|
||||
Ltmp1_real = L_mult(temp[i], 16384);
|
||||
Ltmp1_real = L_mac(Ltmp1_real, *ptrDn, 16384);
|
||||
tmp2_imag = sub(*ptrDn--, temp[i]);
|
||||
|
||||
|
||||
*ptRealUp++ = msu_r(L_mac(Ltmp1_real, tmp2_real, phs_tbl[i]), tmp2_imag, phs_tbl[i+1]);
|
||||
move16();
|
||||
*ptImaDn-- = mac_r(L_mac(Ltmp1_imag, tmp2_imag, phs_tbl[i]), tmp2_real, phs_tbl[i+1]);
|
||||
move16();
|
||||
Ltmp1 = L_mac(L_negate(Ltmp1_imag), tmp2_real, *phstbl_ptrDn);
|
||||
Ltmp1_real = L_mac(Ltmp1_real, tmp2_imag, *phstbl_ptrDn--);
|
||||
*ptImaUp++ = msu_r(Ltmp1, tmp2_imag, *phstbl_ptrDn);
|
||||
move16();
|
||||
*ptRealDn-- = mac_r(Ltmp1_real, tmp2_real, *phstbl_ptrDn--);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE /* The ifFT part */
|
||||
{
|
||||
const Word16 *ptRealUp, *ptRealDn, *ptImaUp, *ptImaDn;
|
||||
|
||||
/* First, handle the DC and foldover frequencies */
|
||||
Ltmp1 = L_mult(in_ptr[0], 16384);
|
||||
temp[0] = mac_r(Ltmp1, in_ptr[SIZE2], 16384);
|
||||
move16();
|
||||
temp[1] = msu_r(Ltmp1, in_ptr[SIZE2], 16384);
|
||||
move16();
|
||||
|
||||
ptrDn = &temp[SIZE-1];
|
||||
|
||||
/* Here we cast to Word16 * from a const Word16 *. */
|
||||
/* This is ok because we use these pointers for */
|
||||
/* reading only. This is just to avoid declaring a */
|
||||
/* bunch of 4 other pointer with const Word16 *. */
|
||||
ptImaDn = &in_ptr[SIZE-1];
|
||||
ptRealUp = &in_ptr[1];
|
||||
ptImaUp = &in_ptr[SIZE2+1];
|
||||
ptRealDn = &in_ptr[SIZE2-1];
|
||||
|
||||
/* Now, handle the remaining positive frequencies */
|
||||
FOR (i = 2; i <= SIZE2; i += 2)
|
||||
{
|
||||
Ltmp1_imag = L_mult(*ptImaDn, 16384);
|
||||
Ltmp1_imag = L_msu(Ltmp1_imag, *ptImaUp, 16384);
|
||||
tmp2_real = add(*ptImaDn--, *ptImaUp++);
|
||||
Ltmp1_real = L_mult(*ptRealUp, 16384);
|
||||
Ltmp1_real = L_mac(Ltmp1_real, *ptRealDn, 16384);
|
||||
tmp2_imag = sub(*ptRealUp++, *ptRealDn--);
|
||||
|
||||
|
||||
temp[i] = mac_r(L_msu(Ltmp1_real, tmp2_real, phs_tbl[i]), tmp2_imag, phs_tbl[i+1]);
|
||||
move16();
|
||||
temp[i+1] = mac_r(L_mac(Ltmp1_imag, tmp2_imag, phs_tbl[i]), tmp2_real, phs_tbl[i+1]);
|
||||
move16();
|
||||
Ltmp1 = L_mac(L_negate(Ltmp1_imag), tmp2_real, *phstbl_ptrDn);
|
||||
Ltmp1_real = L_msu(Ltmp1_real, tmp2_imag, *phstbl_ptrDn--);
|
||||
*ptrDn-- = msu_r(Ltmp1, tmp2_imag, *phstbl_ptrDn);
|
||||
move16();
|
||||
*ptrDn-- = msu_r(Ltmp1_real, tmp2_real, *phstbl_ptrDn--);
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Perform the complex ifFT */
|
||||
c_fft_fx(phs_tbl, SIZE, NUM_STAGE, temp, out_ptr, isign);
|
||||
}
|
||||
}
|
||||
Executable
+456
@@ -0,0 +1,456 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
#define INV_SQR2_FX 23170
|
||||
#define N_MAX_SAS 256
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* fft_rel_fx()
|
||||
*
|
||||
* Computes the split-radix FFT in place for the real-valued
|
||||
* signal x of length n. The algorithm has been ported from
|
||||
* the fortran code of [1].
|
||||
*
|
||||
* The function needs sine and cosine tables t_sin and t_cos,
|
||||
* and the constant N_MAX_SAS. The table entries are defined as
|
||||
* sin(2*pi*i) and cos(2*pi*i) for i = 0, 1, ..., N_MAX_SAS-1. The
|
||||
* implementation assumes that any entry will not be needed
|
||||
* outside the tables. Therefore, N_MAX_SAS and n must be properly
|
||||
* set. The function has been tested with the values n = 16,
|
||||
* 32, 64, 128, 256, and N_MAX_SAS = 1280.
|
||||
*
|
||||
* References
|
||||
* [1] H.V. Sorensen, D.L. Jones, M.T. Heideman, C.S. Burrus,
|
||||
* "Real-valued fast Fourier transform algorithm," IEEE
|
||||
* Trans. on Signal Processing, Vol.35, No.6, pp 849-863,
|
||||
* 1987.
|
||||
*
|
||||
* OUTPUT
|
||||
* x[0:n-1] Transform coeffients in the order re[0], re[1],
|
||||
* ..., re[n/2], im[n/2-1], ..., im[1].
|
||||
*---------------------------------------------------------------------*/
|
||||
/*MERGE fft_rel_fx and fft_rel_fx_lc */
|
||||
void fft_rel_fx(
|
||||
Word16 x[], /* i/o: input/output vector */
|
||||
const Word16 n, /* i : vector length */
|
||||
const Word16 m /* i : log2 of vector length */
|
||||
)
|
||||
{
|
||||
Word16 i, j, k, n1, n2, n4;
|
||||
Word16 step;
|
||||
Word16 xt, t1, t2;
|
||||
Word16 *x0, *x1, *x2;
|
||||
const Word16 *s, *c;
|
||||
Word16 *xi2, *xi3, *xi4, *xi1;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Digit reverse counter
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
j = 0;
|
||||
move16();
|
||||
x0 = &x[0];
|
||||
move16();
|
||||
FOR (i = 0; i < n-1; i++)
|
||||
{
|
||||
IF (sub(i,j) < 0)
|
||||
{
|
||||
xt = x[j];
|
||||
move16();
|
||||
x[j] = *x0;
|
||||
move16();
|
||||
*x0 = xt;
|
||||
move16();
|
||||
}
|
||||
x0++;
|
||||
k = shr(n,1);
|
||||
WHILE (sub(k,j) <= 0)
|
||||
{
|
||||
j = sub(j,k);
|
||||
k = shr(k,1);
|
||||
}
|
||||
j = add(j,k);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Length two butterflies
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
x0 = &x[0];
|
||||
move16();
|
||||
x1 = &x[1];
|
||||
move16();
|
||||
FOR (i = 0; i < n/2; i++)
|
||||
{
|
||||
xt = *x0;
|
||||
move16();
|
||||
*x0 = add(xt,*x1);
|
||||
move16();
|
||||
*x1 = sub(xt,*x1);
|
||||
move16();
|
||||
x0++;
|
||||
x0++;
|
||||
x1++;
|
||||
x1++;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Other butterflies
|
||||
*
|
||||
* The implementation described in [1] has been changed by using
|
||||
* table lookup for evaluating sine and cosine functions. The
|
||||
* variable ind and its increment step are needed to access table
|
||||
* entries. Note that this implementation assumes n4 to be so
|
||||
* small that ind will never exceed the table. Thus the input
|
||||
* argument n and the constant N_MAX_SAS must be set properly.
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
n2 = 1;
|
||||
move16();
|
||||
/* step = N_MAX_SAS/4; */
|
||||
FOR (k = 2; k <= m; k++)
|
||||
{
|
||||
n4 = n2;
|
||||
move16();
|
||||
n2 = shl(n4,1);
|
||||
n1 = shl(n2,1);
|
||||
|
||||
step = N_MAX_SAS/n1;
|
||||
|
||||
x0 = x;
|
||||
x1 = x + n2;
|
||||
x2 = x + add(n2, n4);
|
||||
FOR (i = 0; i < n; i += n1)
|
||||
{
|
||||
xt = *x0;
|
||||
move16(); /* xt = x[i]; */
|
||||
*x0 = add(xt,*x1);
|
||||
move16(); /* x[i] = xt + x[i+n2]; */
|
||||
*x1 = sub(xt,*x1);
|
||||
move16(); /* x[i+n2] = xt - x[i+n2]; */
|
||||
*x2 = negate(*x2);
|
||||
move16(); /* x[i+n2+n4] = -x[i+n2+n4]; */
|
||||
|
||||
|
||||
s = sincos_t_fx + step;
|
||||
c = s + 64;
|
||||
xi1 = x + add(i, 1);
|
||||
xi3 = xi1 + n2;
|
||||
xi2 = xi3 - 2;
|
||||
xi4 = xi1 + sub(n1, 2);
|
||||
|
||||
FOR (j = 1; j < n4; j++)
|
||||
{
|
||||
t1 = add(mult_r(*xi3,*c),mult_r(*xi4,*s)); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); */
|
||||
t2 = sub(mult_r(*xi3,*s),mult_r(*xi4,*c)); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); */
|
||||
*xi4 = sub(*xi2,t2);
|
||||
move16();
|
||||
*xi3 = negate(add(*xi2,t2));
|
||||
move16();
|
||||
*xi2 = sub(*xi1,t1);
|
||||
move16();
|
||||
*xi1 = add(*xi1,t1);
|
||||
move16();
|
||||
|
||||
xi4--;
|
||||
xi2--;
|
||||
xi3++;
|
||||
xi1++;
|
||||
c += step;
|
||||
s += step; /* autoincrement by ar0 */
|
||||
}
|
||||
|
||||
x0 += n1;
|
||||
x1 += n1;
|
||||
x2 += n1;
|
||||
}
|
||||
/* step = shr(step, 1); */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ifft_rel_fx(
|
||||
Word16 io[], /* i/o: input/output vector */
|
||||
const Word16 n, /* i : vector length */
|
||||
const Word16 m /* i : log2 of vector length */
|
||||
)
|
||||
{
|
||||
Word16 i, j, k;
|
||||
Word16 step;
|
||||
Word16 n2, n4, n8, i0;
|
||||
Word16 is, id;
|
||||
Word16 *x,*xi0, *xi1, *xi2, *xi3, *xi4, *xup1, *xdn6, *xup3, *xdn8;
|
||||
Word16 xt;
|
||||
Word16 r1;
|
||||
Word16 t1, t2, t3, t4, t5;
|
||||
const Word16 *s, *c, *s3, *c3;
|
||||
|
||||
Word16 cc1, cc3, ss1, ss3;
|
||||
Word16 tmp;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* ifft
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
x = &io[-1];
|
||||
move16();
|
||||
n2 = shl(n,1);
|
||||
FOR (k=1; k<m; k++)
|
||||
{
|
||||
is = 0;
|
||||
move16();
|
||||
id = n2;
|
||||
move16();
|
||||
n2 = shr(n2,1);
|
||||
move16();
|
||||
n4 = shr(n2,2);
|
||||
move16();
|
||||
n8 = shr(n4,1);
|
||||
move16();
|
||||
tmp = sub(n,1);
|
||||
WHILE( sub(is,tmp) < 0 )
|
||||
{
|
||||
xi1 = x + is + 1;
|
||||
move16();
|
||||
xi2 = xi1 + n4;
|
||||
move16();
|
||||
xi3 = xi2 + n4;
|
||||
move16();
|
||||
xi4 = xi3 + n4;
|
||||
move16();
|
||||
|
||||
FOR (i=is; i<n; i+= id)
|
||||
{
|
||||
t1 = sub(*xi1,*xi3);
|
||||
*xi1 = add(*xi1,*xi3);
|
||||
move16();
|
||||
*xi2 = shl(*xi2,1);
|
||||
move16();
|
||||
*xi3 = sub(t1,shl(*xi4,1));
|
||||
move16();
|
||||
*xi4 = add(t1,shl(*xi4,1));
|
||||
move16();
|
||||
|
||||
IF (sub(n4,1) != 0)
|
||||
{
|
||||
t1 = mult_r(sub(*(xi2+n8),*(xi1+n8)),INV_SQR2_FX);
|
||||
t2 = mult_r(add(*(xi4+n8),*(xi3+n8)),INV_SQR2_FX);
|
||||
|
||||
*(xi1+n8) = add(*(xi1+n8),*(xi2+n8));
|
||||
move16();
|
||||
*(xi2+n8) = sub(*(xi4+n8),*(xi3+n8));
|
||||
move16();
|
||||
*(xi3+n8) = negate(shl(add(t2,t1),1));
|
||||
move16();
|
||||
*(xi4+n8) = shl(sub(t1,t2),1);
|
||||
move16();
|
||||
}
|
||||
xi1 += id;
|
||||
move16();
|
||||
xi2 += id;
|
||||
move16();
|
||||
xi3 += id;
|
||||
move16();
|
||||
xi4 += id;
|
||||
move16();
|
||||
}
|
||||
is = sub(shl(id,1),n2);
|
||||
id = shl(id,2);
|
||||
}
|
||||
/*Can be acheived with a shr */
|
||||
step = N_MAX_SAS/n2;
|
||||
move16();
|
||||
|
||||
s = sincos_t_fx + step;
|
||||
move16();
|
||||
c = s + 64;
|
||||
move16();
|
||||
s3 = sincos_t_fx + i_mult2(step,3);
|
||||
move16();
|
||||
c3 = s3 + 64;
|
||||
move16();
|
||||
FOR (j=2; j<=n8; j++)
|
||||
{
|
||||
cc1 = *c ;
|
||||
move16();
|
||||
ss1 = *s;
|
||||
move16();
|
||||
cc3 = *c3;
|
||||
move16();
|
||||
ss3 = *s3;
|
||||
move16();
|
||||
|
||||
is = 0;
|
||||
move16();
|
||||
id = shl(n2,1);
|
||||
|
||||
c += step;
|
||||
move16();
|
||||
s += step;
|
||||
move16();
|
||||
|
||||
c3 += 3*step;
|
||||
move16();
|
||||
s3 += 3*step;
|
||||
move16();
|
||||
WHILE (sub(is,sub(n,1)) < 0)
|
||||
{
|
||||
xup1 = x + j + is;
|
||||
move16();
|
||||
xup3 = xup1 + shl(n4,1);
|
||||
move16();
|
||||
xdn6 = xup3 - shl(j,1) +2;
|
||||
move16();
|
||||
|
||||
xdn8 = xdn6 + shl(n4,1);
|
||||
move16();
|
||||
|
||||
FOR (i=is; i<n; i+=id)
|
||||
{
|
||||
t1 = sub(*xup1,*xdn6);
|
||||
*xup1 = add(*xup1,*xdn6);
|
||||
move16();
|
||||
xup1 += n4;
|
||||
move16();
|
||||
xdn6 -= n4;
|
||||
move16();
|
||||
|
||||
t2 = sub(*xdn6,*xup1);
|
||||
*xdn6 = add(*xup1,*xdn6);
|
||||
move16();
|
||||
|
||||
xdn6 += n4;
|
||||
move16();
|
||||
t3 = add(*xdn8,*xup3);
|
||||
*xdn6 = sub(*xdn8,*xup3);
|
||||
move16();
|
||||
|
||||
xup3 += n4;
|
||||
move16();
|
||||
xdn8 -= n4;
|
||||
move16();
|
||||
|
||||
t4 = add(*xup3,*xdn8);
|
||||
*xup1= sub(*xup3,*xdn8);
|
||||
move16();
|
||||
|
||||
t5 = sub(t1,t4);
|
||||
t1 = add(t1,t4);
|
||||
t4 = sub(t2,t3);
|
||||
t2 = add(t2,t3);
|
||||
*xup3 = sub(mult_r(t1,cc3),mult_r(t2,ss3));
|
||||
move16();
|
||||
xup3 -= n4;
|
||||
move16();
|
||||
*xup3 = add(mult_r(t5,cc1),mult_r(t4,ss1));
|
||||
move16();
|
||||
*xdn8 = sub(mult_r(t5,ss1),mult_r(t4,cc1));
|
||||
move16();
|
||||
|
||||
xdn8 += n4;
|
||||
move16();
|
||||
*xdn8 = add(mult_r(t2,cc3),mult_r(t1,ss3));
|
||||
move16();
|
||||
|
||||
xup1 -= n4;
|
||||
move16();
|
||||
xup1 += id;
|
||||
move16();
|
||||
xup3 += id;
|
||||
move16();
|
||||
xdn6 += id;
|
||||
move16();
|
||||
xdn8 += id;
|
||||
move16();
|
||||
}
|
||||
is = sub(shl(id,1),n2);
|
||||
id = shl(id,2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Length two butterflies
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
is = 1;
|
||||
move16();
|
||||
id = 4;
|
||||
move16();
|
||||
WHILE (is < n)
|
||||
{
|
||||
xi0 = x + is ;
|
||||
move16();
|
||||
xi1 = xi0 + 1;
|
||||
move16();
|
||||
|
||||
FOR (i0=is; i0<=n; i0+=id)
|
||||
{
|
||||
r1 = *xi0;
|
||||
move16();
|
||||
*xi0= add(r1,*xi1);
|
||||
move16();
|
||||
*xi1 = sub(r1,*xi1);
|
||||
move16();
|
||||
xi0 += id;
|
||||
move16();
|
||||
xi1 += id;
|
||||
move16();
|
||||
}
|
||||
is = sub(shl(id,1),1);
|
||||
id = shl(id,2);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Digit reverse counter
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
j = 1;
|
||||
move16();
|
||||
FOR (i=1; i<n; i++)
|
||||
{
|
||||
IF (sub(i,j) < 0)
|
||||
{
|
||||
xt = x[j];
|
||||
move16();
|
||||
x[j] = x[i];
|
||||
move16();
|
||||
x[i] = xt;
|
||||
move16();
|
||||
}
|
||||
k = shr(n, 1);
|
||||
WHILE (sub(k,j) < 0)
|
||||
{
|
||||
j = sub(j,k);
|
||||
k =shr(k, 1);
|
||||
}
|
||||
j = add(j,k);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Normalization
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
tmp = div_s(1,n); /*Q15 */
|
||||
FOR (i=1; i<=n; i++)
|
||||
{
|
||||
x[i] = mult_r(x[i],tmp);
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+278
@@ -0,0 +1,278 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* fill_spectrum()
|
||||
*
|
||||
* Apply spectral filling by
|
||||
* - filling zero-bit bands below BWE region
|
||||
* - applying BWE above transition frequency
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void fill_spectrum_fx(
|
||||
Word16 *coeff, /* i/o: normalized MLT spectrum / nf spectrum Q12 */
|
||||
Word32 *L_coeff_out, /* i/o: Noisefilled MLT spectrum Q12 */
|
||||
const Word16 *R, /* i : number of pulses per band Q0 */
|
||||
const Word16 is_transient, /* i : transient flag Q0 */
|
||||
Word16 norm[], /* i : quantization indices for norms Q0 */
|
||||
const Word16 *hq_generic_fenv, /* i : HQ GENERIC envelope Q1 */
|
||||
const Word16 hq_generic_offset, /* i : HQ GENERIC offset Q0 */
|
||||
const Word16 nf_idx, /* i : noise fill index Q0 */
|
||||
const Word16 length, /* i : Length of spectrum (32 or 48 kHz) Q0 */
|
||||
const Word16 env_stab, /* i : Envelope stability measure [0..1] Q15 */
|
||||
Word16 *no_att_hangover, /* i/o: Frame counter for attenuation hangover Q0 */
|
||||
Word32 *L_energy_lt, /* i/o: Long-term energy measure for transient detection Q13 */
|
||||
Word16 *bwe_seed, /* i/o: random seed for generating BWE input Q0 */
|
||||
const Word16 hq_generic_exc_clas, /* i : BWE excitation class Q0 */
|
||||
const Word16 core_sfm, /* i : index of the end band for core Q0 */
|
||||
const Word16 HQ_mode, /* i : HQ mode Q0 */
|
||||
Word16 noise_level[], /* i : noise levels for harmonic modes Q15 */
|
||||
const Word32 L_core_brate, /* i : target bit-rate Q0 */
|
||||
Word16 prev_noise_level[], /* i/o: noise factor in previous frame Q15 */
|
||||
Word16 *prev_R, /* i/o: bit allocation info. in previous frame Q0 */
|
||||
Word32 *prev_coeff_out, /* i/o: decoded spectrum in previous frame Q12 */
|
||||
const Word16 *peak_idx, /* i : peak indices for hvq Q0 */
|
||||
const Word16 Npeaks, /* i : number of peaks in hvq Q0 */
|
||||
const Word16 *npulses, /* i : number of pulses per band Q0 */
|
||||
const Word16 prev_is_transient, /* i : previous transient flag Q0 */
|
||||
Word32 *prev_normq, /* i/o: previous norms Q14 */
|
||||
Word32 *prev_env, /* i/o: previous noise envelopes Q(prev_env_Q) */
|
||||
const Word16 prev_bfi, /* i : previous bad frame indicator Q0 */
|
||||
const Word16 *sfmsize, /* i : Length of bands Q0 */
|
||||
const Word16 *sfm_start, /* i : Start of bands Q0 */
|
||||
const Word16 *sfm_end, /* i : End of bands Q0 */
|
||||
Word16 *prev_L_swb_norm, /* i/o: HVQ/Harmonic mode normalization length Q0 */
|
||||
const Word16 prev_hq_mode, /* i : Previous HQ mode Q0 */
|
||||
const Word16 num_sfm /* i : Total number of bands Q0 */
|
||||
,Word16 *prev_env_Q
|
||||
,const Word16 num_env_bands /* i : Number sub bands to be encoded for HQ_GEN Q0 */
|
||||
)
|
||||
{
|
||||
Word16 CodeBook[FREQ_LENGTH]; /* Q12 */
|
||||
Word16 cb_size;
|
||||
Word16 last_sfm;
|
||||
Word16 CodeBook_mod[FREQ_LENGTH]; /*Q12 */
|
||||
Word16 norm_adj[NB_SFM]; /*Q15 */
|
||||
Word16 high_sfm;
|
||||
Word16 flag_32K_env_hangover;
|
||||
Word16 bin_th;
|
||||
Word16 peak_pos[L_HARMONIC_EXC];
|
||||
Word16 bwe_peaks[L_FRAME48k];
|
||||
Word32 L_normq_v[NB_SFM]; /*Q14 */
|
||||
Word16 coeff_fine[L_FRAME48k]; /*Q15 */
|
||||
Word32 L_coeff_out1[L_FRAME48k]; /*Q12 */
|
||||
|
||||
set16_fx( peak_pos, 0, L_HARMONIC_EXC );
|
||||
set16_fx( bwe_peaks, 0, L_FRAME48k );
|
||||
set16_fx(norm_adj, 32767, num_sfm); /* 1.0, Q15 */
|
||||
cb_size = 0;
|
||||
move16();
|
||||
bin_th = 0;
|
||||
move16();
|
||||
high_sfm = 23;
|
||||
move16();
|
||||
|
||||
test();
|
||||
IF ( sub(HQ_mode, HQ_TRANSIENT) == 0 )
|
||||
{
|
||||
last_sfm = sub(num_sfm, 1);
|
||||
}
|
||||
ELSE IF ( sub(HQ_mode,HQ_GEN_SWB) == 0 || sub(HQ_mode,HQ_GEN_FB) == 0 )
|
||||
{
|
||||
last_sfm = s_max(core_sfm,sub(num_env_bands,1));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
last_sfm = core_sfm;
|
||||
move16();
|
||||
}
|
||||
|
||||
IF ( sub(HQ_mode, HQ_HARMONIC) == 0 )
|
||||
{
|
||||
/*high_sfm = (core_brate == HQ_24k40) ? HVQ_THRES_SFM_24k-1 : HVQ_THRES_SFM_32k-3; */
|
||||
high_sfm = sub(HVQ_THRES_SFM_32k, 1);
|
||||
if (L_sub(L_core_brate, HQ_24k40) == 0)
|
||||
{
|
||||
high_sfm = sub(HVQ_THRES_SFM_24k, 1);
|
||||
}
|
||||
|
||||
if( sub(last_sfm, high_sfm) < 0 )
|
||||
{
|
||||
last_sfm = high_sfm;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE if ( sub(HQ_mode, HQ_HVQ) == 0 )
|
||||
{
|
||||
bin_th = sfm_end[last_sfm];
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Transient analysis for envelope stability measure */
|
||||
IF ( sub(length, L_FRAME32k) == 0 )
|
||||
{
|
||||
env_stab_transient_detect_fx( is_transient, length, norm, no_att_hangover, L_energy_lt, HQ_mode, bin_th, L_coeff_out, 12 );
|
||||
}
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF ( sub(length, L_FRAME16k) == 0 ||
|
||||
((sub(length, L_FRAME32k) == 0 && sub(HQ_mode, HQ_HARMONIC) != 0 && sub(HQ_mode, HQ_HVQ) != 0) && *no_att_hangover == 0) )
|
||||
{
|
||||
/* Norm adjustment function */
|
||||
env_adj_fx( npulses, length, last_sfm, norm_adj, env_stab, sfmsize );
|
||||
}
|
||||
|
||||
/*flag_32K_env_hangover = ( length == L_FRAME32k && ( (env_stab < 0.5f && *no_att_hangover == 0) || HQ_mode == HQ_HVQ ) ); */
|
||||
flag_32K_env_hangover = 0;
|
||||
move16();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
if ( sub(length, L_FRAME32k) == 0 && ( (sub(env_stab, 16384) < 0 && *no_att_hangover == 0) || sub(HQ_mode, HQ_HVQ) == 0 ) )
|
||||
{
|
||||
flag_32K_env_hangover = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Build noise-fill codebook
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
IF ( sub(HQ_mode, HQ_HVQ) != 0 )
|
||||
{
|
||||
cb_size = build_nf_codebook_fx(flag_32K_env_hangover, coeff, sfm_start, sfmsize, sfm_end, last_sfm, R, CodeBook, CodeBook_mod);
|
||||
}
|
||||
/*----------------------------------------------------------------*
|
||||
* Prepare fine structure for Harmonic and HVQ
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
IF ( sub(HQ_mode, HQ_HARMONIC) == 0 )
|
||||
{
|
||||
harm_bwe_fine_fx( R, last_sfm, high_sfm, num_sfm, norm, sfm_start, sfm_end, prev_L_swb_norm, coeff, L_coeff_out, coeff_fine );
|
||||
}
|
||||
ELSE IF ( sub(HQ_mode, HQ_HVQ) == 0 )
|
||||
{
|
||||
hvq_bwe_fine_fx( last_sfm, num_sfm, sfm_end, peak_idx, Npeaks, peak_pos, prev_L_swb_norm, L_coeff_out, bwe_peaks, coeff_fine );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Apply noise-fill
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
test();
|
||||
IF ( sub(HQ_mode, HQ_HVQ) != 0 && cb_size > 0 )
|
||||
{
|
||||
apply_noisefill_HQ_fx( R, length, flag_32K_env_hangover, L_core_brate, last_sfm, CodeBook,
|
||||
CodeBook_mod, cb_size, sfm_start, sfm_end, sfmsize, coeff );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Normal mode BWE
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
IF ( HQ_mode == HQ_NORMAL )
|
||||
{
|
||||
hq_fold_bwe_fx(last_sfm, sfm_end, num_sfm, coeff);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Apply noise-fill adjustment
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF( (sub(length, L_FRAME32k) >= 0 || L_sub(L_core_brate, HQ_32k) > 0 || L_sub(L_core_brate, HQ_24k40) < 0)
|
||||
&& sub(HQ_mode, HQ_HVQ) != 0 )
|
||||
{
|
||||
apply_nf_gain_fx(nf_idx, last_sfm, R, sfm_start, sfm_end, coeff);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Prepare fine strucutre for HQ GENERIC
|
||||
*----------------------------------------------------------------*/
|
||||
test();
|
||||
IF ( sub(HQ_mode, HQ_GEN_SWB) == 0 || sub(HQ_mode, HQ_GEN_FB) == 0 )
|
||||
{
|
||||
hq_generic_fine_fx( coeff, last_sfm, sfm_start, sfm_end, bwe_seed, coeff_fine );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Apply envelope
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
test();
|
||||
IF ( sub(HQ_mode, HQ_HARMONIC) != 0 && sub(HQ_mode, HQ_HVQ) != 0 )
|
||||
{
|
||||
apply_envelope_fx( coeff, norm, norm_adj, num_sfm, last_sfm, HQ_mode, length, sfm_start, sfm_end,
|
||||
L_normq_v, L_coeff_out, coeff_fine, L_coeff_out1 );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Harmonic BWE, HVQ BWE and HQ SWB BWE
|
||||
*----------------------------------------------------------------*/
|
||||
test();
|
||||
IF ( sub(HQ_mode, HQ_HARMONIC) == 0 )
|
||||
{
|
||||
harm_bwe_fx( coeff_fine, coeff, num_sfm, sfm_start, sfm_end, last_sfm, R, prev_hq_mode, norm, noise_level, prev_noise_level, bwe_seed, L_coeff_out );
|
||||
}
|
||||
ELSE IF ( sub(HQ_mode, HQ_HVQ) == 0 )
|
||||
{
|
||||
hvq_bwe_fx( L_coeff_out, coeff_fine, sfm_start, sfm_end, sfmsize, last_sfm,
|
||||
prev_hq_mode, bwe_peaks, bin_th, num_sfm, L_core_brate, R, norm,
|
||||
noise_level, prev_noise_level, bwe_seed, L_coeff_out, 15, 12 );
|
||||
}
|
||||
ELSE IF ( sub(HQ_mode, HQ_GEN_SWB) == 0 || sub(HQ_mode, HQ_GEN_FB) == 0 )
|
||||
{
|
||||
hq_bwe_fx( HQ_mode, L_coeff_out1, hq_generic_fenv, L_coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, sfm_end, num_sfm, num_env_bands, R );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* HQ WB BWE refinements
|
||||
*----------------------------------------------------------------*/
|
||||
test();
|
||||
IF ( sub(length, L_FRAME16k) == 0 && L_sub(L_core_brate, HQ_32k) == 0 )
|
||||
{
|
||||
hq_wb_nf_bwe_fx( coeff, is_transient, prev_bfi, L_normq_v, num_sfm, sfm_start, sfm_end, sfmsize, last_sfm, R,
|
||||
prev_is_transient, prev_normq, prev_env, bwe_seed, prev_coeff_out, prev_R, L_coeff_out, prev_env_Q );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Update memories
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
test();
|
||||
IF ( sub(HQ_mode, HQ_HARMONIC) != 0 && sub(HQ_mode, HQ_HVQ) != 0 )
|
||||
{
|
||||
prev_noise_level[0] = 3277;
|
||||
move16();/* 0.1 in Q15 */
|
||||
prev_noise_level[1] = 3277;
|
||||
move16();/* 0.1 in Q15 */
|
||||
}
|
||||
test();
|
||||
IF ( !(sub(length, L_FRAME16k) == 0 && L_sub(L_core_brate, HQ_32k) == 0) )
|
||||
{
|
||||
set32_fx( prev_env, 0, SFM_N_WB );
|
||||
set32_fx( prev_normq, 0, SFM_N_WB );
|
||||
}
|
||||
|
||||
test();
|
||||
IF ( sub(length, L_FRAME32k) == 0 && L_sub(L_core_brate, HQ_32k) <= 0 )
|
||||
{
|
||||
*prev_R = R[SFM_N_WB-1];
|
||||
Copy32( L_coeff_out + L_FRAME16k - L_HQ_WB_BWE, prev_coeff_out, L_HQ_WB_BWE );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+117
@@ -0,0 +1,117 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* findpulse()
|
||||
*
|
||||
* Find first pitch pulse in a frame
|
||||
*----------------------------------------------------------------------------------*/
|
||||
Word16 findpulse_fx( /* o : pulse position */
|
||||
const Word16 L_frame, /* i : length of the frame */
|
||||
const Word16 res[], /* i : Residual signal <12 bits */
|
||||
const Word16 T0, /* i : Pitch estimation Q0 */
|
||||
const Word16 enc, /* i : enc = 1 -> encoder side; enc = 0 -> decoder side */
|
||||
Word16 *sign /* i/o: sign of the maximum */
|
||||
)
|
||||
{
|
||||
const Word16 *ptr;
|
||||
Word16 maxval;
|
||||
Word16 i, maxi;
|
||||
Word32 Ltmp;
|
||||
Word16 resf[L_FRAME16k]; /* Low pass filtered residual */
|
||||
|
||||
IF (enc != DEC)
|
||||
{
|
||||
/*------------------------------------------------------------------------*
|
||||
* 1. Very simple LP filter
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
/* resf[0] = 0.50f * res[0] + 0.25f * res[1] */
|
||||
Ltmp = L_mult(res[0], 16384);
|
||||
resf[0] = mac_r(Ltmp, res[1], 8192);
|
||||
move16();
|
||||
FOR (i=1; i<L_frame-1; i++)
|
||||
{
|
||||
/* resf[i] = 0.25f * res[i-1] + 0.5f * res[i] + 0.25f * res[i+1] */
|
||||
Ltmp = L_mult(8192, res[i-1]);
|
||||
Ltmp = L_mac(Ltmp, 16384, res[i]);
|
||||
resf[i] = mac_r(Ltmp, 8192, res[i+1]);
|
||||
move16();
|
||||
}
|
||||
|
||||
/* resf[L_frame-1] = 0.25f * res[L_frame-2] + 0.50f * res[L_frame-1] */
|
||||
Ltmp = L_mult(res[L_frame-2], 8192);
|
||||
resf[L_frame-1] = mac_r(Ltmp, 16384, res[L_frame-1]);
|
||||
move16();
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* 2. Find "biggest" pitch pulse
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
ptr = resf + L_frame - 1;
|
||||
move16();
|
||||
maxi = 0;
|
||||
move16();
|
||||
|
||||
FOR (i = 1; i < T0; i++)
|
||||
{
|
||||
Ltmp = L_mult0(ptr[-maxi], ptr[-maxi]);
|
||||
if (L_msu0(Ltmp, ptr[-i], ptr[-i]) < 0)
|
||||
{
|
||||
maxi = i;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
/*
|
||||
*sign = 1; move16();
|
||||
test();
|
||||
if (ptr[-maxi] >= 0)
|
||||
{
|
||||
*sign = 0; move16();
|
||||
}*/
|
||||
*sign = negate(shr(ptr[-maxi], 15));
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/*-----------------------------------------------------------------*
|
||||
* 2. Find "biggest" pulse in the last pitch section according to the sign
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
maxval = 0;
|
||||
move16();
|
||||
maxi = 0;
|
||||
move16();
|
||||
|
||||
IF (*sign == 0)
|
||||
{
|
||||
FOR (i = 0; i < T0; i++)
|
||||
{
|
||||
if (sub(res[i], maxval) >= 0)
|
||||
{
|
||||
maxi = add(i, 1);
|
||||
}
|
||||
maxval = s_max(res[i], maxval);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
FOR (i = 0; i < T0; i++)
|
||||
{
|
||||
if (sub(res[i], maxval) <= 0)
|
||||
{
|
||||
maxi = add(i, 1);
|
||||
}
|
||||
maxval = s_min(res[i], maxval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return maxi;
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* subband_gain_bits()
|
||||
*
|
||||
* HQ core encoder
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void subband_gain_bits_fx(
|
||||
const Word16 *Rk, /* i : bit allocation per band Q3 */
|
||||
const Word16 N, /* i : number of bands */
|
||||
Word16 *bits, /* o : gain bits per band */
|
||||
const Word16 *sfmsize /* i : Size of bands */
|
||||
)
|
||||
{
|
||||
Word16 i,b,tot;
|
||||
Word16 bps;
|
||||
|
||||
tot = 0;
|
||||
move16();
|
||||
|
||||
FOR ( i = 0; i < N; i++ )
|
||||
{
|
||||
/*bps = (short)(Rk[i]*((word16)min(32767, ceil(32767.0f/sfmsize[i]); inexact C-integer division approx. */
|
||||
bps = extract_l(L_shr(L_mult0(Rk[i], inv_tbl_fx[sfmsize[i]]), 18)); /* 3+15 */
|
||||
if (L_sub(L_shl(L_mult0(sfmsize[i], add(bps, 1)), 3), Rk[i]) == 0)
|
||||
{
|
||||
bps = add(bps, 1);
|
||||
}
|
||||
|
||||
bps = s_min(7, bps);
|
||||
b = fine_gain_bits[bps];
|
||||
move16();
|
||||
bits[i] = b;
|
||||
move16();
|
||||
tot = add(tot, b);
|
||||
}
|
||||
|
||||
if ( tot == 0)
|
||||
{
|
||||
/* If no gain bits were assigned, use one bit anyway for potential PVQ overage */
|
||||
bits[0] = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* assign_gain_bits()
|
||||
*
|
||||
* Assign gain adjustment bits and update bit budget
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
Word16 assign_gain_bits_fx( /* o : Number of assigned gain bits */
|
||||
const Word16 core, /* i : HQ core */
|
||||
const Word16 BANDS, /* i : Number of bands */
|
||||
const Word16 *band_width, /* i : Sub band bandwidth */
|
||||
Word16 *Rk, /* i/o: Bit allocation/Adjusted bit alloc. Q3 */
|
||||
Word16 *gain_bits_array, /* o : Assigned gain bits */
|
||||
Word16 *Rcalc /* o : Bit budget for shape quantizer Q3 */
|
||||
)
|
||||
{
|
||||
Word16 subband_cnt;
|
||||
Word16 gain_bits_tot;
|
||||
Word16 i;
|
||||
|
||||
/* Allocate gain bits for every subband used, based on bit rate and bandwidth */
|
||||
IF( sub(core, HQ_CORE) == 0 )
|
||||
{
|
||||
subband_gain_bits_fx(Rk, BANDS, gain_bits_array, band_width);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
set16_fx( gain_bits_array, 0, BANDS );
|
||||
}
|
||||
|
||||
/* Re-adjust bit budget for gain quantization */
|
||||
subband_cnt = 0;
|
||||
move16();
|
||||
gain_bits_tot = 0;
|
||||
move16();
|
||||
*Rcalc = 0;
|
||||
move16();
|
||||
FOR (i = 0; i < BANDS; i++)
|
||||
{
|
||||
IF (Rk[i] > 0)
|
||||
{
|
||||
subband_cnt = add(subband_cnt, 1);
|
||||
Rk[i] = sub(Rk[i], shl(gain_bits_array[i], 3));
|
||||
move16();
|
||||
gain_bits_tot = add(gain_bits_tot, gain_bits_array[i]);
|
||||
*Rcalc = add(*Rcalc, Rk[i]);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
return gain_bits_tot;
|
||||
}
|
||||
Executable
+196
@@ -0,0 +1,196 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* frame_ener()
|
||||
*
|
||||
* Estimation of pitch-synchronous (voiced) or mean half-frame (unvoiced) energy
|
||||
*----------------------------------------------------------------------------------*/
|
||||
Word16 frame_ener_fx(
|
||||
const Word16 L_frame, /* i : length of the frame */
|
||||
const Word16 clas, /* i : frame classification */
|
||||
const Word16 *synth, /* i : synthesized speech at Fs = 12k8 Hz Q_new */
|
||||
const Word16 pitch, /* i : pitch period Q0 */
|
||||
Word32 *enr_q, /* o : pitch-synchronous or half_frame energy Q0 */
|
||||
const Word16 offset, /* i : speech pointer offset (0 or L_FRAME) */
|
||||
const Word16 Q_new, /* i : Scaling factor */
|
||||
Word16 shift, /* i : Shift need to obtain 12 bits vectors */
|
||||
const Word16 enc /* i : Encoder/decoder */
|
||||
)
|
||||
{
|
||||
Word16 len, exp_enrq, exp_tmp, pos;
|
||||
Word16 i;
|
||||
const Word16 *pt_synth;
|
||||
Word32 Ltmp;
|
||||
|
||||
exp_enrq = 0;
|
||||
move16();
|
||||
test();
|
||||
test();
|
||||
IF( (sub(clas, VOICED_CLAS) == 0) || (sub(clas, ONSET) == 0) || (sub(clas, SIN_ONSET) == 0) ) /* current frame is voiced */
|
||||
{
|
||||
/* current frame is voiced */
|
||||
len = pitch;
|
||||
move16(); /* pitch value at the end of frame */
|
||||
pt_synth = synth;
|
||||
move16();
|
||||
if (offset != 0)
|
||||
{
|
||||
pt_synth = synth + sub(L_frame, len);
|
||||
}
|
||||
emaximum_fx(Q_new, pt_synth, len, enr_q);
|
||||
move16();/* pitch synchronous E */
|
||||
IF (enc != 0)
|
||||
{
|
||||
exp_enrq = norm_l(*enr_q);
|
||||
*enr_q = L_shl(*enr_q, exp_enrq);
|
||||
move32();
|
||||
exp_enrq = sub(exp_enrq, 2);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* current frame is unvoiced */
|
||||
Word16 L_frame2, exp2, enr_q_tmp;
|
||||
|
||||
L_frame2 = shr(L_frame,1);
|
||||
pos = 0;
|
||||
move16();
|
||||
|
||||
if (offset != 0)
|
||||
{
|
||||
pos = sub(L_frame, L_frame2);
|
||||
}
|
||||
Ltmp = L_mult(synth[pos], synth[pos]);
|
||||
FOR (i = 1; i < L_frame2; i++)
|
||||
{
|
||||
Ltmp = L_mac(Ltmp, synth[pos+i], synth[pos+i]);
|
||||
}
|
||||
test();
|
||||
IF (L_sub(Ltmp, MAX_32) == 0 || enc != 0)
|
||||
{
|
||||
/* scale down when overflow occurs */
|
||||
*enr_q = Energy_scale(synth+pos, L_frame2, shift, &exp_enrq);
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
shift = 0;
|
||||
move16();
|
||||
/* Normalize acc in Q31 (energy already calculated) */
|
||||
pos = norm_l(Ltmp);
|
||||
Ltmp = L_shl(Ltmp, pos);
|
||||
exp_enrq = sub(30, pos); /* exponent = 0..30 */
|
||||
*enr_q = Ltmp;
|
||||
move32();
|
||||
}
|
||||
|
||||
/* enr2 = 1.0f/L_FRAME2 * dot_product(synth, synth, L_FRAME2) */
|
||||
exp_enrq = sub(exp_enrq, shl(shift, 1));
|
||||
|
||||
IF (enc != 0)
|
||||
{
|
||||
assert(L_frame == 256 || L_frame == 320);
|
||||
|
||||
exp_tmp = add(shl(Q_new, 1), -2+7); /* L_subfr == L_SUBFR */
|
||||
exp_enrq = sub(exp_enrq, exp_tmp);
|
||||
exp_enrq = sub(31, exp_enrq);
|
||||
|
||||
IF(sub(L_frame, 320) == 0)
|
||||
{
|
||||
*enr_q = Mult_32_16(*enr_q, 26214); /*x 0.8 to get /160*/
|
||||
i = norm_l(*enr_q);
|
||||
*enr_q = L_shl(*enr_q, i);
|
||||
exp_enrq = add(i, exp_enrq);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
exp_enrq = sub(exp_enrq, add(Q_new, Q_new));
|
||||
enr_q_tmp /*Q30 exp2+exp_enrq*/ = BASOP_Util_Divide3216_Scale(*enr_q /*Q31*/, L_frame2 /*Q0*/, &exp2);
|
||||
*enr_q = L_shr(L_deposit_l(enr_q_tmp),sub(30,add(exp2,exp_enrq))); /*Q0*/
|
||||
*enr_q = L_add(*enr_q, 1);
|
||||
move32();
|
||||
exp_enrq = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return exp_enrq;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* frame_energy()
|
||||
*
|
||||
* Compute pitch-synchronous energy at the frame end
|
||||
*------------------------------------------------------------------------*/
|
||||
Word16 frame_energy_fx( /* o : Frame energy in Q8 */
|
||||
Word16 L_frame,
|
||||
const Word16 *pitch, /* i : pitch values for each subframe Q6 */
|
||||
const Word16 *speech, /* i : pointer to speech signal for E computation Q_syn*/
|
||||
const Word16 lp_speech, /* i : long term active speech energy average Q8 */
|
||||
Word16 *frame_ener, /* o : pitch-synchronous energy at frame end Q8 */
|
||||
const Word16 Q_syn /* i : Synthesis scaling */
|
||||
)
|
||||
{
|
||||
Word32 Ltmp;
|
||||
const Word16 *pt1;
|
||||
Word16 tmp16, exp1, exp2, tmp1, tmp2;
|
||||
Word16 len, enern;
|
||||
|
||||
/* len = (0.5f * (pitch[2]/64.0 + pitch[3]/64.0) + 0.5f) */
|
||||
len = mult_r(add(pitch[2], pitch[3]), 256);
|
||||
|
||||
if(sub(len,L_SUBFR) < 0 )
|
||||
{
|
||||
len = shl(len, 1);
|
||||
}
|
||||
pt1 = speech + sub(L_frame,len);
|
||||
|
||||
/* *frame_ener = 10.0f * log10(dot_product(pt1, pt1, len) / (float)len) */
|
||||
|
||||
tmp1 = norm_s(len);
|
||||
tmp2 = shl(len, tmp1);
|
||||
tmp1 = sub(15, tmp1);
|
||||
|
||||
Ltmp = Dot_productSq16HQ( 0, pt1, len, &exp1);
|
||||
exp1 = sub(exp1, shl(Q_syn, 1));
|
||||
exp1 = sub(exp1, 1); /* compensation of leftshift caused by mac operation in dot_productSq16HQ */
|
||||
tmp16 = BASOP_Util_Divide3216_Scale( Ltmp, len, &exp2);
|
||||
|
||||
exp1 = add(exp1, exp2);
|
||||
exp1 = add(exp1, 1); /* compensate result of division Q-1 */
|
||||
|
||||
|
||||
tmp2 = norm_s(tmp16);
|
||||
Ltmp = L_shl(L_deposit_h(tmp16),tmp2); /*Q16, (exp1-tmp2) = Q31, exp1-tmp2+15*/
|
||||
|
||||
Ltmp = BASOP_Util_Log2(Ltmp);/*Q(31-6) = Q25*/
|
||||
exp1 = sub(15+exp1,tmp2);
|
||||
|
||||
/*add ld(2^exp1)=exp1 but check format, first*/
|
||||
tmp16=sub(sub(15,norm_s(exp1)),5); /*factor to shift Ltmp and exp1 with (shr) to avoid overflows when adding*/
|
||||
Ltmp= L_shr(Ltmp,tmp16); /*Q25, tmp16*/
|
||||
exp2 = shr(exp1,tmp16); /*Q0 , tmp16*/
|
||||
Ltmp = L_add(Ltmp,L_shl(L_deposit_l(exp2),25)); /*Q25, tmp16, normalized*/
|
||||
|
||||
/*make 10*log10 out of log2*/
|
||||
Ltmp = Mpy_32_16_1(Ltmp,LG10); /*Q25,tmp16 * Q13 = Q23, tmp16*/
|
||||
*frame_ener = extract_h(L_shl(Ltmp,add(tmp16,1)));/*Q8*/ move16();
|
||||
enern = sub( *frame_ener ,lp_speech); /*Q8*/
|
||||
|
||||
return enern;
|
||||
}
|
||||
Executable
+254
@@ -0,0 +1,254 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#include <Winsock2.h>
|
||||
typedef unsigned short uint16_t;
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef signed __int64 int64_t;
|
||||
#endif
|
||||
#include "options.h"
|
||||
#include "stl.h"
|
||||
#include "g192.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( disable : 4996 )
|
||||
#endif
|
||||
|
||||
#define G192_SYNC_GOOD_FRAME (Word16)0x6B21
|
||||
#define G192_SYNC_BAD_FRAME (Word16)0x6B20
|
||||
#define G192_BIT0 (Word16)0x007F
|
||||
#define G192_BIT1 (Word16)0x0081
|
||||
#define MAX_BITS_PER_FRAME 2560
|
||||
#define RTP_HEADER_PART1 (Word16)22 /* magic number by network simulator */
|
||||
|
||||
/*
|
||||
* Structures
|
||||
*/
|
||||
|
||||
/* main handle */
|
||||
struct __G192
|
||||
{
|
||||
FILE * file;
|
||||
};
|
||||
|
||||
/*
|
||||
* Functions
|
||||
*/
|
||||
|
||||
G192_ERROR
|
||||
G192_Reader_Open(G192_HANDLE* phG192, FILE * filename)
|
||||
{
|
||||
/* create handle */
|
||||
*phG192 = (G192_HANDLE) calloc(1, sizeof(struct __G192) );
|
||||
if ( *phG192 == NULL )
|
||||
{
|
||||
return G192_MEMORY_ERROR;
|
||||
}
|
||||
|
||||
memset(*phG192, 0, sizeof(struct __G192));
|
||||
|
||||
/* associate file stream */
|
||||
(*phG192)->file = filename;
|
||||
if( (*phG192)->file == NULL )
|
||||
{
|
||||
G192_Reader_Close(phG192);
|
||||
return G192_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
|
||||
G192_ERROR
|
||||
G192_ReadVoipFrame_compact(G192_HANDLE const hG192,
|
||||
unsigned char * const serial,
|
||||
Word16 * const num_bits,
|
||||
Word16 *rtpSequenceNumber,
|
||||
Word32 *rtpTimeStamp,
|
||||
Word32 *rcvTime_ms)
|
||||
{
|
||||
Word16 short_serial [MAX_BITS_PER_FRAME];
|
||||
G192_ERROR err;
|
||||
Word16 i;
|
||||
|
||||
err = G192_ReadVoipFrame_short(hG192, short_serial, num_bits, rtpSequenceNumber, rtpTimeStamp, rcvTime_ms);
|
||||
if(err != G192_NO_ERROR)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
for(i=0; i<*num_bits; i++)
|
||||
{
|
||||
unsigned char bit = (short_serial[i] == G192_BIT1) ? 1 : 0;
|
||||
unsigned char bitinbyte = bit << (7- (i&0x7));
|
||||
if(!(i&0x7))
|
||||
serial[i>>3] = 0;
|
||||
serial[i>>3] |= bitinbyte;
|
||||
}
|
||||
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
|
||||
G192_ERROR
|
||||
G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
Word16 * const serial,
|
||||
Word16 *num_bits,
|
||||
Word16 *rtpSequenceNumber,
|
||||
Word32 *rtpTimeStamp,
|
||||
Word32 *rcvTime_ms)
|
||||
{
|
||||
Word32 rtpPacketSize;
|
||||
Word16 rtpPacketHeaderPart1;
|
||||
Word32 ssrc;
|
||||
Word16 rtpPayloadG192[2];
|
||||
Word16 rtpPayloadSize;
|
||||
|
||||
/* RTP packet size */
|
||||
if(fread(&rtpPacketSize, sizeof(rtpPacketSize), 1, hG192->file) != 1)
|
||||
{
|
||||
if(feof( hG192->file) != 0)
|
||||
{
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP Packet Size could't be read\n");
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
if(rtpPacketSize <= 12)
|
||||
{
|
||||
fprintf(stderr, "RTP Packet size too small: %d\n", rtpPacketSize);
|
||||
return G192_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* RTP packet arrival time */
|
||||
if(fread(rcvTime_ms, sizeof(*rcvTime_ms), 1, hG192->file) != 1)
|
||||
{
|
||||
if(feof( hG192->file) != 0)
|
||||
{
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "Reception Time in ms could't be read\n");
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
/* RTP packet header (part without sequence number) */
|
||||
if(fread(&rtpPacketHeaderPart1, sizeof(rtpPacketHeaderPart1), 1, hG192->file) != 1)
|
||||
{
|
||||
if(feof( hG192->file) != 0)
|
||||
{
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP Header couldn't be read\n");
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
if(rtpPacketHeaderPart1 != RTP_HEADER_PART1)
|
||||
{
|
||||
fprintf(stderr, "Unexpected RTP Packet header\n");
|
||||
return G192_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* RTP sequence number */
|
||||
if(fread(rtpSequenceNumber, sizeof(*rtpSequenceNumber), 1, hG192->file) != 1)
|
||||
{
|
||||
if(feof( hG192->file) != 0)
|
||||
{
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP Sequence Number be read\n");
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
*rtpSequenceNumber = ntohs(*rtpSequenceNumber);
|
||||
/* RTP timestamp */
|
||||
if(fread(rtpTimeStamp, sizeof(*rtpTimeStamp), 1, hG192->file) != 1)
|
||||
{
|
||||
if(feof( hG192->file) != 0)
|
||||
{
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP Timestamp could't be read\n");
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
*rtpTimeStamp = ntohl(*rtpTimeStamp);
|
||||
/* RTP ssrc */
|
||||
if(fread(&ssrc, sizeof(ssrc), 1, hG192->file) != 1)
|
||||
{
|
||||
if(feof( hG192->file) != 0)
|
||||
{
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP SSRC could't be read\n");
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
/* RTP payload size */
|
||||
rtpPayloadSize = (Word16)(rtpPacketSize - 12);
|
||||
if(rtpPayloadSize <= 2)
|
||||
{
|
||||
fprintf(stderr, "RTP payload size too small: %d\n", rtpPayloadSize);
|
||||
return G192_INVALID_DATA;
|
||||
}
|
||||
/* RTP payload */
|
||||
if(fread(rtpPayloadG192, sizeof(Word16), 2, hG192->file) != 2)
|
||||
{
|
||||
if(feof( hG192->file) != 0)
|
||||
{
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "Premature end of file, cannot read G.192 header\n");
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
if(rtpPayloadG192[0] != G192_SYNC_GOOD_FRAME)
|
||||
{
|
||||
fprintf(stderr, "G192_SYNC_WORD missing from RTP payload!");
|
||||
return G192_INVALID_DATA;
|
||||
}
|
||||
*num_bits = rtpPayloadG192[1];
|
||||
if(*num_bits == 0 || *num_bits + 2 != rtpPayloadSize || *num_bits > MAX_BITS_PER_FRAME)
|
||||
{
|
||||
fprintf(stderr, "error in parsing RTP payload: rtpPayloadSize=%u nBits=%d",
|
||||
rtpPayloadSize, *num_bits);
|
||||
return G192_INVALID_DATA;
|
||||
}
|
||||
if( (Word16)fread(serial, sizeof(Word16), *num_bits, hG192->file) != *num_bits)
|
||||
{
|
||||
if(feof( hG192->file) != 0)
|
||||
{
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "Premature end of file, cannot read G.192 payload\n");
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
|
||||
G192_ERROR
|
||||
G192_Reader_Close(G192_HANDLE* phG192)
|
||||
{
|
||||
if(phG192 == NULL || *phG192 == NULL)
|
||||
{
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
|
||||
free( *phG192 );
|
||||
*phG192 = NULL;
|
||||
phG192 = NULL;
|
||||
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
Executable
+64
@@ -0,0 +1,64 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef G192_H
|
||||
#define G192_H G192_H
|
||||
|
||||
/*
|
||||
* ENUMS
|
||||
*/
|
||||
|
||||
/* error enums */
|
||||
|
||||
typedef enum _G192_ERROR
|
||||
{
|
||||
G192_NO_ERROR = 0x0000,
|
||||
G192_MEMORY_ERROR = 0x0001,
|
||||
G192_WRONG_PARAMS = 0x0002,
|
||||
G192_INIT_ERROR = 0x0003,
|
||||
G192_WRITE_ERROR = 0x0004,
|
||||
G192_READ_ERROR = 0x0005,
|
||||
G192_FILE_NOT_FOUND = 0x0006,
|
||||
G192_INVALID_DATA = 0x0007, /* error returned when read data is invalid */
|
||||
G192_NOT_IMPLEMENTED = 0x0010,
|
||||
G192_NOT_INITIALIZED = 0x0100,
|
||||
G192_UNKNOWN_ERROR = 0x1000,
|
||||
G192_EOF = 0xffff /* EOF during reading */
|
||||
} G192_ERROR;
|
||||
|
||||
/*
|
||||
* Structures
|
||||
*/
|
||||
|
||||
/* main handle */
|
||||
struct __G192;
|
||||
typedef struct __G192 * G192_HANDLE;
|
||||
|
||||
/*
|
||||
* Functions
|
||||
*/
|
||||
|
||||
G192_ERROR
|
||||
G192_Reader_Open(G192_HANDLE* phG192, FILE * filename);
|
||||
|
||||
G192_ERROR
|
||||
G192_ReadVoipFrame_compact(G192_HANDLE const hG192,
|
||||
unsigned char * const serial,
|
||||
Word16 * const num_bits,
|
||||
Word16 *rtpSequenceNumber,
|
||||
Word32 *rtpTimeStamp,
|
||||
Word32 *rcvTime_ms);
|
||||
|
||||
G192_ERROR
|
||||
G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
Word16 * const serial,
|
||||
Word16 *num_bits,
|
||||
Word16 *rtpSequenceNumber,
|
||||
Word32 *rtpTimeStamp,
|
||||
Word32 *rcvTime_ms);
|
||||
|
||||
G192_ERROR
|
||||
G192_Reader_Close(G192_HANDLE* phG192);
|
||||
|
||||
#endif /* G192_H */
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
#include "rom_com_fx.h"
|
||||
|
||||
|
||||
Word32 calc_gain_inov( /* returns innovation gain Q16 */
|
||||
const Word16 *code, /* i : algebraic excitation Q9 */
|
||||
Word16 lcode, /* i : Subframe size Q0 */
|
||||
Word32 *dotp, /* o : intermediate result Q31-e */
|
||||
Word16 *dotp_e /* o : intermediate result exponent Q0 */
|
||||
)
|
||||
{
|
||||
Word32 L_tmp;
|
||||
Word16 exp_L_tmp, i;
|
||||
|
||||
/* L_tmp = dot_product(code, code, lcode) + 0.01 */
|
||||
L_tmp = Dot_product12_offs(code, code, lcode, &exp_L_tmp, 2621l/*0.01f/2.0f Q19*/);
|
||||
exp_L_tmp = sub(exp_L_tmp, 18);
|
||||
|
||||
/* gain_inov = 1.0f / sqrt((dot_product(code, code, lcode) + 0.01) / lcode) */
|
||||
/* Note: lcode is in range: 32,40,64,80 */
|
||||
assert((lcode == 32) || (lcode == 40) || (lcode == 64) || (lcode == 80));
|
||||
if (s_and(lcode, sub(lcode, 1)) != 0)
|
||||
{
|
||||
L_tmp = Mpy_32_32(L_tmp, 1717986918l/*64.0/80.0 Q31*/);
|
||||
}
|
||||
exp_L_tmp = sub(exp_L_tmp, sub(14, norm_s(lcode)));
|
||||
|
||||
i = norm_l(L_tmp);
|
||||
L_tmp = L_shl(L_tmp, i);
|
||||
exp_L_tmp = sub(exp_L_tmp, i);
|
||||
|
||||
if (dotp != NULL)
|
||||
{
|
||||
*dotp = L_tmp;
|
||||
move32();
|
||||
}
|
||||
if (dotp_e != NULL)
|
||||
{
|
||||
*dotp_e = exp_L_tmp;
|
||||
move16();
|
||||
}
|
||||
|
||||
L_tmp = ISqrt32norm(L_tmp, &exp_L_tmp);
|
||||
|
||||
return L_shl(L_tmp, sub(exp_L_tmp, 15)); /* 15Q16 */
|
||||
}
|
||||
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
Word32 get_gain( /* output: codebook gain (adaptive or fixed) Q16 */
|
||||
Word16 x[], /* input : target signal */
|
||||
Word16 y[], /* input : filtered codebook excitation */
|
||||
Word16 n /* input : segment length */
|
||||
)
|
||||
{
|
||||
Word32 tcorr, tener, Lgain;
|
||||
Word16 exp_c, exp_e, exp, tmp;
|
||||
|
||||
|
||||
tcorr = L_deposit_l(0);
|
||||
tener = L_deposit_l(0);
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Find gain based on inter-correlation product
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
tcorr = Dot_product16HQ( 0, x, y, n, &exp_c );
|
||||
tener = Dot_productSq16HQ( 0, y, n, &exp_e );
|
||||
|
||||
BASOP_Util_Divide_MantExp(round_fx(tcorr), exp_c, s_max(round_fx(tener),1), exp_e, &tmp,&exp);
|
||||
Lgain = L_shl(L_deposit_l(tmp)/*Q15*/,add(1,exp))/*Q16*/;
|
||||
|
||||
return Lgain;
|
||||
}
|
||||
|
||||
Word32 get_gain2( /* output: codebook gain (adaptive or fixed) Q16 */
|
||||
Word16 x[], /* input : target signal */
|
||||
Word16 y[], /* input : filtered codebook excitation */
|
||||
Word16 n /* input : segment length */
|
||||
)
|
||||
{
|
||||
Word32 tcorr, tener, Lgain;
|
||||
Word16 m_corr, m_ener, negative, Q_corr, Q_ener;
|
||||
|
||||
negative = 0;
|
||||
move16();
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Find gain based on inter-correlation product
|
||||
*----------------------------------------------------------------*/
|
||||
tcorr = Dot_product16HQ(0, x, y, n, &Q_corr);
|
||||
tener = Dot_productSq16HQ(0, y, n, &Q_ener);
|
||||
|
||||
tener = L_max(tener, 1);
|
||||
|
||||
if (tcorr <= 0)
|
||||
{
|
||||
negative = 1;
|
||||
move16();
|
||||
}
|
||||
BASOP_SATURATE_WARNING_OFF /*tcorr max be negative maxvall - not critical*/
|
||||
tcorr = L_abs(tcorr);
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
|
||||
m_corr = extract_h(tcorr);
|
||||
|
||||
m_ener = extract_h(tener);
|
||||
|
||||
IF (sub(m_corr, m_ener) > 0)
|
||||
{
|
||||
m_corr = shr(m_corr, 1);
|
||||
Q_corr = add(Q_corr,1);
|
||||
}
|
||||
if (m_ener==0)
|
||||
{
|
||||
move16();
|
||||
m_corr = 0x7FFF;
|
||||
}
|
||||
if (m_ener != 0)
|
||||
{
|
||||
m_corr = div_s(m_corr, m_ener);
|
||||
}
|
||||
|
||||
Q_corr = sub(Q_corr,Q_ener);
|
||||
|
||||
Lgain = L_shl(L_deposit_l(m_corr), add(Q_corr, 1)); /* Lgain in Q16 */
|
||||
|
||||
if (negative != 0)
|
||||
{
|
||||
Lgain = L_negate(Lgain); /* Lgain in Q16 */
|
||||
}
|
||||
|
||||
|
||||
return Lgain;
|
||||
}
|
||||
+481
@@ -0,0 +1,481 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "assert.h" /* Debug prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*==================================================================================*/
|
||||
/* FUNCTION : void bands_and_bit_alloc_fx(); */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* PURPOSE : AC mode (GSC) bands and bits allocation */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16) cor_strong_limit : HF correlation */
|
||||
/* _ (Word16) noise_lev : dwn scaling factor Q0 */
|
||||
/* _ (Word32) core_brate : core codec used Q0 */
|
||||
/* _ (Word16) Diff_len : Lenght of the difference signal Q0 */
|
||||
/* _ (Word16) bits_used : Number of bit used before frequency Q0 */
|
||||
/* _ (Word16) idx : Energy band 14 Q0 */
|
||||
/* _ (Word16*) exc_diff : Difference signal to quantize (Encoder only) */
|
||||
/* _ (Word16) coder_type : coding type Q0 */
|
||||
/* _ (Word16) bwidth : input signal bandwidth Q0 */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*) max_ener_band : Sorted order */
|
||||
/* _ (Word16*) nb_subbands : Number of subband allowed Q0 */
|
||||
/* _ (Word16*) concat_in : Concatened PVQ's input vector (Encoder Only) */
|
||||
/* _ (Word16*) pvq_len : Number of bin covered with the PVQ Q0 */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*) bit :Number of bit allowed for frequency quantization */
|
||||
/* _ (Word16*) Ener_per_bd_iQ : Quantized energy vector Q13 */
|
||||
/* _ (Word32*) bits_per_bands : Number of bit allowed per allowed subband Q18 */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*==================================================================================*/
|
||||
void bands_and_bit_alloc_fx(
|
||||
const Word16 cor_strong_limit, /* i : HF correlation */
|
||||
const Word16 noise_lev, /* i : dwn scaling factor */
|
||||
const Word32 core_brate, /* i : core bit rate */
|
||||
const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/
|
||||
const Word16 bits_used, /* i : Number of bit used before frequency Q */
|
||||
Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */
|
||||
const Word16 *Ener_per_bd_iQ, /* i/o: Quantized energy vector */
|
||||
Word16 *max_ener_band, /* o : Sorted order */
|
||||
Word16 *out_bits_per_bands, /* i/o: Number of bit allowed per allowed subband Q3 */
|
||||
Word16 *nb_subbands, /* o : Number of subband allowed */
|
||||
const Word16 *exc_diff, /* i : Difference signal to quantize (encoder side only) */
|
||||
Word16 *concat_in, /* o : Concatened PVQ's input vector (encoder side only) */
|
||||
Word16 *pvq_len, /* o : Number of bin covered with the PVQ */
|
||||
const Word16 coder_type, /* i : coding type */
|
||||
const Word16 bwidth, /* i : input signal bandwidth */
|
||||
const Word16 GSC_noisy_speech
|
||||
)
|
||||
{
|
||||
|
||||
Word16 bandoffset, i, j, nb_bands_max, bit_new_bands, bit_tmp, st_band, nb_bands;
|
||||
Word16 ener_vec[MBANDS_GN]; /*Q12 */
|
||||
Word16 nb_tot_bands = 16;
|
||||
Word16 bit_index, bit_index_mem, imax;
|
||||
Word32 L_tmp;
|
||||
Word32 sum_bit, bit_fracf;
|
||||
Word16 etmp;
|
||||
Word16 tmp;
|
||||
Word16 Ener_per_bd_iQ_tmp[MBANDS_GN];
|
||||
Word16 pos, band;
|
||||
Word16 SWB_bit_budget;
|
||||
Word32 bits_per_bands[MBANDS_GN];
|
||||
Word16 w_sum_bit;
|
||||
|
||||
Copy( Ener_per_bd_iQ, Ener_per_bd_iQ_tmp, MBANDS_GN );
|
||||
|
||||
set32_fx( bits_per_bands, 0, MBANDS_GN );
|
||||
set16_fx( out_bits_per_bands, 0, MBANDS_GN );
|
||||
|
||||
/* To adapt current energy band to PVQ freq band for sorting*/
|
||||
ener_vec[0] = add(Ener_per_bd_iQ[0],Ener_per_bd_iQ[1]); /*Q12 */
|
||||
Copy( Ener_per_bd_iQ_tmp+1, ener_vec, 15 ); /*Q12 */
|
||||
ener_vec[15] = ener_vec[14];
|
||||
move16();
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* Determination of the number of bits available to the frequency domain
|
||||
* Allocation of a maximum number of band to be encoded
|
||||
*-----------------------------------------------------------------------*/
|
||||
|
||||
nb_bands_max = nb_tot_bands;
|
||||
move16();
|
||||
bit_new_bands = 5;
|
||||
move16();
|
||||
|
||||
bit_index = i_mult2(BRATE2IDX_fx(core_brate),17);
|
||||
bit_index_mem = bit_index;
|
||||
move16();
|
||||
|
||||
test();
|
||||
test();
|
||||
IF( (sub(coder_type,AUDIO) == 0 || sub(coder_type,INACTIVE) == 0) && sub(bwidth,NB) == 0 )
|
||||
{
|
||||
IF(L_sub(core_brate,ACELP_9k60) >= 0)
|
||||
{
|
||||
/* *bit = (short)(core_brate*(1.0f/50) + 0.5f) - bits_used - 25; */
|
||||
L_tmp = Mult_32_16(core_brate,20971);
|
||||
tmp = extract_l(L_shr_r(L_tmp,5));
|
||||
*bit = sub(sub(tmp,bits_used), 25);
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_tmp = Mult_32_16(core_brate,20971);
|
||||
tmp = extract_l(L_shr_r(L_tmp,5));
|
||||
*bit = sub(sub(tmp,bits_used), 21);
|
||||
move16();
|
||||
}
|
||||
nb_tot_bands = 10;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* *bit = (short)(core_brate*(1.0f/50) + 0.5f) - bits_used - GSC_freq_bits[bit_index]; */
|
||||
|
||||
L_tmp = Mult_32_16(core_brate,20971);
|
||||
tmp = extract_l(L_shr_r(L_tmp,5));
|
||||
*bit = sub(sub(tmp,bits_used),GSC_freq_bits[bit_index]);
|
||||
move16();
|
||||
}
|
||||
|
||||
IF( sub(GSC_noisy_speech,1) == 0 )
|
||||
{
|
||||
SWB_bit_budget = *bit;
|
||||
move16();
|
||||
nb_bands = 5;
|
||||
move16();
|
||||
st_band = nb_bands;
|
||||
move16();
|
||||
|
||||
set32_fx( bits_per_bands, 0, MBANDS_GN );
|
||||
/*bit_fracf = (1.0f/nb_bands)*(SWB_bit_budget); */
|
||||
bit_fracf = L_mult(div_s(1,nb_bands),shl(SWB_bit_budget,2)); /* Q18 */
|
||||
|
||||
nb_tot_bands = sub(nb_bands_max,6);
|
||||
nb_tot_bands = s_min(nb_tot_bands, 16);
|
||||
|
||||
FOR(j = 0; j < 2; j++)
|
||||
{
|
||||
i = j;
|
||||
move16();
|
||||
max_ener_band[j] = i;
|
||||
move16();
|
||||
ener_vec[i] = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR(; j < nb_bands; j++)
|
||||
{
|
||||
i = maximum_fx(ener_vec, nb_tot_bands, &etmp);
|
||||
max_ener_band[j] = i;
|
||||
move16();
|
||||
ener_vec[i] = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
set32_fx(bits_per_bands, bit_fracf, nb_bands);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
bit_index++;
|
||||
bit_tmp = sub(*bit,GSC_freq_bits[bit_index]);
|
||||
bit_index++;
|
||||
nb_bands_max = add(nb_bands_max,GSC_freq_bits[bit_index]);
|
||||
bit_index++;
|
||||
|
||||
*pvq_len = 112;
|
||||
move16();
|
||||
st_band = 7;
|
||||
move16();
|
||||
|
||||
IF( L_sub(core_brate,ACELP_9k60) <= 0 )
|
||||
{
|
||||
*pvq_len = 80;
|
||||
move16();
|
||||
st_band = 5;
|
||||
move16();
|
||||
|
||||
IF( Diff_len == 0 )
|
||||
{
|
||||
nb_bands_max = add(nb_bands_max,2);
|
||||
bit_tmp = sub(bit_tmp,13);
|
||||
}
|
||||
}
|
||||
|
||||
ELSE IF( Diff_len == 0 )
|
||||
{
|
||||
nb_bands_max = add(nb_bands_max,2);
|
||||
bit_tmp = sub(bit_tmp,17);
|
||||
}
|
||||
|
||||
nb_bands = shr(*pvq_len,4);
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* Ajustement of the maximum number of bands in function of the
|
||||
* dynamics of the spectrum (more or less speech like)
|
||||
*-----------------------------------------------------------------------*/
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF( sub(coder_type,INACTIVE) == 0 || sub(noise_lev,NOISE_LEVEL_SP3) >= 0 )
|
||||
{
|
||||
/* Probably classification error -> concentrate bits on LF */
|
||||
nb_bands_max = nb_bands;
|
||||
move16();
|
||||
if( L_sub(core_brate,ACELP_8k00) >= 0 )
|
||||
{
|
||||
nb_bands_max = add(nb_bands,1);
|
||||
}
|
||||
}
|
||||
ELSE IF( sub(noise_lev,NOISE_LEVEL_SP2) >= 0 ||
|
||||
(L_sub(core_brate,ACELP_13k20) <= 0 && L_sub(core_brate,ACELP_9k60) >= 0 && cor_strong_limit == 0) ) /* Very low dynamic, tend to speech, do not try to code HF at all */
|
||||
{
|
||||
nb_bands_max = sub(nb_bands_max,2);
|
||||
}
|
||||
ELSE if( sub(noise_lev,NOISE_LEVEL_SP1) >= 0) /* Very low dynamic, tend to speech, code less HF */
|
||||
{
|
||||
nb_bands_max = sub(nb_bands_max,1);
|
||||
}
|
||||
|
||||
test();
|
||||
if( sub(bwidth,NB) == 0 && sub(nb_bands_max,10) > 0 )
|
||||
{
|
||||
nb_bands_max = 10;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* Find extra number of band to code according to bit rate availables
|
||||
*-----------------------------------------------------------------------*/
|
||||
WHILE ( sub(bit_tmp,bit_new_bands) >= 0 && sub(nb_bands,sub(nb_bands_max, 1)) <= 0 )
|
||||
{
|
||||
bit_tmp = sub(bit_tmp,bit_new_bands);
|
||||
nb_bands = add(nb_bands,1);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* Fractional bits to distribute on the first x bands
|
||||
*-----------------------------------------------------------------------*/
|
||||
|
||||
bit_fracf = L_mult(div_s(1,st_band),shl(bit_tmp,2)); /* Q18 */
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* Complete the bit allocation per frequency band
|
||||
*-----------------------------------------------------------------------*/
|
||||
imax = 5;
|
||||
move16();
|
||||
|
||||
if( L_sub(core_brate,ACELP_9k60) > 0 )
|
||||
{
|
||||
imax = 7;
|
||||
move16();
|
||||
}
|
||||
FOR(i = 0; i < imax; i++)
|
||||
{
|
||||
bits_per_bands[i] = L_add(GSC_freq_bits_fx[bit_index],bit_fracf);
|
||||
move32();/* Q18 */
|
||||
bit_index = add(bit_index,1);
|
||||
}
|
||||
|
||||
IF( Diff_len == 0 )
|
||||
{
|
||||
bit_index = add(bit_index_mem,10);
|
||||
FOR( i = 0; i < 7; i++ )
|
||||
{
|
||||
bits_per_bands[i] = L_add(bits_per_bands[i],GSC_freq_bits_fx[bit_index]);
|
||||
move32();/*chk Q18 */
|
||||
bit_index = add(bit_index,1);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Complete the bit allocation per frequency band for 16kHz high brate mode
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
FOR( j = st_band; j < nb_bands; j++ )
|
||||
{
|
||||
bits_per_bands[j] = L_shl(bit_new_bands,18);
|
||||
move32(); /*chk Q18 */
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Compute a maximum band (band offset) for the search on maximal energy
|
||||
* This is function of the spectral dynamic and the bitrate
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
bandoffset = sub(nb_tot_bands,add(nb_bands,2));
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF( sub(noise_lev,NOISE_LEVEL_SP1a) <= 0 )
|
||||
{
|
||||
bandoffset = sub(bandoffset,1);
|
||||
}
|
||||
ELSE if ( (L_sub(core_brate,ACELP_13k20) <= 0 && (sub(coder_type,INACTIVE) == 0 || sub(noise_lev,NOISE_LEVEL_SP3) >= 0)) ||
|
||||
(L_sub(core_brate,ACELP_13k20) <= 0 && L_sub(core_brate,ACELP_9k60) >= 0 && cor_strong_limit == 0) )
|
||||
{
|
||||
bandoffset = add(bandoffset,1);
|
||||
}
|
||||
|
||||
bandoffset = s_max(bandoffset ,0);
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Initiazed sorted vector
|
||||
* For the first x bands to be included in th final sorted vector
|
||||
* Sort the remaining bands in decrease energy order
|
||||
*--------------------------------------------------------------------------*/
|
||||
FOR(j = 0; j < nb_tot_bands; j++)
|
||||
{
|
||||
max_ener_band[j] = -10;
|
||||
move16();
|
||||
}
|
||||
FOR(j = 0; j < st_band; j++)
|
||||
{
|
||||
max_ener_band[j] = j;
|
||||
move16();
|
||||
ener_vec[j] = -10;
|
||||
move16();
|
||||
}
|
||||
pos = st_band;
|
||||
move16();
|
||||
FOR(; j < nb_bands; j++)
|
||||
{
|
||||
i = maximum_fx(ener_vec, sub(nb_tot_bands,bandoffset), &etmp);
|
||||
pos = s_max(pos,i);
|
||||
max_ener_band[j] = i;
|
||||
move16();
|
||||
ener_vec[i] = -10;
|
||||
move16();
|
||||
}
|
||||
|
||||
/* re-allocate bits to the frames such that the highest band with allocated bits is higher than the threshold */
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF( sub(sub(nb_tot_bands, bandoffset),nb_bands) > 0 && ( sub(pos,7) > 0 && L_sub(core_brate,ACELP_8k00) == 0 ) && sub(bwidth,WB) == 0 )
|
||||
{
|
||||
band = sub(nb_tot_bands, add(bandoffset,nb_bands));
|
||||
FOR(j=0; j<band; j++)
|
||||
{
|
||||
i = maximum_fx( ener_vec, sub(nb_tot_bands,bandoffset), &etmp );
|
||||
max_ener_band[add(nb_bands,j)] = i;
|
||||
move16();
|
||||
ener_vec[i] = -10;
|
||||
move16();
|
||||
bits_per_bands[add(nb_bands,j)] = 1310720;
|
||||
move32(); /*Q18 */
|
||||
}
|
||||
nb_bands = add(nb_bands,band);
|
||||
|
||||
bit_tmp = i_mult2(band,5);
|
||||
|
||||
IF( sub(band,2) <= 0 )
|
||||
{
|
||||
FOR(j = sub(st_band,1); j < nb_bands; j++)
|
||||
{
|
||||
bits_per_bands[j] = L_add(bits_per_bands[j],262144); /*Q18 */ move32();
|
||||
}
|
||||
bit_tmp = add(bit_tmp, add(sub(nb_bands, st_band) , 1));
|
||||
}
|
||||
|
||||
i = 0;
|
||||
move16();
|
||||
j = 0;
|
||||
move16();
|
||||
FOR( ; bit_tmp > 0; bit_tmp--)
|
||||
{
|
||||
bits_per_bands[j] = L_sub(bits_per_bands[j],262144); /*Q18 */
|
||||
j = add(j,1);
|
||||
if ( sub(j,sub(st_band, i)) == 0 )
|
||||
{
|
||||
j = 0;
|
||||
move16();
|
||||
}
|
||||
test();
|
||||
if( j == 0 && sub(i,sub(st_band, 1)) < 0)
|
||||
{
|
||||
i = add(i,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------
|
||||
* Bit sum verification for GSC inactive at very high rate
|
||||
* The maximum number of bits per band of length 16 is 112
|
||||
* Redistribute the overage bits if needed
|
||||
*--------------------------------------------------------------------------*/
|
||||
sum_bit = 0;
|
||||
move16();
|
||||
j = 0;
|
||||
move16();
|
||||
FOR( i = 0; i < nb_bands; i++ )
|
||||
{
|
||||
L_tmp = Mult_32_16(sum_bit,10923);
|
||||
|
||||
IF( L_sub(bits_per_bands[i],29360128) > 0) /* 112 in Q18 */
|
||||
{
|
||||
sum_bit = L_add(sum_bit,L_sub(bits_per_bands[i],29360128)); /* Q18 */
|
||||
bits_per_bands[i] = 29360128;
|
||||
move32();
|
||||
j = add(i,1);
|
||||
}
|
||||
ELSE if( L_sub(L_add(bits_per_bands[i],L_tmp),29360128 ) > 0) /* Q18 */
|
||||
{
|
||||
j = add(i,1);
|
||||
}
|
||||
}
|
||||
|
||||
IF( sum_bit != 0 )
|
||||
{
|
||||
tmp = sub(nb_bands,j);
|
||||
sum_bit = Mult_32_16(sum_bit,div_s(1,tmp)); /* Q18 */
|
||||
FOR( i = j; i < nb_bands; i++ )
|
||||
{
|
||||
bits_per_bands[i] = L_add(bits_per_bands[i],sum_bit);
|
||||
move32();/* Q18 */
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------
|
||||
* second step of bit sum verification, normally sum_bit == *bit
|
||||
*--------------------------------------------------------------------------*/
|
||||
w_sum_bit = 0;
|
||||
move16();
|
||||
FOR( i = 0; i < nb_bands; i++ )
|
||||
{
|
||||
out_bits_per_bands[i] = shl(extract_l(L_shr(bits_per_bands[i],18)),3);
|
||||
move16();
|
||||
w_sum_bit = add(w_sum_bit,out_bits_per_bands[i]); /* Q3 */
|
||||
}
|
||||
tmp = shl(*bit,3);
|
||||
|
||||
IF( sub(tmp,w_sum_bit)>0 )
|
||||
{
|
||||
i = sub(nb_bands,1);
|
||||
move16();
|
||||
FOR( ; tmp > w_sum_bit; w_sum_bit += (1<<3) )
|
||||
{
|
||||
out_bits_per_bands[i] = add(out_bits_per_bands[i],1<<3);
|
||||
move16();
|
||||
i = sub(i, 1);
|
||||
if(i==0)
|
||||
{
|
||||
i = sub(nb_bands,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------
|
||||
* Recompute the real number/length of frequency bands to encode
|
||||
*--------------------------------------------------------------------------*/
|
||||
*nb_subbands = nb_bands;
|
||||
move16();
|
||||
*pvq_len = shl(*nb_subbands,4);
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Concatenate bands (encoder only)
|
||||
*--------------------------------------------------------------------------*/
|
||||
IF( exc_diff != NULL )
|
||||
{
|
||||
FOR( j = 0; j < nb_bands; j++ )
|
||||
{
|
||||
Copy( exc_diff + shl(max_ener_band[j],4), concat_in+shl(j,4), 16 );
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+673
@@ -0,0 +1,673 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
static Word16 VDQ_vec_fx( Word16 *Qvec_out_fx, const Word16 *mean_dic_fx, const Word16 *dic_fx,
|
||||
const Word16 index_fx, const Word16 vec_en_fx );
|
||||
|
||||
/*========================================================================*/
|
||||
/* FUNCTION : void Comp_and_apply_gain_enc_fx */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* PURPOSE : Compute and apply the quantized per band gain */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16[]) Ener_per_bd_iQ : Target ener per band Q12 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16[]) exc_diffQ : Quantized excitation Qexc */
|
||||
/* _ (Word16[]) Ener_per_bd_yQ : Ener per band for norm vectori->Q12/o->Q2*/
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*========================================================================*/
|
||||
void Comp_and_apply_gain_fx(
|
||||
Word16 exc_diffQ[], /* i/o: Quantized excitation */
|
||||
Word16 Ener_per_bd_iQ[], /* i : Target ener per band Q13 */
|
||||
Word16 Ener_per_bd_yQ[], /* i/o : Ener per band for norm vector i->Q13/o->Q13 */
|
||||
Word16 Mbands_gn, /* i : number of bands */
|
||||
const Word16 ReUseGain, /* i : Reuse the gain in Ener_per_bd_yQ */
|
||||
Word16 Qexc_diff,
|
||||
Word16 Q_exc
|
||||
)
|
||||
{
|
||||
Word16 i, i_band;
|
||||
Word16 StartBin, NB_Qbins;
|
||||
Word16 y_gain;
|
||||
Word16 L16, frac, exp1, tmp_exp;
|
||||
Word32 L32;
|
||||
|
||||
/* Recreate excitation for local synthesis and decoder */
|
||||
StartBin = 0;
|
||||
move16();
|
||||
NB_Qbins = 0;
|
||||
move16();
|
||||
|
||||
tmp_exp = add(14,sub(Q_exc,Qexc_diff)); /* In case of reuse, it can be computed outside the loop*/
|
||||
FOR( i_band = 0; i_band < Mbands_gn; i_band++ )
|
||||
{
|
||||
StartBin = add(StartBin, NB_Qbins);
|
||||
NB_Qbins = mfreq_bindiv_loc[i_band];
|
||||
move16();
|
||||
IF( sub(ReUseGain,1) == 0 )
|
||||
{
|
||||
y_gain = Ener_per_bd_yQ[i_band];
|
||||
move16();
|
||||
|
||||
FOR(i = StartBin ; i < NB_Qbins + StartBin ; i++)
|
||||
{
|
||||
L32 = L_shl(L_mult(exc_diffQ[i], y_gain),tmp_exp); /*Q_exc+16 */
|
||||
exc_diffQ[i] = round_fx(L32);/*Q_exc */
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/*-----------------------------------------------------------------*
|
||||
* y_gain = pow(10.0, (Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
|
||||
* = pow(2, 3.321928*(Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
|
||||
*-----------------------------------------------------------------*/
|
||||
L16 = sub(Ener_per_bd_iQ[i_band], Ener_per_bd_yQ[i_band]);/*Q12 */
|
||||
L32 = L_mult(L16, 27213); /* 3.321928 in Q13 -> Q26 */
|
||||
L32 = L_shr(L32, 10); /* From Q26 to Q16 */
|
||||
frac = L_Extract_lc(L32, &exp1); /* Extract exponent of gcode0 */
|
||||
y_gain = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */
|
||||
/* output of Pow2() will be: */
|
||||
/* 16384 < Pow2() <= 32767 */
|
||||
Ener_per_bd_yQ[i_band] = shl(y_gain, sub(exp1, 13));
|
||||
move16();/*Q1 */
|
||||
tmp_exp = add(add(exp1,1),sub(Q_exc,Qexc_diff));
|
||||
|
||||
FOR(i = StartBin ; i < NB_Qbins + StartBin ; i++)
|
||||
{
|
||||
L32 = L_mult(exc_diffQ[i], y_gain); /*Qexc_diff+15 */
|
||||
exc_diffQ[i] = round_fx(L_shl(L32,tmp_exp)); /*Q_exc */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*========================================================================*/
|
||||
/* FUNCTION : Ener_per_band_comp_fx() */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* PURPOSE : Compute the energy per band in log domain for quantization */
|
||||
/* purposes. */
|
||||
/* Loops are decomposed to accomodate the PVQ quantization */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16*) edct_table_128_fx : edct table Q15 */
|
||||
/* _ (Word16*) Q_exc_diff : input format of exc_diff */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16[]) y_gain4 : Energy per band to quantize Q12 */
|
||||
/* _ (Word32*) etmp14 : Energy band 14 Q_exc_diff*2+1 */
|
||||
/* _ (Word32*) etmp15 : Energy band 15 Q_exc_diff*2+1 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*========================================================================*/
|
||||
static Word16 Comp_band_log_ener( /* o : Band gain Q12 */
|
||||
const Word16 *pt_fx, /* i : Dct input Q_sc */
|
||||
const Word16 Len, /* i : Lenght en energy accumulation */
|
||||
const Word16 Q_sc, /* i : scaling of input */
|
||||
const Word16 E_sc /* i : Additional scaling factor for energy */
|
||||
)
|
||||
{
|
||||
Word32 L_tmp;
|
||||
Word16 e_tmp, f_tmp, tmp16, ener_exp;
|
||||
|
||||
/*for(i = 0; i < 8; i++){etmp += (*pt * *pt);pt++;}*/
|
||||
L_tmp = Calc_Energy_Autoscaled(pt_fx, Q_sc, Len, &ener_exp);
|
||||
|
||||
/*y_gain4[j] = (float)log10(sqrt(etmp<<E_sc));*/
|
||||
e_tmp = norm_l(L_tmp);
|
||||
f_tmp = Log2_norm_lc(L_shl(L_tmp, e_tmp));
|
||||
e_tmp = sub(sub(add(30,E_sc),e_tmp),ener_exp);
|
||||
L_tmp = Mpy_32_16(e_tmp, f_tmp, 19728); /* Q16 */ /*log10(2) in Q17 */
|
||||
tmp16 = round_fx(L_shl(L_tmp, 12-2)); /* Q12 -1 is to compensate Q17 */
|
||||
return tmp16;
|
||||
}
|
||||
|
||||
void Ener_per_band_comp_fx(
|
||||
const Word16 exc_diff_fx[], /* i : target signal Q_exc_diff */
|
||||
Word16 y_gain4_fx[], /* o : Energy per band to quantize Q12 */
|
||||
const Word16 Q_exc, /* i : frame length */
|
||||
const Word16 Mband, /* i : Max band */
|
||||
const Word16 Eflag /* i : flag of highest band */
|
||||
)
|
||||
{
|
||||
const Word16 *pt_fx;
|
||||
Word16 j;
|
||||
|
||||
pt_fx = exc_diff_fx;
|
||||
FOR(j = 0; j < 2; j++)
|
||||
{
|
||||
y_gain4_fx[j] = Comp_band_log_ener(pt_fx, 8, Q_exc, 1);
|
||||
move16();
|
||||
pt_fx += 8;
|
||||
}
|
||||
|
||||
FOR(j = 1; j < Mband-2; j++)
|
||||
{
|
||||
y_gain4_fx[j+1] = Comp_band_log_ener(pt_fx, 16, Q_exc, 0);
|
||||
move16();
|
||||
pt_fx += 16;
|
||||
}
|
||||
|
||||
IF( sub(Eflag,1) == 0 )
|
||||
{
|
||||
y_gain4_fx[j+1] = Comp_band_log_ener(pt_fx, 32, Q_exc, -1);
|
||||
move16();
|
||||
pt_fx += 32;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* gsc_gainQ()
|
||||
*
|
||||
* Quantization of the energy per band
|
||||
*-------------------------------------------------------------------*/
|
||||
static void GSC_gain_adj(
|
||||
const Word16 coder_type, /* i : Coder type */
|
||||
const Word32 core_brate, /* i : Bit rate */
|
||||
const Word16 mean_g, /* i : Average gain Q12 */
|
||||
Word16 *old_y_gain, /* i/o: Previous frame dequantized vector */
|
||||
const Word16 *y_gain_tmp, /* i : Dequantized gains */
|
||||
Word16 *y_gainQ /* i/o: Output gains Q12 */
|
||||
)
|
||||
{
|
||||
/* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
|
||||
Word16 Gain_off, i;
|
||||
|
||||
IF( sub(coder_type,INACTIVE) != 0 )
|
||||
{
|
||||
FOR( i = 0; i < MBANDS_GN; i++ )
|
||||
{
|
||||
old_y_gain[i] = y_gain_tmp[i];
|
||||
move16();
|
||||
y_gainQ[i] = add(y_gain_tmp[i], mean_g);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Gain_off = 0;
|
||||
move16();
|
||||
IF(L_sub(core_brate,ACELP_7k20) <= 0 )
|
||||
{
|
||||
Gain_off = 32767;
|
||||
move16(); /* 8 -> Q12 */
|
||||
}
|
||||
ELSE IF (L_sub(core_brate,ACELP_8k00) <= 0)
|
||||
{
|
||||
Gain_off = 27034;
|
||||
move16(); /* 6.6f -> Q12 */
|
||||
}
|
||||
ELSE IF (L_sub(core_brate,ACELP_9k60) <= 0)
|
||||
{
|
||||
Gain_off = 19661;
|
||||
move16(); /*4.8f-> Q12 */
|
||||
}
|
||||
ELSE IF (L_sub(core_brate,ACELP_11k60) <= 0)
|
||||
{
|
||||
Gain_off = 14336;
|
||||
move16(); /* 3.5f -> Q12 */
|
||||
}
|
||||
ELSE IF (L_sub(core_brate,ACELP_13k20) <= 0)
|
||||
{
|
||||
Gain_off = 12288;
|
||||
move16(); /* 3.0f -> Q12 dB */
|
||||
}
|
||||
|
||||
/*mimic ACELP decay of energy for low rates*/
|
||||
FOR( i = 0; i < MBANDS_GN; i++ )
|
||||
{
|
||||
old_y_gain[i] = y_gain_tmp[i];
|
||||
move16();
|
||||
/*y_gainQ[i] = y_gain_tmp[i]+mean_4g[0]-(i*(Gain_off/20.f)/((float) Mbands_gn));*/
|
||||
y_gainQ[i] = add(y_gain_tmp[i], sub(mean_g, i_mult2(i, mult_r(Gain_off, 102))));
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*==========================================================================*/
|
||||
/* FUNCTION : Word16 gsc_gaindec_fx () */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* PURPOSE : Generic signal frequency band decoding and application */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16) pvq_bits_fx : core used Q0 */
|
||||
/* _ (Word16) coder_type_fx : coding type Q0 */
|
||||
/* _ (Word16) core_fx : core used Q0 */
|
||||
/* _ (Word16) bwidth_fx : input signal bandwidth Q0 */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16[]) y_gainQ_fx : quantized gain per band */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16[]) old_y_gain_fx : AR gain quantizer for low rate */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ (Word16) : average frequency gain */
|
||||
/*==========================================================================*/
|
||||
|
||||
Word16 gsc_gaindec_fx( /* o : average frequency gain */
|
||||
Decoder_State_fx *st_fx, /* i/o: decoder state structure */
|
||||
Word16 y_gainQ_fx[], /* o : quantized gain per band */
|
||||
const Word32 core_brate_fx, /* i : core used */
|
||||
Word16 old_y_gain_fx[], /* i/o: AR gain quantizer for low rate */
|
||||
const Word16 coder_type_fx, /* i : coding type */
|
||||
const Word16 bwidth_fx /* i : input signal bandwidth */
|
||||
)
|
||||
{
|
||||
Word16 idx_g_fx, i;
|
||||
Word16 mean_4g_fx;
|
||||
Word16 y_gain_tmp3_fx[MBANDS_GN];
|
||||
|
||||
test();
|
||||
test();
|
||||
IF( (sub(coder_type_fx,AUDIO) == 0 || sub(coder_type_fx,INACTIVE) == 0) && sub(bwidth_fx,NB) == 0 )
|
||||
{
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
|
||||
VDQ_vec_fx(&mean_4g_fx, Gain_meanNB_fx, Gain_mean_dicNB_fx, idx_g_fx, 1 );
|
||||
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
|
||||
move16();
|
||||
VDQ_vec_fx(y_gainQ_fx, Mean_dic_NB_fx, Gain_dic1_NB_fx, idx_g_fx, 3 );
|
||||
|
||||
IF(L_sub(core_brate_fx,ACELP_9k60) < 0)
|
||||
{
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
|
||||
VDQ_vec_fx(y_gainQ_fx+3, Mean_dic_NB_fx+3, Gain_dic2_NB_fx, idx_g_fx, 3 );
|
||||
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
|
||||
VDQ_vec_fx(y_gainQ_fx+6, Mean_dic_NB_fx+6, Gain_dic3_NB_fx, idx_g_fx, 4 );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
|
||||
VDQ_vec_fx(y_gainQ_fx+3, Mean_dic_NB_fx+3, Gain_dic2_NBHR_fx, idx_g_fx, 3 );
|
||||
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 7 );
|
||||
VDQ_vec_fx(y_gainQ_fx+6, Mean_dic_NB_fx+6, Gain_dic3_NBHR_fx, idx_g_fx, 4 );
|
||||
}
|
||||
test();
|
||||
IF( L_sub(core_brate_fx,ACELP_9k60) <= 0 && sub(coder_type_fx,INACTIVE) == 0 )
|
||||
{
|
||||
/* Some energy is needed in high band for stat_noise_uv_enc
|
||||
to be functional in inactive speech */
|
||||
y_gainQ_fx[10] = mean_fx(y_gainQ_fx+6, 3);
|
||||
move16();
|
||||
y_gainQ_fx[11] = mean_fx(y_gainQ_fx+7, 3);
|
||||
move16();
|
||||
y_gainQ_fx[12] = mean_fx(y_gainQ_fx+8, 3);
|
||||
move16();
|
||||
y_gainQ_fx[13] = mean_fx(y_gainQ_fx+9, 3);
|
||||
move16();
|
||||
y_gainQ_fx[14] = mean_fx(y_gainQ_fx+10, 3);
|
||||
move16();
|
||||
y_gainQ_fx[15] = mean_fx(y_gainQ_fx+11, 3);
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
set16_fx( y_gainQ_fx + 10, 0, MBANDS_GN - 10 );
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
|
||||
|
||||
VDQ_vec_fx(&mean_4g_fx, mean_m_fx, mean_gain_dic_fx, idx_g_fx, 1 );
|
||||
|
||||
IF(L_sub(core_brate_fx,ACELP_9k60) <= 0)
|
||||
{
|
||||
/*--------------------------------------------------------------------------------------*
|
||||
* UQ of the first 8 bands and half of the last 8 bands
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
|
||||
VDQ_vec_fx(y_gainQ_fx, YGain_mean_LR_fx, YGain_dic1_LR_fx, idx_g_fx, 3 );
|
||||
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
|
||||
VDQ_vec_fx(y_gainQ_fx+3, YGain_mean_LR_fx+3, YGain_dic2_LR_fx, idx_g_fx, 4 );
|
||||
|
||||
/*----------------------------------------------------------------------*
|
||||
* Interpolation of the last 4 Q bands to create bands 8-16
|
||||
* And scaling
|
||||
*----------------------------------------------------------------------*/
|
||||
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
|
||||
|
||||
VDQ_vec_fx(y_gainQ_fx+7, YGain_mean_LR_fx+7, YGain_dic3_LR_fx, idx_g_fx, 5 );
|
||||
|
||||
Copy(y_gainQ_fx+8, y_gain_tmp3_fx, 4);
|
||||
set16_fx(y_gainQ_fx+12, 0, 4);
|
||||
|
||||
fft_rel_fx(y_gainQ_fx+8, 4, 2);
|
||||
|
||||
y_gainQ_fx[15] = y_gainQ_fx[11];
|
||||
move16();
|
||||
y_gainQ_fx[11] = 0;
|
||||
move16();
|
||||
ifft_rel_fx(y_gainQ_fx+8, 8, 3);
|
||||
FOR(i = 8; i < 16; i++)
|
||||
{
|
||||
/*y_gainQ_fx[i] *= 1.41f;*/
|
||||
y_gainQ_fx[i] = round_fx(L_shl(L_mult(y_gainQ_fx[i] , 23101),1));/*Q12 */
|
||||
}
|
||||
/*----------------------------------------------------------------------*
|
||||
* Copy the true Q values in the specific bands
|
||||
*----------------------------------------------------------------------*/
|
||||
y_gainQ_fx[8] = y_gain_tmp3_fx[0];
|
||||
move16();
|
||||
y_gainQ_fx[10]= y_gain_tmp3_fx[1];
|
||||
move16();
|
||||
y_gainQ_fx[12]= y_gain_tmp3_fx[2];
|
||||
move16();
|
||||
y_gainQ_fx[14]= y_gain_tmp3_fx[3];
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
|
||||
VDQ_vec_fx(y_gainQ_fx, YG_mean16_fx, YG_dicMR_1_fx, idx_g_fx, 4 );
|
||||
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
|
||||
VDQ_vec_fx(y_gainQ_fx+4, YG_mean16_fx+4, YG_dicMR_2_fx, idx_g_fx, 4 );
|
||||
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
|
||||
VDQ_vec_fx(y_gainQ_fx+8, YG_mean16_fx+8, YG_dicMR_3_fx, idx_g_fx, 4 );
|
||||
|
||||
idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
|
||||
VDQ_vec_fx(y_gainQ_fx+12, YG_mean16_fx+12, YG_dicMR_4_fx, idx_g_fx, 4 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
|
||||
GSC_gain_adj(coder_type_fx, core_brate_fx, mean_4g_fx, old_y_gain_fx, y_gainQ_fx, y_gainQ_fx);
|
||||
|
||||
return mean_4g_fx;
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* gsc_gainQ()
|
||||
*
|
||||
* Quantization of the energy per band
|
||||
*-------------------------------------------------------------------*/
|
||||
Word16 gsc_gainQ_fx( /*Q12*/
|
||||
Encoder_State_fx *st_fx, /* i/o: decoder state structure */
|
||||
const Word16 y_gain4[], /* i : Energy per band Q12 */
|
||||
Word16 y_gainQ[], /* o : quantized energy per band Q12 */
|
||||
const Word32 core_brate, /* i : Core rate */
|
||||
const Word16 coder_type, /* i : coding type */
|
||||
const Word16 bwidth /* i : input signal bandwidth */
|
||||
)
|
||||
{
|
||||
Word16 y_gain_tmp[MBANDS_GN], y_gain_tmp2[MBANDS_GN];
|
||||
Word16 i, idx_g = 0;
|
||||
Word16 mean_4g[1] = {0}, tmp16,tmp1, tmp2;
|
||||
Word16 Mbands_gn = MBANDS_GN;
|
||||
Word16 y_gain_tmp3[MBANDS_GN];
|
||||
Word16 cnt;
|
||||
Word32 L_tmp;
|
||||
|
||||
mean_4g[0] = 0;
|
||||
|
||||
test();
|
||||
test();
|
||||
IF( (sub(coder_type,AUDIO) == 0 || sub(coder_type,INACTIVE) == 0) && sub(bwidth,NB) == 0 )
|
||||
{
|
||||
|
||||
/*ftmp1 = mean(y_gain4, 10)-0.6f;*/
|
||||
L_tmp = L_deposit_l(0);
|
||||
FOR(cnt = 0 ; cnt < 10 ; cnt++)
|
||||
{
|
||||
L_tmp = L_mac(L_tmp,y_gain4[cnt], 3277);
|
||||
}
|
||||
tmp16 = sub(round_fx(L_tmp), 4915);
|
||||
|
||||
FOR(i = 0; i < Mbands_gn; i++)
|
||||
{
|
||||
y_gain_tmp2[i] = y_gain4[i];
|
||||
move16();
|
||||
/*if(y_gain4[i] < ftmp1-0.6f)*/
|
||||
y_gain_tmp2[i] = s_max(y_gain_tmp2[i], tmp16);
|
||||
move16();
|
||||
}
|
||||
|
||||
L_tmp = L_deposit_l(0);
|
||||
FOR(i = 0; i < 10; i++)
|
||||
{
|
||||
L_tmp = L_mac(L_tmp,y_gain_tmp2[i], 3277);
|
||||
}
|
||||
|
||||
/* Quantized mean gain without clipping */
|
||||
mean_4g[0] = round_fx(L_tmp);
|
||||
idx_g = vquant_fx(mean_4g, Gain_meanNB_fx, mean_4g, Gain_mean_dicNB_fx, 1, 64);
|
||||
push_indice_fx( st_fx, IND_MEAN_GAIN2, idx_g, 6 );
|
||||
|
||||
FOR(i = 0; i < Mbands_gn; i++)
|
||||
{
|
||||
y_gain_tmp[i] = sub(y_gain_tmp2[i],mean_4g[0]);
|
||||
move16();
|
||||
}
|
||||
/*if(y_gain_tmp[9] < -0.3f){y_gain_tmp[9] = -0.3f;}*/
|
||||
y_gain_tmp[9] = s_max(y_gain_tmp[9], -1229);
|
||||
move16();
|
||||
set16_fx(y_gain_tmp+10, 0, MBANDS_GN-10);
|
||||
idx_g = vquant_fx(y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64);
|
||||
push_indice_fx( st_fx, IND_Y_GAIN_TMP, idx_g, 6 );
|
||||
|
||||
IF(L_sub(core_brate,ACELP_9k60) < 0)
|
||||
{
|
||||
idx_g = vquant_fx(y_gain_tmp+3, Mean_dic_NB_fx+3, y_gain_tmp+3, Gain_dic2_NB_fx, 3, 32);
|
||||
push_indice_fx( st_fx, IND_Y_GAIN_TMP, idx_g, 5 );
|
||||
idx_g = vquant_fx(y_gain_tmp+6, Mean_dic_NB_fx+6, y_gain_tmp+6, Gain_dic3_NB_fx, 4, 16);
|
||||
push_indice_fx( st_fx, IND_Y_GAIN_TMP, idx_g, 4 );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
idx_g = vquant_fx(y_gain_tmp+3, Mean_dic_NB_fx+3, y_gain_tmp+3, Gain_dic2_NBHR_fx, 3, 64);
|
||||
push_indice_fx( st_fx, IND_Y_GAIN_TMP, idx_g, 6 );
|
||||
idx_g = vquant_fx(y_gain_tmp+6, Mean_dic_NB_fx+6, y_gain_tmp+6, Gain_dic3_NBHR_fx, 4, 128);
|
||||
push_indice_fx( st_fx, IND_Y_GAIN_TMP, idx_g, 7 );
|
||||
}/*add end */
|
||||
|
||||
test();
|
||||
IF( L_sub(core_brate,ACELP_9k60) <= 0 && sub(coder_type,INACTIVE) == 0 )
|
||||
{
|
||||
/* Some energy is needed in high band for stat_noise_uv_enc
|
||||
to be functional in inactive speech */
|
||||
y_gain_tmp[10] = round_fx(L_mac(L_mac(L_mult(y_gain_tmp[6],8192),y_gain_tmp[7],8192),y_gain_tmp[8],8192));
|
||||
y_gain_tmp[11] = round_fx(L_mac(L_mac(L_mult(y_gain_tmp[7],8192),y_gain_tmp[8],8192),y_gain_tmp[9],8192));
|
||||
|
||||
y_gain_tmp[12] = round_fx(L_mac(L_mac(L_mult(y_gain_tmp[8],8192),y_gain_tmp[9],8192),y_gain_tmp[10],8192));
|
||||
y_gain_tmp[13] = round_fx(L_mac(L_mac(L_mult(y_gain_tmp[9],8192),y_gain_tmp[10],8192),y_gain_tmp[11],8192));
|
||||
y_gain_tmp[14] = round_fx(L_mac(L_mac(L_mult(y_gain_tmp[10],8192),y_gain_tmp[11],8192),y_gain_tmp[12],8192));
|
||||
y_gain_tmp[15] = round_fx(L_mac(L_mac(L_mult(y_gain_tmp[11],8192),y_gain_tmp[12],8192),y_gain_tmp[13],8192));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/*ftmp1 = mean(y_gain4, 16);*/
|
||||
|
||||
L_tmp =0;
|
||||
FOR(cnt = 0 ; cnt < 16 ; cnt++)
|
||||
{
|
||||
L_tmp = L_mac(L_tmp,y_gain4[cnt], 2048);
|
||||
}
|
||||
tmp16 = round_fx(L_tmp);
|
||||
|
||||
tmp1 = sub(tmp16,4915);
|
||||
tmp2 = add(tmp16,4915);
|
||||
L_tmp =0;
|
||||
FOR(i = 0; i < 16; i++)
|
||||
{
|
||||
y_gain_tmp2[i] = y_gain4[i];
|
||||
move16();
|
||||
/*if(y_gain4[i] < ftmp1-0.6f)*/
|
||||
y_gain_tmp2[i] = s_max(y_gain_tmp2[i], tmp1);
|
||||
move16();
|
||||
/*else if(y_gain4[i] > ftmp1+0.6f)*/
|
||||
y_gain_tmp2[i] = s_min(y_gain_tmp2[i], tmp2);
|
||||
move16();
|
||||
L_tmp = L_mac(L_tmp,y_gain_tmp2[i], 2048);
|
||||
}
|
||||
FOR(; i < Mbands_gn; i++)
|
||||
{
|
||||
y_gain_tmp2[i] = y_gain4[i];
|
||||
/*if(y_gain4[i] < ftmp1-0.6f)*/
|
||||
y_gain_tmp2[i] = s_max(y_gain_tmp2[i], tmp1); /* Just the last move is needed, because s_max and s_min could be done in 1 line*/
|
||||
/*else if(y_gain4[i] > ftmp1+0.6f)*/
|
||||
y_gain_tmp2[i] = s_min(y_gain_tmp2[i], tmp2);
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Quantized mean gain without clipping */
|
||||
mean_4g[0] = round_fx(L_tmp);
|
||||
|
||||
|
||||
/*idx_g = (short)vquant(mean_4g, mean_m, mean_4g, mean_gain_dic, 1, 64);*/
|
||||
idx_g = vquant_fx(mean_4g, mean_m_fx, mean_4g, mean_gain_dic_fx, 1, 64);
|
||||
push_indice_fx( st_fx, IND_MEAN_GAIN2, idx_g, 6 );
|
||||
|
||||
FOR(i = 0; i < Mbands_gn; i++)
|
||||
{
|
||||
y_gain_tmp[i] = sub(y_gain_tmp2[i],mean_4g[0]);
|
||||
move16();
|
||||
}
|
||||
|
||||
IF( L_sub(core_brate,ACELP_9k60) < 0 )
|
||||
{
|
||||
/*mvr2r(y_gain_tmp, y_gain_tmp2, 8); */
|
||||
Copy(y_gain_tmp, y_gain_tmp2, 8);
|
||||
|
||||
y_gain_tmp2[8] = y_gain_tmp[8];
|
||||
move16();
|
||||
y_gain_tmp2[9] = y_gain_tmp[10];
|
||||
move16();
|
||||
y_gain_tmp2[10] =y_gain_tmp[12];
|
||||
move16();
|
||||
y_gain_tmp2[11] =y_gain_tmp[14];
|
||||
move16();
|
||||
|
||||
idx_g = 0;
|
||||
|
||||
/*idx_g = (short)vquant(y_gain_tmp2, YGain_mean_LR, y_gain_tmp2, YGain_dic1_LR, 3, 32);*/
|
||||
idx_g = vquant_fx(y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 );
|
||||
push_indice_fx( st_fx, IND_Y_GAIN_TMP, idx_g, 5 );
|
||||
/*idx_g = (short)vquant(y_gain_tmp2+3, YGain_mean_LR+3, y_gain_tmp2+3, YGain_dic2_LR, 4, 32);*/
|
||||
idx_g = vquant_fx(y_gain_tmp2+3, YGain_mean_LR_fx+3, y_gain_tmp2+3, YGain_dic2_LR_fx, 4, 32 );
|
||||
push_indice_fx( st_fx, IND_Y_GAIN_TMP, idx_g, 5 );
|
||||
/*idx_g = (short)vquant(y_gain_tmp2+7, YGain_mean_LR+7, y_gain_tmp2+7, YGain_dic3_LR, 5, 32);*/
|
||||
idx_g = vquant_fx(y_gain_tmp2+7, YGain_mean_LR_fx+7, y_gain_tmp2+7, YGain_dic3_LR_fx, 5, 32);
|
||||
push_indice_fx( st_fx, IND_Y_GAIN_TMP, idx_g, 5 );
|
||||
/*set_f(y_gain_tmp2+12, 0, MBANDS_GN-12);*/
|
||||
set16_fx(y_gain_tmp2+12, 0, MBANDS_GN-12);
|
||||
|
||||
/* Update to quantized vector */
|
||||
Copy(y_gain_tmp2, y_gain_tmp, 8);
|
||||
|
||||
Copy(y_gain_tmp2+8, y_gain_tmp3, 4);
|
||||
set16_fx(y_gain_tmp+8, 0,8);
|
||||
fft_rel_fx(y_gain_tmp2+8, 4, 2);
|
||||
|
||||
Copy(y_gain_tmp2+8, y_gain_tmp+8, 3);
|
||||
y_gain_tmp[15] = y_gain_tmp2[11];
|
||||
ifft_rel_fx(y_gain_tmp+8, 8, 3);
|
||||
|
||||
FOR(i = 8; i < 16; i++)
|
||||
{
|
||||
/*y_gain_tmp[i] *= 1.41f;*/
|
||||
y_gain_tmp[i] = shl( mult_r(y_gain_tmp[i] , 23101),1) ;
|
||||
move16();
|
||||
}
|
||||
|
||||
y_gain_tmp[8] = y_gain_tmp3[0];
|
||||
move16();
|
||||
y_gain_tmp[10]= y_gain_tmp3[1];
|
||||
move16();
|
||||
y_gain_tmp[12]= y_gain_tmp3[2];
|
||||
move16();
|
||||
y_gain_tmp[14]= y_gain_tmp3[3];
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
idx_g = vquant_fx(y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64);
|
||||
push_indice_fx( st_fx, IND_Y_GAIN_TMP, idx_g, 6 );
|
||||
idx_g = vquant_fx(y_gain_tmp+4, YG_mean16_fx+4, y_gain_tmp+4, YG_dicMR_2_fx, 4, 32);
|
||||
push_indice_fx( st_fx, IND_Y_GAIN_TMP, idx_g, 5 );
|
||||
idx_g = vquant_fx(y_gain_tmp+8, YG_mean16_fx+8, y_gain_tmp+8, YG_dicMR_3_fx, 4, 32);
|
||||
push_indice_fx( st_fx, IND_Y_GAIN_TMP, idx_g, 5 );
|
||||
idx_g = vquant_fx(y_gain_tmp+12, YG_mean16_fx+12, y_gain_tmp+12, YG_dicMR_4_fx, 4, 16);
|
||||
push_indice_fx( st_fx, IND_Y_GAIN_TMP, idx_g, 4 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
|
||||
GSC_gain_adj(coder_type, core_brate, mean_4g[0], y_gain_tmp2 /* dummy buffer */, y_gain_tmp, y_gainQ);
|
||||
|
||||
return mean_4g[0]; /*Q12*/
|
||||
}
|
||||
/*-------------------------------------------------------------------*
|
||||
* VDQ_vec()
|
||||
*
|
||||
* Return the dequantized vector of index
|
||||
*-------------------------------------------------------------------*/
|
||||
static Word16 VDQ_vec_fx(
|
||||
Word16 *Qvec_out_fx, /* o: Quanitzed vector */
|
||||
const Word16 *mean_dic_fx, /* i: average codebook */
|
||||
const Word16 *dic_fx, /* i: codebook */
|
||||
const Word16 index_fx, /* i: index of codebook*/
|
||||
const Word16 vec_en_fx /* i: vector length */
|
||||
)
|
||||
{
|
||||
Word16 i, j;
|
||||
|
||||
/*j = shr_r(extract_l(L_mult(index_fx,vec_en_fx)),1);*/
|
||||
j = i_mult2(index_fx,vec_en_fx);
|
||||
FOR ( i = 0; i < vec_en_fx; i++)
|
||||
{
|
||||
Qvec_out_fx[i] = dic_fx[j++];
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR(i = 0; i < vec_en_fx; i++)
|
||||
{
|
||||
Qvec_out_fx[i] = add(Qvec_out_fx[i],mean_dic_fx[i]);
|
||||
move16();
|
||||
}
|
||||
|
||||
return index_fx;
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
#define ALPHA0_FX 13107
|
||||
#define BETA0_FX (32768-ALPHA0_FX)
|
||||
|
||||
/*========================================================================*/
|
||||
/* FUNCTION : Inac_swtch_ematch_fx() */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* PURPOSE : Apply energy matching when swithcing to INACTIVE frame coded */
|
||||
/* by the GSC technology */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16) coder_type : Coding mode */
|
||||
/* _ (Word16) L_frame : Frame lenght */
|
||||
/* _ (Word32) core_brate : core bitrate */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16[]) exc2 : CELP/GSC excitation buffer Q_exc */
|
||||
/* _ (Word16[]) lt_ener_per_band : Long term energy per band Q12 */
|
||||
/* _ (Word16*) Q_exc : input and output format of exc2 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*========================================================================*/
|
||||
void Inac_swtch_ematch_fx(
|
||||
Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/
|
||||
Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */
|
||||
Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */
|
||||
const Word16 coder_type, /* i : Coding mode */
|
||||
const Word16 L_frame, /* i : Frame lenght */
|
||||
const Word32 core_brate, /* i : Core bit rate */
|
||||
const Word16 Q_exc /* i : input and output format of exc2 */
|
||||
,const Word16 bfi /* i : frame lost indicator */
|
||||
,const Word16 last_core, /* i : Last core used */
|
||||
const Word16 last_codec_mode /* i : Last codec mode */
|
||||
)
|
||||
{
|
||||
Word16 Ener_per_bd[MBANDS_GN];
|
||||
Word16 ftmp;
|
||||
Word16 *pt_exc;
|
||||
Word16 j, i;
|
||||
|
||||
Word16 exp,frac;
|
||||
Word32 L_tmp;
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* average energy per band
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF(sub(coder_type,AUDIO) == 0 && bfi == 0)
|
||||
{
|
||||
Ener_per_band_comp_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1);
|
||||
|
||||
/* reset long-term energy per band */
|
||||
FOR(i = 0; i < MBANDS_GN; i++)
|
||||
{
|
||||
lt_ener_per_band[i] = Ener_per_bd[i];
|
||||
move16();
|
||||
}
|
||||
|
||||
}
|
||||
ELSE IF( sub(coder_type,VOICED) == 0 || sub(coder_type,GENERIC) == 0 || sub(coder_type,TRANSITION) == 0 || sub(last_core,ACELP_CORE) != 0 || sub(last_codec_mode,MODE1) != 0 )
|
||||
{
|
||||
/* Find spectrum and energy per band for GC and VC frames */
|
||||
edct_16fx( exc2, dct_exc_tmp, L_frame, 5 );
|
||||
|
||||
Ener_per_band_comp_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1);
|
||||
|
||||
/* reset long-term energy per band */
|
||||
FOR(i = 0; i < MBANDS_GN; i++)
|
||||
{
|
||||
lt_ener_per_band[i] = Ener_per_bd[i];
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE IF( sub(coder_type,INACTIVE) == 0 && L_sub(core_brate,ACELP_24k40) <= 0)
|
||||
{
|
||||
/* Find spectrum and energy per band for inactive frames */
|
||||
edct_16fx( exc2, dct_exc_tmp, L_frame, 5 );
|
||||
Ener_per_band_comp_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1 );
|
||||
|
||||
/* More agressive smoothing in the first 50 frames */
|
||||
pt_exc = dct_exc_tmp;
|
||||
move16();
|
||||
FOR(i = 0; i < MBANDS_GN; i++)
|
||||
{
|
||||
/* Compute smoothing gain to apply with gain limitation */
|
||||
L_tmp = L_mult(ALPHA0_FX,lt_ener_per_band[i]); /*Q(15+12+1)=Q(28) */
|
||||
L_tmp = L_mac(L_tmp,BETA0_FX,Ener_per_bd[i]); /*Q28 */
|
||||
lt_ener_per_band[i] = round_fx(L_tmp); /*Q12 */
|
||||
|
||||
ftmp = sub(lt_ener_per_band[i],Ener_per_bd[i]); /*Q12 */
|
||||
|
||||
/* ftmp = (float)pow(10, ftmp);= pow(2,3.321928*ftmp);*/
|
||||
|
||||
L_tmp = L_mult(27213,ftmp); /*Q(13+12+1)=Q26 ; 27213=3.321928 in Q13 */
|
||||
L_tmp = L_shr(L_tmp, 10); /* From Q26 to Q16 */
|
||||
frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of ftmp */
|
||||
ftmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */
|
||||
/* output of Pow2() will be: */
|
||||
/* 16384 < Pow2() <= 32767 */
|
||||
|
||||
exp = sub(exp,14);
|
||||
IF( sub(i,2) < 0 )
|
||||
{
|
||||
FOR (j = 0; j < 8; j ++)
|
||||
{
|
||||
L_tmp = L_mult(*pt_exc,ftmp); /* Q_exc*Q0 -> Q(Q_exc+1) */
|
||||
L_tmp = L_shl(L_tmp, add(exp,15)); /* Q(Q_exc+1) -> Q(16+Q_exc)*/
|
||||
*pt_exc = round_fx(L_tmp);
|
||||
pt_exc++;
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
FOR (j = 0; j < 16; j ++)
|
||||
{
|
||||
L_tmp = L_mult(*pt_exc,ftmp); /* Q_exc*Q0 -> Q(Q_exc+1) */
|
||||
L_tmp = L_shl(L_tmp, add(exp,15)); /* Q(Q_exc+1) -> Q(16+Q_exc)*/
|
||||
*pt_exc = round_fx(L_tmp); /*Q_exc*/
|
||||
pt_exc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Going back to time */
|
||||
edct_16fx( dct_exc_tmp, exc2, L_frame, 5 );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+921
@@ -0,0 +1,921 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* gs_noisf()
|
||||
*
|
||||
* Noise fill-in function
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
static void gs_noisf_fx(
|
||||
const Word16 Start_BIN, /* i : First bin for noise fill */
|
||||
const Word16 NB_Qbins, /* i : Number of bin per band */
|
||||
const Word16 Noise_fac, /* i : Noise level Q15 */
|
||||
const Word16 *y_norm, /* i : Quantized pulses Qn */
|
||||
Word16 *exc_diffQ, /* o : Quantized pulses with noise added Qn */
|
||||
Word16 *seed_tcx, /* i : Random generator seed */
|
||||
const Word16 coder_type, /* i : coder type */
|
||||
Word16 qNoise_fac
|
||||
)
|
||||
{
|
||||
Word32 ftmp;
|
||||
Word16 i, k;
|
||||
Word16 NB_zer;
|
||||
Word32 const_1=1;
|
||||
Word16 tmp;
|
||||
|
||||
NB_zer = shr(NB_Qbins,1);
|
||||
|
||||
const_1 = L_shl(const_1, add(qNoise_fac, qNoise_fac));
|
||||
if( sub(coder_type,INACTIVE) == 0 )
|
||||
{
|
||||
NB_zer = 2;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*----------------------------------------------*
|
||||
* noise fill-in on unquantized subvector *
|
||||
* injected only from 1066Hz to 6400Hz. *
|
||||
*----------------------------------------------*/
|
||||
|
||||
FOR( k=Start_BIN; k<NB_Qbins + Start_BIN; k+=NB_zer )
|
||||
{
|
||||
ftmp = L_deposit_l(0);
|
||||
FOR(i=k; i<k+NB_zer; i++)
|
||||
{
|
||||
exc_diffQ[i] = y_norm[i];
|
||||
move16();
|
||||
ftmp = L_mac0(ftmp, exc_diffQ[i], exc_diffQ[i]);
|
||||
}
|
||||
|
||||
IF (L_sub(L_shl(ftmp, 1),const_1) < 0)
|
||||
{
|
||||
FOR(i=k; i<k+NB_zer; i++)
|
||||
{
|
||||
/*exc_diffQ[i] += Noise_fac*((float)own_random(seed_tcx)/32768.0f);*/
|
||||
tmp = mult(Noise_fac, Random(seed_tcx));/*Q15 */
|
||||
tmp = shr(tmp, sub(15,qNoise_fac));/*qNoise_fac */
|
||||
exc_diffQ[i] = add(exc_diffQ[i], tmp);
|
||||
move16();/*Q */
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* This is added only to keep the seed in sync between different compilers */
|
||||
FOR(i=k; i<k+NB_zer; i++)
|
||||
{
|
||||
Random(seed_tcx);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* EstimateNoiseLevel_inner()
|
||||
*
|
||||
* Estimate noise level from the power spectrum
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
static void EstimateNoiseLevel_inner_fx(
|
||||
Word16 *noisepb, /* o : Noise per band Q15 */
|
||||
const long bitrate, /* i : Bitrate of the codec */
|
||||
const Word16 i_band, /* i : First band to compute the noise */
|
||||
const Word16 Mbands_gn /* i : number of bands */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word16 noise_offset;
|
||||
|
||||
noise_offset = 8192;
|
||||
move16();
|
||||
/*0.25f * 32768 */
|
||||
IF( bitrate > ACELP_24k40 )
|
||||
{
|
||||
noise_offset = 6554;
|
||||
move16(); /*.2f * 32768 */
|
||||
}
|
||||
ELSE IF ( bitrate >= ACELP_22k60 )
|
||||
{
|
||||
noise_offset = 9830;
|
||||
move16();/*.3f * 32768 */
|
||||
}
|
||||
ELSE IF ( bitrate >= ACELP_9k60 )
|
||||
{
|
||||
noise_offset = 11469;
|
||||
move16(); /*0.35f * 32768 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
noise_offset = 13107;
|
||||
move16(); /*.4f * 32768 */
|
||||
}
|
||||
|
||||
set16_fx( noisepb + i_band, noise_offset, sub(Mbands_gn, i_band) );
|
||||
|
||||
FOR( i = i_band; i < 5; i++ )
|
||||
{
|
||||
noisepb[i] = s_min(noisepb[i], 6554);
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*==========================================================================*/
|
||||
/* FUNCTION : void EstimateNoiseLevel_fx() */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* PURPOSE : */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word32) bitrate : Bitrate of the codec Q0 */
|
||||
/* _ (Word16) Diff_len : number of bin before cut-off frequency */
|
||||
/* _ (Word16) Mbands_gn : number of bands Q0 */
|
||||
/* _ (Word16) coder_type : coder type Q0 */
|
||||
/* _ (Word16) noise_lev : pulses dynamic Q0 */
|
||||
/* _ (Word16) pit_band_idx : bin position of the cut-off frequency */
|
||||
/* _ (Word16*) freq_nsbin_per_band : bin per bands tables Q0 */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*) noisepb : Noise per band Q15 */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* None */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*==========================================================================*/
|
||||
static void EstimateNoiseLevel_fx(
|
||||
Word16 *noisepb, /* o : Noise per band */
|
||||
const Word32 bitrate, /* i : Bitrate of the codec */
|
||||
const Word16 Diff_len, /* i : number of bin before cut-off frequency */
|
||||
const Word16 Mbands_gn, /* i : number of bands */
|
||||
const Word16 coder_type, /* i : coder type */
|
||||
const Word16 noise_lev, /* i : pulses dynamic */
|
||||
const Word16 pit_band_idx, /* i : bin position of the cut-off frequency */
|
||||
Word16 last_bin, /* i : the last bin of bit allocation */
|
||||
Word16 bwidth
|
||||
)
|
||||
{
|
||||
Word16 i_band;
|
||||
|
||||
i_band = 0;
|
||||
move16();
|
||||
|
||||
IF( sub(Diff_len,L_FRAME) < 0)
|
||||
{
|
||||
EstimateNoiseLevel_inner_fx(noisepb, bitrate, i_band, MBANDS_GN);
|
||||
IF( coder_type != INACTIVE )
|
||||
{
|
||||
test();
|
||||
test();
|
||||
IF( (L_sub(bitrate,ACELP_8k00) == 0 && sub(last_bin,8) > 0) && sub(bwidth,NB) != 0)
|
||||
{
|
||||
FOR( ; Mbands_gn > i_band; i_band++)
|
||||
{
|
||||
noisepb[i_band] = add(noisepb[i_band],noisepb[i_band]);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
FOR( ; pit_band_idx > i_band; i_band++ )
|
||||
{
|
||||
noisepb[i_band] = mult_r(noisepb[i_band], 16384);
|
||||
move16();/* 1/2=0.5 in Q15 */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
test();
|
||||
IF ( (sub(coder_type,INACTIVE) == 0 || sub(noise_lev,NOISE_LEVEL_SP3) >= 0) )
|
||||
{
|
||||
FOR( i_band = 9; i_band < Mbands_gn; i_band++ )
|
||||
{
|
||||
noisepb[i_band] = add(noisepb[i_band], mult_r(noisepb[i_band], 4915));
|
||||
move16();/*noisepb[i_band]*1.15=noisepb[i_band] *(1 + 0.15) */
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*============================================================================*/
|
||||
/* FUNCTION : void Appy_NoiseFill_fx() */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* PURPOSE : */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16*) seed_tcx : Seed for noise Q0 */
|
||||
/* _ (Word16*) noisepb : Noise per band Q15 */
|
||||
/* _ (Word16) Diff_len : number of bin before cut-off frequency Q0 */
|
||||
/* _ (Word16) Mbands_gn : number of bands Q0 */
|
||||
/* _ (Word16) coder_type : pulses dynamic Q0 */
|
||||
/* _ (Word16*) freq_nsbin_per_band: bin per bands tables Q0 */
|
||||
/* _ (Word16) qexc_diffQ : Q format of exc_diffQ */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*) exc_diffQ : Noise per band qexc_diffQ */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* None */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*============================================================================*/
|
||||
static void Apply_NoiseFill_fx(
|
||||
Word16 *exc_diffQ, /* i/o: Noise per band qexc_diffQ */
|
||||
Word16 *seed_tcx, /* i : Seed for noise */
|
||||
const Word16 *noisepb, /* i : Noise per band Q15 */
|
||||
const Word16 Diff_len, /* i : number of bin before cut-off frequency */
|
||||
const Word16 Mbands_gn, /* i : number of bands */
|
||||
const Word16 coder_type, /* i : coder type */
|
||||
const Word16 *freq_nsbin_per_band, /* i : bin per bands tables */
|
||||
Word16 qexc_diffQ
|
||||
)
|
||||
{
|
||||
Word16 StartBin, NB_Qbins, i_band;
|
||||
StartBin = 0;
|
||||
move16();
|
||||
NB_Qbins = 0;
|
||||
move16();
|
||||
|
||||
FOR( i_band = 0; i_band < Mbands_gn; i_band++ )
|
||||
{
|
||||
StartBin += NB_Qbins;
|
||||
move16();
|
||||
NB_Qbins = freq_nsbin_per_band[i_band];
|
||||
move16();
|
||||
|
||||
IF( sub(Diff_len,L_FRAME) < 0 )
|
||||
{
|
||||
gs_noisf_fx( StartBin , NB_Qbins, noisepb[i_band], exc_diffQ, exc_diffQ, seed_tcx, coder_type, qexc_diffQ);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*==========================================================================*/
|
||||
/* FUNCTION :void freq_dnw_scaling_fx () */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* PURPOSE : */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16) cor_strong_limit : HF correlation Q0 */
|
||||
/* _ (Word16) coder_type : coder type Q0 */
|
||||
/* _ (Word16) noise_lev : Noise level Q0 */
|
||||
/* _ (Word32) core_brate : Core bitrate Q0 */
|
||||
/* _ (Word16) Qx : Q format of fy_norm */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16[]) fy_norm : Frequency quantized parameter Qx */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _None */
|
||||
/*==========================================================================*/
|
||||
void freq_dnw_scaling_fx(
|
||||
const Word16 cor_strong_limit, /* i : HF correlation */
|
||||
const Word16 coder_type, /* i : coder type */
|
||||
const Word16 noise_lev, /* i : Noise level */
|
||||
const Word32 core_brate, /* i : Core bitrate */
|
||||
Word16 fy_norm[], /* i/o: Frequency quantized parameter */
|
||||
Word16 Qx /* Q format of fy_norm*/
|
||||
)
|
||||
{
|
||||
Word16 sc_dyn;
|
||||
Word16 start_sc, i;
|
||||
|
||||
sc_dyn = 32767;
|
||||
move16(); /*Q15 */
|
||||
start_sc = L_FRAME;
|
||||
move16();
|
||||
test();
|
||||
IF( L_sub(core_brate,ACELP_8k00) <= 0 && sub(coder_type,INACTIVE) == 0 )
|
||||
{
|
||||
sc_dyn = mult_r(sc_dyn,4915); /*Q15 (0.15 in Q15) */
|
||||
start_sc = 64;
|
||||
move16();
|
||||
}
|
||||
ELSE IF ( sub(coder_type,INACTIVE) == 0 )
|
||||
{
|
||||
sc_dyn = mult_r(sc_dyn,8192); /*Q15 (0.25 in Q15) */
|
||||
start_sc = 80;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/*sc_dyn = (float)(NOISE_LEVEL_SP3 - noise_lev)/10.0f + 0.4f;*/
|
||||
sc_dyn = extract_l(L_mac(13107, sub(NOISE_LEVEL_SP3, noise_lev), 1638)); /*Q0*Q14x2+Q15 =Q15*/
|
||||
start_sc = add(112, shl(sub(NOISE_LEVEL_SP3, noise_lev), 4));
|
||||
if( sub(noise_lev,NOISE_LEVEL_SP0) == 0)
|
||||
{
|
||||
start_sc = L_FRAME;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
FOR(i = start_sc; i < L_FRAME; i++)
|
||||
{
|
||||
fy_norm[i] = mult_r(fy_norm[i],sc_dyn);
|
||||
move16();/*Qx */
|
||||
}
|
||||
|
||||
test();
|
||||
test();
|
||||
IF( (L_sub(core_brate,ACELP_13k20) < 0 && cor_strong_limit == 0) || L_sub(core_brate,ACELP_9k60) < 0)
|
||||
{
|
||||
FOR(i = 160; i < L_FRAME; i++)
|
||||
{
|
||||
fy_norm[i] = s_min(fy_norm[i],shl(1,Qx));
|
||||
move16();
|
||||
fy_norm[i] = s_max(fy_norm[i],shl(-1,Qx));
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE IF ( L_sub(core_brate,ACELP_22k60) < 0 )
|
||||
{
|
||||
FOR(i = 160; i < L_FRAME; i++)
|
||||
{
|
||||
fy_norm[i] = s_min(fy_norm[i],shr_r(1536,sub(10,Qx)));
|
||||
move16();
|
||||
fy_norm[i] = s_max(fy_norm[i],shr_r(-1536,sub(10,Qx)));
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
static void Decreas_freqPeak_fx(
|
||||
Word16 *lsf_new, /* i : ISFs at the end of the frame */
|
||||
Word16 *exc_diffQ, /* i/o: frequency coefficients of per band */
|
||||
Word16 rat /* i : threshold of ratio between consecutive lsf_new_diff */
|
||||
)
|
||||
{
|
||||
Word16 i, j, k;
|
||||
Word16 last_bin = 0;
|
||||
Word16 pos = 0;
|
||||
Word16 *src, max,avrg;
|
||||
Word32 L_avrg,L_tmp;
|
||||
Word16 lsf_new_diff[M];
|
||||
Word16 tmp,tmp1,exp;
|
||||
Word16 tmp2;
|
||||
|
||||
move16(); /*ptr init*/
|
||||
lsf_new_diff[0] = 0; /* prevent unitialized value */
|
||||
FOR(j=1; j<(M-1); j++)
|
||||
{
|
||||
lsf_new_diff[j] =sub( lsf_new[j] , lsf_new[j-1]);/*Qx2.56 */
|
||||
}
|
||||
|
||||
avrg = 0;
|
||||
move16();
|
||||
L_avrg = L_deposit_l(0);
|
||||
max = 1;
|
||||
move16();
|
||||
FOR(i=160; i<L_FRAME; i++)
|
||||
{
|
||||
IF(sub(abs_s(exc_diffQ[i]),max) > 0)
|
||||
{
|
||||
max = abs_s(exc_diffQ[i]);
|
||||
pos = i;
|
||||
move16();
|
||||
}
|
||||
L_avrg = L_add(L_avrg,abs_s(exc_diffQ[i]));
|
||||
}
|
||||
/* avrg /= 96; */
|
||||
L_avrg = Mult_32_16(L_avrg,21845);/*Q_exc+21 -15 ->Q_exc + 6 */
|
||||
avrg = round_fx(L_shl(L_avrg,10));/*Q_exc */
|
||||
last_bin = M-1;
|
||||
move16(); /* When the search is false, should equate the end of the vector, not the beginning */
|
||||
FOR(i=0; i<(M-1); i++)
|
||||
{
|
||||
if(sub(lsf_new[i],10240) > 0)
|
||||
{
|
||||
last_bin = i;
|
||||
move16();
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
FOR(i=last_bin; i<14; i++)
|
||||
{
|
||||
tmp = mult_r(rat,lsf_new_diff[i-1] );/*Qx2.56 */
|
||||
IF(sub(tmp , lsf_new_diff[i])>0)
|
||||
{
|
||||
src = &exc_diffQ[shl(sub(i,1),4)];
|
||||
move16();
|
||||
FOR(j=0; j<2; j++)
|
||||
{
|
||||
FOR(k=0; k<16; k++)
|
||||
{
|
||||
tmp = mult_r(16384,abs_s(*src));
|
||||
IF(sub(tmp,avrg)>0)
|
||||
{
|
||||
tmp = abs_s(*src) ;
|
||||
exp = norm_s(max);
|
||||
tmp1 = div_s(shl(1,sub(14,exp)),max);/*Q(29 - exp - Q_exc) */
|
||||
L_tmp = L_mult(tmp,tmp1);/*Q(30 - exp) */
|
||||
tmp = round_fx(L_shl(L_tmp,exp));/*Q14 */
|
||||
tmp = sub(32767,tmp);/*Q14 */
|
||||
L_tmp = L_mult(avrg,tmp);/*Q_exc +15 */
|
||||
|
||||
tmp = round_fx(L_shl(L_tmp,1));
|
||||
tmp1 = negate(tmp);
|
||||
|
||||
tmp2 = *src;
|
||||
*(src) = tmp1;
|
||||
move16();
|
||||
if( tmp2 > 0 )
|
||||
{
|
||||
*(src) = tmp;
|
||||
move16();
|
||||
}
|
||||
|
||||
}
|
||||
src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tmp = mult_r(8192,max);/*Q_exc */
|
||||
test();
|
||||
IF(sub(abs_s(exc_diffQ[pos]),max) == 0 && sub(tmp ,avrg)>0)
|
||||
{
|
||||
FOR(i=pos-1; i<pos+2; i++)
|
||||
{
|
||||
exc_diffQ[pos] =mult_r(16384,exc_diffQ[pos]);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void envelop_modify_fx(
|
||||
Word16 *exc_diffQ_fx, /* i/o: frequency coefficients of per band */
|
||||
Word16 *seed_tcx, /* i : Seed for noise */
|
||||
Word16 last_bin, /* i : last bin of bit allocation */
|
||||
Word16 *Ener_per_bd_iQ_fx, /* i : Quantized energy of targeted vector */
|
||||
Word16 Q_exc,
|
||||
Word16 *Q_hb_exc
|
||||
)
|
||||
{
|
||||
Word16 i, j, end_band;
|
||||
Word16 start_band;
|
||||
Word32 Ener_fx;
|
||||
Word16 Ener1_fx;
|
||||
Word16 tmp, tmp1;
|
||||
Word32 L_tmp;
|
||||
Word16 exp, exp1, frac;
|
||||
Word16 *src_fx;
|
||||
Word16 weight_fx;
|
||||
Word32 L_exc_diffQ_fx[L_FRAME16k], exc_diffQ_max;
|
||||
Word16 Q_tmp;
|
||||
|
||||
start_band = i_mult(last_bin, 16);
|
||||
end_band = L_FRAME;
|
||||
move16();
|
||||
Ener_fx = L_deposit_l(0);
|
||||
FOR(i=start_band; i<end_band; i++)
|
||||
{
|
||||
L_tmp = L_mult0(exc_diffQ_fx[i], exc_diffQ_fx[i]); /*2*Q_exc */
|
||||
Ener_fx = L_add(Ener_fx, L_shr(L_tmp, 7)); /*2*Q_exc-7 */
|
||||
}
|
||||
|
||||
tmp = sub(end_band, start_band);
|
||||
tmp = div_s(1, tmp);/*Q15 */
|
||||
Ener_fx = Mult_32_16(Ener_fx, tmp); /*Q(2*Q_exc-7+15)->Q(2*Q_exc-7) */
|
||||
|
||||
exp1 = norm_l(Ener_fx);
|
||||
Ener_fx = L_shl(Ener_fx, exp1);
|
||||
exp1 = 31-exp1-sub(shl(Q_exc,1),7);
|
||||
move16();
|
||||
Ener_fx = Isqrt_lc(Ener_fx, &exp1); /*Q(31-exp1) */
|
||||
|
||||
weight_fx = 16384; /*Q15 */
|
||||
src_fx = &exc_diffQ_fx[start_band]; /*Q_exc */
|
||||
FOR(i=last_bin; i<last_bin+4; i++)
|
||||
{
|
||||
/*Ener1 = (float)(0.4f*pow(10, Ener_per_bd_iQ[i+1])); */
|
||||
L_tmp = L_shr(L_mult0(Ener_per_bd_iQ_fx[i+1], 27213), 9); /* 3.321928 in Q13 -> Q16 */
|
||||
|
||||
frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */
|
||||
tmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */
|
||||
/* output of Pow2() will be: */
|
||||
/* 16384 < Pow2() <= 32767 */
|
||||
exp = sub(exp, 14);
|
||||
Ener1_fx = mult_r(13107, shl(tmp, exp)); /*Q0 */
|
||||
|
||||
FOR(j=0; j<16; j++)
|
||||
{
|
||||
/**src = Ener1*(weight*(*src)*Ener + (1.0f-weight)*own_random(seed_tcx)/32768.0f); */
|
||||
L_tmp = Mult_32_16(Ener_fx, *src_fx); /*Q(31-exp+Q_exc-15) -> Q(16-exp+Q_exc) */
|
||||
tmp = extract_l(L_shr(L_tmp, add(4, sub(Q_exc, exp1)))); /*Q12 */
|
||||
tmp = mult_r(weight_fx, tmp); /*Q12 */
|
||||
|
||||
L_tmp = L_mult0(sub(32767, weight_fx), Random(seed_tcx)); /*Q30 */
|
||||
tmp1 = round_fx(L_shr(L_tmp, 2));
|
||||
|
||||
L_exc_diffQ_fx[16*i+j] = L_mult0(Ener1_fx, add(tmp, tmp1)); /*Q12 */ move32();
|
||||
src_fx++;
|
||||
}
|
||||
}
|
||||
|
||||
/*Ener1 = (float)(0.4f*pow(10, Ener_per_bd_iQ[15])); */
|
||||
L_tmp = L_shr(L_mult0(Ener_per_bd_iQ_fx[15], 27213), 9); /* 3.321928 in Q13 -> Q16 */
|
||||
|
||||
frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */
|
||||
tmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */
|
||||
/* output of Pow2() will be: */
|
||||
/* 16384 < Pow2() <= 32767 */
|
||||
exp = sub(exp, 14);
|
||||
Ener1_fx = mult_r(13107, shl(tmp, exp)); /*Q0 */
|
||||
|
||||
src_fx = &exc_diffQ_fx[224];
|
||||
FOR(j=0; j<32; j++)
|
||||
{
|
||||
/**src = Ener1*(weight*(*src)*Ener + (1.0f-weight)*own_random(seed_tcx)/32768.0f); */
|
||||
L_tmp = Mult_32_16(Ener_fx, *src_fx); /*Q(31-exp+Q_exc-15) -> Q(16-exp+Q_exc) */
|
||||
tmp = extract_l(L_shr(L_tmp, add(4, sub(Q_exc, exp1)))); /*Q12 */
|
||||
tmp = mult_r(weight_fx, tmp); /*Q12 */
|
||||
|
||||
L_tmp = L_mult0(sub(32767, weight_fx), Random(seed_tcx)); /*Q30 */
|
||||
tmp1 = round_fx(L_shr(L_tmp, 2)); /*Q12 */
|
||||
|
||||
L_exc_diffQ_fx[16*i+j] = L_mult0(Ener1_fx, add(tmp, tmp1)); /*Q12 */ move32();
|
||||
src_fx++;
|
||||
}
|
||||
|
||||
exc_diffQ_max = 0;
|
||||
move16();
|
||||
FOR(i=start_band; i<L_FRAME; i++)
|
||||
{
|
||||
IF(L_sub(L_abs(L_exc_diffQ_fx[i]), exc_diffQ_max) > 0)
|
||||
{
|
||||
exc_diffQ_max = L_abs(L_exc_diffQ_fx[i]);
|
||||
}
|
||||
}
|
||||
exp = norm_l(exc_diffQ_max);
|
||||
|
||||
IF(sub(exp,16) > 0)
|
||||
{
|
||||
*Q_hb_exc = 12;
|
||||
move16();
|
||||
FOR(i=start_band; i<L_FRAME; i++)
|
||||
{
|
||||
exc_diffQ_fx[i] = extract_l(L_exc_diffQ_fx[i]);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Q_tmp = sub(16, exp);
|
||||
*Q_hb_exc = sub(12, Q_tmp);
|
||||
FOR(i=start_band; i<L_FRAME; i++)
|
||||
{
|
||||
exc_diffQ_fx[i] = extract_l(L_shr(L_exc_diffQ_fx[i], Q_tmp));
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void highband_exc_dct_in_fx(
|
||||
const Word32 core_brate, /* i : core bitrate */
|
||||
const Word16 *mfreq_bindiv, /* i : bin per bands tables */
|
||||
Word16 last_bin, /* i : last bin of bit allocation */
|
||||
Word16 Diff_len, /* i : number of bin before cut-off frequency */
|
||||
Word16 noise_lev, /* i : pulses dynamic */
|
||||
Word16 pit_band_idx, /* i : bin position of the cut-off frequency */
|
||||
Word16 *exc_diffQ, /* i : frequency coefficients of per band */
|
||||
Word16 *seed_tcx, /* i : Seed for noise */
|
||||
Word16 *Ener_per_bd_iQ, /* i : Quantized energy of targeted vector */
|
||||
Word16 nb_subfr, /* i : Number of subframe considered */
|
||||
Word16 *exc_dct_in, /* o : dct of residual signal */
|
||||
Word16 last_coder_type, /* i : coding type of last frame */
|
||||
Word16 *bitallocation_band, /* i : bit allocation flag of each band */
|
||||
Word16 *lsf_new, /* i : LSFs at the end of the frame */
|
||||
Word16 *last_exc_dct_in, /* i : dct of residual signal of last frame */
|
||||
Word16 *last_ener, /* i : frequency energy of last frame */
|
||||
Word16 *last_bitallocation_band, /* i : bit allocation flag of each band of last frame */
|
||||
Word16 *bitallocation_exc, /* i : flag of decoded coefficients */
|
||||
Word16 bfi, /* i : bad frame indicator */
|
||||
const Word16 coder_type, /* i : coder type */
|
||||
Word16 bwidth,
|
||||
Word16 *exc_wo_nf , /* o : temporal excitation (in f domain) without noisefill */
|
||||
Word16 Qexc_diffQ,
|
||||
Word16 Q_exc,
|
||||
const Word16 GSC_noisy_speech
|
||||
,Word16 *lt_ener_per_band_fx /* i/o: Average per band energy */
|
||||
)
|
||||
{
|
||||
Word16 i, j, k;
|
||||
Word16 MAX_Bin = 0;
|
||||
Word16 last_bin_tmp,ener=0;
|
||||
Word16 noisepb[MBANDS_GN];
|
||||
Word16 Ener_per_bd_yQ[MBANDS_GN];
|
||||
Word16 *src, *dst;
|
||||
Word32 L_tmp;
|
||||
Word16 length_bin, bwe_flag = 0,tmp;
|
||||
Word16 frac,exp,tmp1;
|
||||
Word16 tmp2;
|
||||
Word16 *end, Q_hb_exc;
|
||||
|
||||
FOR( j=10; j<MBANDS_GN; j++ )
|
||||
{
|
||||
/* ener += (float)pow(10, Ener_per_bd_iQ[j]);
|
||||
ener += (float)pow(2, 3.321928*Ener_per_bd_iQ[j]); */
|
||||
|
||||
L_tmp = L_mult(Ener_per_bd_iQ[j], 27213); /* 3.321928 in Q13 -> Q27 */
|
||||
L_tmp = L_shr(L_tmp, 10); /* From Q27 to Q16 */
|
||||
|
||||
frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */
|
||||
tmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */
|
||||
/* output of Pow2() will be: */
|
||||
/* 16384 < Pow2() <= 32767 */
|
||||
exp = sub(exp, 14);
|
||||
tmp1 = shl(tmp,add(exp,0));
|
||||
ener = add (tmp1,ener);/*Q0 */
|
||||
}
|
||||
|
||||
test();
|
||||
IF( L_sub(core_brate,ACELP_8k00) == 0 && sub(bwidth,NB) != 0 )
|
||||
{
|
||||
if(sub(last_coder_type,AUDIO) != 0)
|
||||
{
|
||||
*last_ener = ener;
|
||||
move16();
|
||||
}
|
||||
test();
|
||||
test();
|
||||
IF((sub(last_bin,8) > 0 || Diff_len != 0) && sub(last_coder_type,AUDIO) == 0)
|
||||
{
|
||||
MAX_Bin = 10;
|
||||
move16();
|
||||
bwe_flag = 1;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
MAX_Bin = 15;
|
||||
move16();
|
||||
}
|
||||
|
||||
last_bin_tmp = last_bin;
|
||||
move16();
|
||||
last_bin = s_max(last_bin , MAX_Bin);
|
||||
last_bin = add(last_bin, 1);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
last_bin = MBANDS_GN;
|
||||
move16();
|
||||
last_bin_tmp = last_bin;
|
||||
move16();
|
||||
}
|
||||
IF( bfi )
|
||||
{
|
||||
set16_fx( noisepb, 13107, MBANDS_GN ); /*0.4 in Q15 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
EstimateNoiseLevel_fx( noisepb, core_brate, Diff_len, last_bin, coder_type, noise_lev, pit_band_idx,
|
||||
last_bin_tmp, bwidth );
|
||||
}
|
||||
|
||||
IF( exc_wo_nf != NULL )
|
||||
{
|
||||
Copy( exc_diffQ, exc_wo_nf, L_FRAME );
|
||||
}
|
||||
|
||||
test();
|
||||
IF( GSC_noisy_speech && !bfi )
|
||||
{
|
||||
set16_fx( noisepb, 3277, MBANDS_GN );
|
||||
}
|
||||
Apply_NoiseFill_fx( exc_diffQ, seed_tcx, noisepb, Diff_len, last_bin, coder_type, mfreq_bindiv, Qexc_diffQ );
|
||||
|
||||
/*--------------------------------------------------------------------------------------*
|
||||
* Quantize average gain
|
||||
* Substract Q averaged gain
|
||||
* VQ of remaining gain per band
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
test();
|
||||
IF( L_sub(core_brate,ACELP_8k00) == 0 && sub(bwidth,NB) != 0 )
|
||||
{
|
||||
Ener_per_band_comp_fx(exc_diffQ, Ener_per_bd_yQ, Qexc_diffQ, add(last_bin,1), 0);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Ener_per_band_comp_fx(exc_diffQ, Ener_per_bd_yQ, Qexc_diffQ, MBANDS_GN, 1 );
|
||||
|
||||
IF( sub(nb_subfr, 4) < 0 )
|
||||
{
|
||||
FOR(i = L_FRAME-16; i < L_FRAME; i++)
|
||||
{
|
||||
/*exc_diffQ[i] *= 0.067f * i - 15.0f; = -15 - (-0.067f * i) */
|
||||
tmp = msu_r(-7680*65536, -17564, shl(i,6));/*-15 in Q9; -0.067 in Q18 and i in Q6= Q9 */
|
||||
L_tmp = L_mult(exc_diffQ[i],tmp); /*Q(Qexc_diffQ+10) */
|
||||
exc_diffQ[i] = round_fx(L_shl(L_tmp,16-10));/*Qexc_diffQ */
|
||||
}
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------------------*
|
||||
* Check potential energy excitation overshoot
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
IF( bfi )
|
||||
{
|
||||
test();
|
||||
IF (GSC_noisy_speech == 0 && sub(coder_type,UNVOICED) > 0 ) /* Here coder_type == last_coder_type because of the bfi */
|
||||
{
|
||||
FOR( i=0; i<last_bin; i++ )
|
||||
{
|
||||
Ener_per_bd_iQ[i]= s_min( Ener_per_bd_iQ[i], sub(sub(lt_ener_per_band_fx[i],154), Ener_per_bd_yQ[i]));
|
||||
move16();
|
||||
lt_ener_per_band_fx[i] = sub(lt_ener_per_band_fx[i], 77);
|
||||
move16();
|
||||
}
|
||||
FOR(; i<MBANDS_GN; i++ )
|
||||
{
|
||||
Ener_per_bd_iQ[i]= s_min( Ener_per_bd_iQ[i], sub(lt_ener_per_band_fx[i],154));
|
||||
move16();
|
||||
lt_ener_per_band_fx[i] = sub(lt_ener_per_band_fx[i], 77);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
FOR( i=0; i<last_bin; i++ )
|
||||
{
|
||||
Ener_per_bd_iQ[i]= s_min( Ener_per_bd_iQ[i], sub(add(lt_ener_per_band_fx[i],1229), Ener_per_bd_yQ[i]));
|
||||
move16();
|
||||
lt_ener_per_band_fx[i] = sub(lt_ener_per_band_fx[i], 77);
|
||||
move16();
|
||||
}
|
||||
FOR( ; i<MBANDS_GN; i++ )
|
||||
{
|
||||
Ener_per_bd_iQ[i]= s_min( Ener_per_bd_iQ[i], add(lt_ener_per_band_fx[i],1229));
|
||||
move16();
|
||||
lt_ener_per_band_fx[i] = sub(lt_ener_per_band_fx[i], 77);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------------------*
|
||||
* Apply decoded gain onto the difference signal
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
IF( GSC_noisy_speech )
|
||||
{
|
||||
FOR( i= 0; i < L_FRAME; i++ )
|
||||
{
|
||||
exc_diffQ[i] = mult_r(exc_diffQ[i], 29491);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
Comp_and_apply_gain_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, Q_exc );
|
||||
|
||||
IF( exc_wo_nf != NULL )
|
||||
{
|
||||
Comp_and_apply_gain_fx( exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1 , Qexc_diffQ, Q_exc);
|
||||
Vr_add( exc_dct_in, exc_wo_nf, exc_wo_nf, L_FRAME );
|
||||
}
|
||||
/*--------------------------------------------------------------------------------------*
|
||||
* add the correction layer to the LF bins,
|
||||
* and add the quantized pulses or the noise for the higher part of the spectrum
|
||||
* (non valuable temporal content already zeroed)
|
||||
* DC is Zeroed
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
|
||||
Vr_add( exc_dct_in, exc_diffQ, exc_dct_in, L_FRAME );
|
||||
test();
|
||||
IF( core_brate == ACELP_8k00 && bwidth != NB )
|
||||
{
|
||||
IF( sub(bwe_flag,1) == 0 )
|
||||
{
|
||||
last_bin = sub(last_bin, 1);
|
||||
tmp = i_mult(MAX_Bin, 16);
|
||||
tmp1 = i_mult(last_bin, 16);
|
||||
src = &exc_diffQ[sub(L_FRAME,1)];
|
||||
move16();
|
||||
dst = &exc_dct_in[sub(tmp,1)];
|
||||
move16();
|
||||
end = &exc_diffQ[sub(tmp1,1)];
|
||||
move16();
|
||||
|
||||
WHILE (src> end)
|
||||
{
|
||||
*src-- = *dst--;
|
||||
move16();
|
||||
}
|
||||
test();
|
||||
test();
|
||||
if( (bitallocation_exc[0] != 0 || bitallocation_exc[1] != 0) && L_sub(core_brate, ACELP_8k00) == 0 )
|
||||
{
|
||||
exc_diffQ[160] = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
Q_hb_exc = 0;
|
||||
move16();
|
||||
envelop_modify_fx( exc_diffQ, seed_tcx, last_bin, Ener_per_bd_iQ, Q_exc, &Q_hb_exc);
|
||||
Copy_Scale_sig( &exc_diffQ[tmp1], &exc_dct_in[tmp1], sub(L_FRAME,tmp1), sub(Q_exc, Q_hb_exc)); /* from Q_hb_exc -> Q_exc as expected */
|
||||
}
|
||||
|
||||
IF( sub(nb_subfr,4) < 0 )
|
||||
{
|
||||
FOR( i = sub(L_FRAME,16); i < L_FRAME; i++ )
|
||||
{
|
||||
/*exc_dct_in[i] *= (0.067f*i-15.f); */
|
||||
tmp = mult_r(17564,shl(i,6)); /*0.067 in Q18 and i in Q6= Q9 */
|
||||
tmp = sub(tmp,7680); /*15 in Q9 = Q9 */
|
||||
L_tmp = L_mult(exc_dct_in[i],tmp);/*Q(Q_exc+10) */
|
||||
exc_dct_in[i] = round_fx(L_shl(L_tmp,6));/*Q_exc */
|
||||
}
|
||||
}
|
||||
|
||||
tmp1 = mult_r(ener,16384);
|
||||
tmp1 = sub(*last_ener,tmp1);
|
||||
tmp = mult_r(*last_ener,16384);
|
||||
tmp = sub(ener,tmp);
|
||||
test();
|
||||
IF( tmp>0 && tmp1>0 )
|
||||
{
|
||||
length_bin = 6;
|
||||
move16();
|
||||
IF(last_coder_type != AUDIO)
|
||||
{
|
||||
set16_fx( last_bitallocation_band, 0, 6 );
|
||||
Copy( &exc_dct_in[(4+length_bin)*16], &last_exc_dct_in[(4+length_bin)*16], length_bin*16 );
|
||||
}
|
||||
|
||||
FOR(i=4; i<(4+length_bin); i++)
|
||||
{
|
||||
test();
|
||||
IF( !(bitallocation_band[i] == 0 && last_bitallocation_band[i-4] == 0))
|
||||
{
|
||||
k = shl(add(i,length_bin),4);
|
||||
src = &exc_dct_in[k]; /*(i+length_bin)*16*/
|
||||
dst = &last_exc_dct_in[k];
|
||||
FOR(j=0; j<16; j++)
|
||||
{
|
||||
tmp= mult_r(10923,abs_s(*src));
|
||||
tmp1 =mult_r(10923,abs_s(*dst));
|
||||
|
||||
IF(sub(tmp,abs_s(*dst)) >0)
|
||||
{
|
||||
tmp2 = *src;
|
||||
*src = mult_r(16384,sub(*src , abs_s(*dst))); /*Q_exc */ move16();
|
||||
tmp = mult_r(16384,add(tmp2 , abs_s(*dst))); /*Q_exc */
|
||||
if( tmp2 > 0 )
|
||||
{
|
||||
*src = tmp;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE IF (sub(tmp1,abs_s(*src)) >0)
|
||||
{
|
||||
tmp = mult_r(*src,22938);
|
||||
tmp1 = mult_r(9830,abs_s(*dst));
|
||||
tmp2 = *src;
|
||||
*src = sub(tmp,tmp1); /*Q_exc */ move16();
|
||||
if( tmp2 > 0 )
|
||||
{
|
||||
*src = add(tmp,tmp1); /*Q_exc */ move16();
|
||||
}
|
||||
}
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
IF(sub(bwe_flag,1) == 0)
|
||||
{
|
||||
Decreas_freqPeak_fx( lsf_new, exc_dct_in, 9830 );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Decreas_freqPeak_fx( lsf_new, exc_dct_in, 16384 );
|
||||
}
|
||||
}
|
||||
|
||||
Copy( &exc_dct_in[64], &last_exc_dct_in[64], L_FRAME-64 );
|
||||
Copy(&bitallocation_band[4], last_bitallocation_band, 6);
|
||||
*last_ener = ener;
|
||||
move16();
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+139
@@ -0,0 +1,139 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
#define ATT_LENGHT 64
|
||||
#define ATT_SEG_LEN (L_FRAME/ATT_LENGHT)
|
||||
#define INV_ATT_SEG_LEN (1.0f/ATT_SEG_LEN)
|
||||
#define INV_L_FRAME (1.0f/L_FRAME)
|
||||
|
||||
/*==========================================================================*/
|
||||
/* FUNCTION : void pre_echo_att_fx(); */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* PURPOSE : Attenuation of the pre-echo when encoder specifies an attack */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16) L_frame_fx : length of the frame Q0 */
|
||||
/* _ (Word16) gsc_attack_flag_fx : LP filter coefficient Q0 */
|
||||
/* _ (Word16) core_fx : core codec used Q0 */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*) exc_fx : adapt. excitation exc Q_exc */
|
||||
/* _ (Word32*) Last_frame_ener_fx : Energy of the last frame Q1 */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*==========================================================================*/
|
||||
void pre_echo_att_fx(
|
||||
Word32 *Last_frame_ener_fx, /* i/o: Energy of the last frame 2*Q_new+1*/
|
||||
Word16 *exc_fx, /* i/o: Excitation of the current frame Q_new*/
|
||||
const Word16 gsc_attack_flag_fx /* i : flag signalling attack encoded by AC mode (GSC) */
|
||||
,const Word16 Q_new
|
||||
,const Word16 last_coder_type_fx /* i : Last coding mode */
|
||||
)
|
||||
{
|
||||
Word32 etmp_fx;
|
||||
Word32 finc_fx[ATT_LENGHT] = {0};
|
||||
Word16 ratio_fx;
|
||||
Word16 attack_pos_fx, i;
|
||||
Word32 L_tmp, L_tmp1;
|
||||
Word16 tmp, n1, n2, exp, frac1, frac2;
|
||||
Word32 etmp1_fx;
|
||||
test();
|
||||
IF ( sub(gsc_attack_flag_fx,1) == 0 && sub(last_coder_type_fx, AUDIO) == 0) /*gsc_attack_flag_fx does not get set for all the test cases */
|
||||
{
|
||||
/*-------------------------------------------------------------------------*
|
||||
* Find where the onset (attack) occurs by computing the energy per section
|
||||
* The inverse weighting aims to favor the first maxima in case of
|
||||
* gradual onset
|
||||
*-------------------------------------------------------------------------*/
|
||||
FOR(i = 0; i < ATT_LENGHT; i++)
|
||||
{
|
||||
L_tmp = sum2_fx(&exc_fx[shl(i,2)], ATT_SEG_LEN ); /*2*Q_new+1, //ATT_SEG_LEN=(L_FRAME/ATT_LENGHT)=4(=shl(x,2))*/
|
||||
tmp = div_s(sub(ATT_LENGHT,i),ATT_LENGHT); /*Q15 */
|
||||
L_tmp = Mult_32_16(L_tmp, tmp); /*2*Q_new+1 */
|
||||
finc_fx[i] = L_tmp;
|
||||
move32(); /*2*Q_new+1 */
|
||||
}
|
||||
|
||||
attack_pos_fx = maximum_32_fx(finc_fx, ATT_LENGHT, &etmp_fx);
|
||||
|
||||
/* Scaled the maximum energy and allowed 6 dB increase*/
|
||||
etmp_fx = L_shr(etmp_fx,add(2+1-4, shl(Q_new,1)));/*2*Q_new+1 //INV_ATT_SEG_LEN=1/4(=shr(x,2)) -> Q4 */
|
||||
etmp1_fx = etmp_fx;
|
||||
move32();
|
||||
*Last_frame_ener_fx = L_shl(*Last_frame_ener_fx,2);
|
||||
move32(); /*2*Q_new+1 */
|
||||
|
||||
/* If the maximum normalized energy > last frame energy + 6dB */
|
||||
test();
|
||||
IF( L_sub(etmp_fx,*Last_frame_ener_fx) > 0 && attack_pos_fx > 0 )
|
||||
{
|
||||
/* Find the average energy before the attack */
|
||||
L_tmp = sum32_fx( finc_fx, attack_pos_fx); /*Q1 */
|
||||
L_tmp1 = L_shr(L_mult(attack_pos_fx,attack_pos_fx),1); /*Q0 */
|
||||
tmp = round_fx(Isqrt(L_tmp1)); /*Q15 */
|
||||
L_tmp = L_shr(L_tmp,2); /*Q1 ; ATT_SEG_LEN=4 */
|
||||
etmp_fx = Mult_32_16(L_tmp,tmp); /*Q1 */
|
||||
|
||||
etmp_fx = L_shr(etmp_fx,add(1-4, shl(Q_new,1))); /* makes etmp i nQ4 as *Last_frame_ener_fx */
|
||||
/* Find the correction factor and apply it before the attack */
|
||||
/* ratio = (float)sqrt(*Last_frame_ener/etmp);*/
|
||||
/* = isqrt(etmp/(*Last_frame_ener)) */
|
||||
etmp_fx = L_max(etmp_fx,1);
|
||||
*Last_frame_ener_fx = L_max(*Last_frame_ener_fx,1);
|
||||
n1 = norm_l(etmp_fx);
|
||||
n2 = norm_l(*Last_frame_ener_fx);
|
||||
|
||||
n1 = sub(n1,1);
|
||||
exp = sub(n1,n2);
|
||||
|
||||
frac1 = round_fx(L_shl(etmp_fx,n1));
|
||||
frac2 = round_fx(L_shl(*Last_frame_ener_fx,n2));
|
||||
|
||||
L_tmp = L_mult0(128, div_s(frac1, frac2)); /* s = gain_out / gain_in */
|
||||
L_tmp = L_shr(L_tmp, exp); /* add exponent */
|
||||
|
||||
L_tmp = Isqrt(L_tmp);
|
||||
ratio_fx = round_fx(L_shl(L_tmp, 9));
|
||||
|
||||
/* Pre-echo atttenuation should never increase the energy */
|
||||
ratio_fx = s_min(ratio_fx, 8192);
|
||||
FOR(i = 0; i < attack_pos_fx*ATT_SEG_LEN; i++)
|
||||
{
|
||||
/*exc_fx[i] *= ratio_fx;*/
|
||||
exc_fx[i] = round_fx(L_shl(L_mac(-8192, exc_fx[i], ratio_fx), 2));
|
||||
}
|
||||
}
|
||||
*Last_frame_ener_fx = etmp1_fx;
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/*-------------------------------------------------------*
|
||||
* In normal cases, just compute the energy of the frame
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
etmp_fx = sum2_fx( exc_fx, L_FRAME ); /*2*Q_new+1 */
|
||||
|
||||
etmp_fx = L_shr(etmp_fx,add(8+1-4, shl(Q_new,1))); /*2*Q_new+1 //INV_L_FRAME = 1/256 -> Q4*/
|
||||
*Last_frame_ener_fx = etmp_fx;
|
||||
move32(); /*2*Q_new+1*/
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+324
@@ -0,0 +1,324 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
#include "rom_com_fx.h"
|
||||
|
||||
#include "basop_util.h"
|
||||
#include "rom_basop_util.h"
|
||||
|
||||
void getLookAheadResSig( Word16 *speechLookAhead, Word16 *A_3Q12, Word16 *res, Word16 L_frame, Word16 numSubFrame )
|
||||
{
|
||||
Word16 *p_A;
|
||||
Word16 i_subfr;
|
||||
Word16 subfr_len[2] = { L_SUBFR, L_SUBFR };
|
||||
|
||||
if( sub( L_FRAME16k, L_frame )>0 )
|
||||
{
|
||||
subfr_len[1] = 48;
|
||||
move16(); /* 0.75 * L_SUBFR(64) */
|
||||
}
|
||||
|
||||
p_A = A_3Q12;
|
||||
FOR(i_subfr=0; i_subfr<numSubFrame*L_SUBFR; i_subfr+=L_SUBFR)
|
||||
{
|
||||
/* calculate residual signal */
|
||||
Residu3_fx( p_A,
|
||||
&speechLookAhead[i_subfr],
|
||||
&res[i_subfr],
|
||||
subfr_len[shr(i_subfr,6)],
|
||||
0
|
||||
);
|
||||
|
||||
/* pointer initialization */
|
||||
p_A += (M+1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void updateLSFForConcealment( HANDLE_PLC_ENC_EVS decState, Word16 *lsf_14Q1, Word16 m )
|
||||
{
|
||||
Word16 i;
|
||||
Word32 L_tmp = 0;
|
||||
const Word16 divide_by_3_Q15 = 10923;
|
||||
|
||||
FOR (i=0; i<m; i++)
|
||||
{
|
||||
L_tmp = L_mult( divide_by_3_Q15, decState->lsfoldbfi1_14Q1[i] );
|
||||
L_tmp = L_mac( L_tmp, divide_by_3_Q15, decState->lsfoldbfi0_14Q1[i] );
|
||||
decState->lsf_adaptive_mean_14Q1[i] = mac_r( L_tmp, divide_by_3_Q15, lsf_14Q1[i] );
|
||||
decState->lsfoldbfi1_14Q1[i] = decState->lsfoldbfi0_14Q1[i];
|
||||
move16();
|
||||
decState->lsfoldbfi0_14Q1[i] = lsf_14Q1[i];
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void getConcealedLP( HANDLE_PLC_ENC_EVS memDecState, Word16 *AqCon, const Word16 lsfBase[], Word16 last_good, Word16 L_frame)
|
||||
{
|
||||
Word16 *lsf;
|
||||
Word16 lsp[(NB_DIV+1)*M];
|
||||
Word32 int_fs;
|
||||
|
||||
move16();
|
||||
lsf = memDecState->lsf_con;
|
||||
|
||||
|
||||
dlpc_bfi( L_frame, &lsf[0], memDecState->lsfold_14Q1, last_good,
|
||||
1, memDecState->mem_MA_14Q1, memDecState->mem_AR, &(memDecState->stab_fac_Q15), memDecState->lsf_adaptive_mean_14Q1,
|
||||
1,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
lsfBase,
|
||||
0
|
||||
);
|
||||
Copy( memDecState->lspold_Q15, lsp, M );
|
||||
|
||||
int_fs = INT_FS_FX;
|
||||
move32();
|
||||
if( sub(L_frame,L_FRAME_16k) == 0 )
|
||||
{
|
||||
int_fs = INT_FS_16k_FX;
|
||||
move32();
|
||||
}
|
||||
lsf2lsp_fx( lsf, &lsp[M], M, int_fs );
|
||||
|
||||
int_lsp_fx( L_frame, &lsp[0], &lsp[M], AqCon, M, interpol_frac_fx, 0 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void getConcealedLSF( HANDLE_PLC_ENC_EVS memDecState, const Word16 lsfBase[], Word16 last_good, Word16 L_frame)
|
||||
{
|
||||
Word16 *lsf = memDecState->lsf_con;
|
||||
|
||||
|
||||
dlpc_bfi( L_frame, &lsf[0], memDecState->lsfold_14Q1, last_good,
|
||||
1, memDecState->mem_MA_14Q1, memDecState->mem_AR, &(memDecState->stab_fac_Q15), memDecState->lsf_adaptive_mean_14Q1,
|
||||
1,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
lsfBase,
|
||||
0
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void reorder_lsfs(Word16 *lsf, const Word16 min_dist, const Word16 n, const Word32 sr_core);
|
||||
|
||||
void RecLpcSpecPowDiffuseLc( Word16 *lspq, Word16 *lsp_old, Word16 *lsfq, Decoder_State_fx *st, Word16 reset_q )
|
||||
{
|
||||
const Word16 *means;
|
||||
Word16 lsf_old[M];
|
||||
Word16 i;
|
||||
|
||||
means = PlcGetLsfBase ( st->lpcQuantization,
|
||||
st->narrowBand,
|
||||
st->sr_core );
|
||||
|
||||
Copy( st->lsf_old_fx, lsf_old, M );
|
||||
|
||||
modify_lsf( lsf_old, M, st->sr_core, reset_q );
|
||||
|
||||
lsf2lsp_fx( lsf_old, lsp_old, M, st->sr_core );
|
||||
|
||||
IF( reset_q )
|
||||
{
|
||||
FOR ( i=0; i<M; i++ )
|
||||
{
|
||||
lsfq[i] = add(st->mem_MA_fx[i], means[i]);
|
||||
move16();
|
||||
}
|
||||
sort_fx( lsfq, 0, sub(M, 1) );
|
||||
|
||||
reorder_lsfs( lsfq, LSF_GAP_FX, M, st->sr_core );
|
||||
lsf2lsp_fx( lsfq, lspq, M, st->sr_core );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
modify_lsf( lsfq, M, st->sr_core, reset_q );
|
||||
lsf2lsp_fx(lsfq, lspq, M, st->sr_core);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void modify_lsf(
|
||||
Word16 *lsf,
|
||||
const Word16 n,
|
||||
const Word32 sr_core
|
||||
, Word16 reset_q
|
||||
)
|
||||
{
|
||||
Word16 i, k, th_x1p28_Q14;
|
||||
Word16 gap, gap_sum;
|
||||
|
||||
|
||||
th_x1p28_Q14 = 4864/*1900.0f*1.28f Q1*/;
|
||||
move16();
|
||||
if( L_sub( sr_core, 16000 ) == 0 )
|
||||
{
|
||||
th_x1p28_Q14 = 6080/*2375.0f*1.28f Q1*/;
|
||||
move16();
|
||||
}
|
||||
|
||||
IF( reset_q == 0 )
|
||||
{
|
||||
th_x1p28_Q14 = 2048; /* 800.0f*1.28f Q1*/ move16();
|
||||
if( L_sub( sr_core, 16000 ) == 0 )
|
||||
{
|
||||
th_x1p28_Q14 = 2560; /*1000.0f*1.28f Q1*/ move16();
|
||||
}
|
||||
}
|
||||
|
||||
FOR ( i=1; i<n; i++)
|
||||
{
|
||||
IF ( sub(lsf[i], th_x1p28_Q14) >= 0 )
|
||||
{
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
gap = mult_r(lsf[i - 1], InvIntTable[i]);
|
||||
|
||||
move16();
|
||||
gap_sum = gap;
|
||||
i = sub(i,1);
|
||||
FOR(k = 0; k < i; k++)
|
||||
{
|
||||
move16();
|
||||
lsf[k] = gap_sum;
|
||||
gap_sum = add(gap_sum, gap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void reorder_lsfs(
|
||||
Word16 *lsf, /* i/o: vector of lsfs in the frequency domain (0..0.5)*/
|
||||
const Word16 min_dist0, /* i : minimum required distance */
|
||||
const Word16 n, /* i : LPC order */
|
||||
const Word32 sr_core /* i : input sampling frequency */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word16 curr_min_dist;
|
||||
Word16 min_dist_fac2;
|
||||
Word16 min_dist_fac3;
|
||||
Word16 lsf_min;
|
||||
Word16 lsf_max;
|
||||
Word16 fs2;
|
||||
Word16 th1, th2;
|
||||
Word16 min_dist;
|
||||
|
||||
|
||||
fs2 = 16384/*6400.0 * 1.28 Q1*/;
|
||||
move16();
|
||||
|
||||
if(L_sub(sr_core, 16000) == 0)
|
||||
{
|
||||
fs2 = 20480/*8000.0 * 1.28 Q1*/;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Verify the LSF ordering and minimum GAP
|
||||
*-----------------------------------------------------------------*/
|
||||
IF( L_sub( sr_core, 16000 )==0 )
|
||||
{
|
||||
th1 = 3200;
|
||||
move16();
|
||||
th2 = 6080;
|
||||
move16();
|
||||
min_dist = add( min_dist0, shr(min_dist0,2) );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
th1 = 2560;
|
||||
move16();
|
||||
th2 = 4864;
|
||||
move16();
|
||||
min_dist = min_dist0;
|
||||
move16();
|
||||
}
|
||||
min_dist_fac2 = shl(min_dist, 1);
|
||||
min_dist_fac3 = add(min_dist, min_dist_fac2);
|
||||
curr_min_dist = min_dist_fac3;
|
||||
move16();
|
||||
|
||||
lsf_min = curr_min_dist;
|
||||
move16();
|
||||
|
||||
FOR (i = 0; i < n; i++)
|
||||
{
|
||||
IF (sub(lsf[i], th1) > 0)
|
||||
{
|
||||
curr_min_dist = min_dist_fac2;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
if (sub(lsf[i], th2) > 0)
|
||||
{
|
||||
curr_min_dist = min_dist;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
if (sub(lsf[i], lsf_min) < 0)
|
||||
{
|
||||
lsf[i] = lsf_min;
|
||||
move16();
|
||||
}
|
||||
|
||||
lsf_min = add(lsf[i], curr_min_dist);
|
||||
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------------------*
|
||||
* Reverify the LSF ordering and minimum GAP in the reverse order (security)
|
||||
*------------------------------------------------------------------------------------------*/
|
||||
|
||||
lsf_max = sub(fs2, curr_min_dist);
|
||||
|
||||
IF (sub(lsf[n-1], lsf_max) > 0) /* If danger of unstable filter in case of resonance in HF */
|
||||
{
|
||||
FOR (i = sub(n, 1); i >= 0; i--) /* Reverify the minimum ISF gap in the reverse direction */
|
||||
{
|
||||
IF (sub(lsf[i], th2) <= 0)
|
||||
{
|
||||
curr_min_dist = min_dist_fac2;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
if (sub(lsf[i], th1) <= 0)
|
||||
{
|
||||
curr_min_dist = min_dist_fac3;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
if (sub(lsf[i], lsf_max) > 0)
|
||||
{
|
||||
lsf[i] = lsf_max;
|
||||
move16();
|
||||
}
|
||||
lsf_max = sub(lsf[i], curr_min_dist);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Executable
+250
@@ -0,0 +1,250 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "options.h"
|
||||
|
||||
|
||||
#define HP20_COEFF_SCALE (2)
|
||||
|
||||
/*
|
||||
* hp20
|
||||
*
|
||||
* Function:
|
||||
* 2nd order high pass filter with nominal cut off frequency at 20 Hz.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
|
||||
static Word32 HP50_Mode2_Mpy_32_16_fix(Word32 a, Word16 b)
|
||||
{
|
||||
Word32 result = Mpy_32_16_1(a,b);
|
||||
/* perform rounding towards lower value for negative results */
|
||||
if (result < 0) result = L_add(result,1);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Word32 HP50_Mpy_32_32_fix(Word32 a, Word32 b)
|
||||
{
|
||||
Word32 result = Mpy_32_32(a,b);
|
||||
/* perform rounding towards lower value for negative results */
|
||||
if (result < 0) result = L_add(result,1);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void filter_2nd_order(
|
||||
Word16 signal[],
|
||||
const Word16 stride,
|
||||
const Word16 prescale,
|
||||
const Word16 lg,
|
||||
Word32 mem[4],
|
||||
Word32 a1,
|
||||
Word32 a2,
|
||||
Word32 b1,
|
||||
Word32 b2
|
||||
)
|
||||
{
|
||||
|
||||
Word16 i;
|
||||
Word16 x2, x1;
|
||||
Word32 L_sum, L_y1, L_y2;
|
||||
|
||||
|
||||
/*
|
||||
* Saturation: The states of the filter, namely L_y1 and L_y2 shall
|
||||
* never saturate, because that causes error in the filter feedback.
|
||||
* The final output written into signal[] might saturate because of
|
||||
* unavoidable filter overshoot.
|
||||
*/
|
||||
|
||||
/* Execute first 2 iterations with 32-bit x anx y memory values */
|
||||
BASOP_SATURATE_ERROR_ON
|
||||
L_sum = HP50_Mpy_32_32_fix(b2,mem[2]); /* b2*x2 */
|
||||
L_sum = L_add(L_sum,HP50_Mpy_32_32_fix(b1,mem[3])); /* b1*x1 */
|
||||
x2 = shr(signal[0*stride], prescale);
|
||||
L_sum = L_add(L_sum,HP50_Mode2_Mpy_32_16_fix(b2,x2)); /* b2*x0 */
|
||||
L_sum = L_add(L_sum, HP50_Mpy_32_32_fix(mem[0],a2)); /* y2*a2 */
|
||||
L_sum = L_add(L_sum, HP50_Mpy_32_32_fix(mem[1],a1)); /* y1*a1 */
|
||||
|
||||
L_y2 = L_shl(L_sum, HP20_COEFF_SCALE);
|
||||
BASOP_SATURATE_ERROR_OFF
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
signal[0*stride] = round_fx(L_shl(L_y2, prescale));
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
|
||||
BASOP_SATURATE_ERROR_ON
|
||||
L_sum = HP50_Mpy_32_32_fix(b2,mem[3]); /* b2*x2 */
|
||||
L_sum = L_add(L_sum,HP50_Mode2_Mpy_32_16_fix(b1,x2)); /* b1*x1 */
|
||||
x1 = shr(signal[1*stride], prescale);
|
||||
L_sum = L_add(L_sum,HP50_Mode2_Mpy_32_16_fix(b2,x1)); /* b2*x0 */
|
||||
L_sum = L_add(L_sum, HP50_Mpy_32_32_fix(mem[1],a2)); /* y2*a2 */
|
||||
L_sum = L_add(L_sum, HP50_Mpy_32_32_fix(L_y2, a1)); /* y1*a1 */
|
||||
|
||||
L_y1 = L_shl(L_sum, HP20_COEFF_SCALE);
|
||||
BASOP_SATURATE_ERROR_OFF
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
signal[1*stride] = round_fx(L_shl(L_y1, prescale));
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
|
||||
/* New we use a trick and toggle x1/x2 and L_y1/L_y2 to save a few cycles unrolling the loop by 2 */
|
||||
FOR (i = 2; i < lg; i+=2)
|
||||
{
|
||||
/* y[i+0] = b2*x[i-2] + b1*x[i-1] + b2*x[i-0] + a2*y[i-2] + a1*y[i-1]; */
|
||||
BASOP_SATURATE_ERROR_ON
|
||||
L_sum = HP50_Mode2_Mpy_32_16_fix(b2,x2);
|
||||
L_sum = L_add(L_sum,HP50_Mode2_Mpy_32_16_fix(b1,x1));
|
||||
x2 = shr(signal[i*stride], prescale);
|
||||
L_sum = L_add(L_sum,HP50_Mode2_Mpy_32_16_fix(b2,x2));
|
||||
L_sum = L_add(L_sum, HP50_Mpy_32_32_fix(L_y2,a2));
|
||||
L_sum = L_add(L_sum, HP50_Mpy_32_32_fix(L_y1,a1));
|
||||
|
||||
L_y2 = L_shl(L_sum, HP20_COEFF_SCALE);
|
||||
BASOP_SATURATE_ERROR_OFF
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
signal[i*stride] = round_fx(L_shl(L_y2, prescale));
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
/* y[i+1] = b2*x[i-1] + b1*x[i-0] + b2*x[i+1] + a2*y[i-1] + a1*y[i+0]; */
|
||||
BASOP_SATURATE_ERROR_ON
|
||||
L_sum = HP50_Mode2_Mpy_32_16_fix(b2,x1);
|
||||
L_sum = L_add(L_sum,HP50_Mode2_Mpy_32_16_fix(b1,x2));
|
||||
x1 = shr(signal[(i+1)*stride], prescale);
|
||||
L_sum = L_add(L_sum,HP50_Mode2_Mpy_32_16_fix(b2,x1));
|
||||
L_sum = L_add(L_sum, HP50_Mpy_32_32_fix(L_y1,a2));
|
||||
L_sum = L_add(L_sum, HP50_Mpy_32_32_fix(L_y2,a1));
|
||||
|
||||
L_y1 = L_shl(L_sum, HP20_COEFF_SCALE);
|
||||
BASOP_SATURATE_ERROR_OFF
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
signal[(i+1)*stride] = round_fx(L_shl(L_y1, prescale));
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
}
|
||||
/* update static filter memory from variables */
|
||||
mem[0] = L_y2;
|
||||
move32();
|
||||
mem[1] = L_y1;
|
||||
move32();
|
||||
mem[2] = L_deposit_h(x2);
|
||||
mem[3] = L_deposit_h(x1);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void hp20(Word16 signal[], /* i/o: signal to filter any */
|
||||
const Word16 stride, /* i : stride to be applied accessing signal */
|
||||
const Word16 lg, /* i : length of signal (integer) Q0 */
|
||||
Word32 mem[5], /* i/o: static filter memory with this layout: */
|
||||
/* mem[0]: y[-2] (32-bit) */
|
||||
/* mem[1]; y[-1] (32-bit) */
|
||||
/* mem[2]: x[-2] << 16 */
|
||||
/* mem[3]: x[-1] << 16 */
|
||||
/* Note: mem[0..3] need to be scaled per frame */
|
||||
/* mem[4]: states scale */
|
||||
const Word32 sFreq) /* i : input sampling rate Q0 */
|
||||
{
|
||||
Word32 a1, b1, a2, b2;
|
||||
Word16 prescale, prescaleOld, diff;
|
||||
|
||||
|
||||
|
||||
prescale = getScaleFactor16(signal, lg);
|
||||
prescaleOld = extract_l(mem[4]);
|
||||
diff = norm_l(L_shl(mem[2], prescaleOld));
|
||||
if (mem[2] != 0)
|
||||
{
|
||||
prescale = s_min(prescale, diff);
|
||||
}
|
||||
diff = norm_l(L_shl(mem[3], prescaleOld));
|
||||
if (mem[3] != 0)
|
||||
{
|
||||
prescale = s_min(prescale, diff);
|
||||
}
|
||||
/* Take into account the left shift performed into the loop + 1 bit headroom*/
|
||||
prescale = s_max(-12, sub(1+HP20_COEFF_SCALE, prescale));
|
||||
IF (prescale != prescaleOld)
|
||||
{
|
||||
diff = sub(prescale, prescaleOld);
|
||||
mem[0] = L_shr(mem[0], diff);
|
||||
move32();
|
||||
mem[1] = L_shr(mem[1], diff);
|
||||
move32();
|
||||
mem[2] = L_shr(mem[2], diff);
|
||||
move32();
|
||||
mem[3] = L_shr(mem[3], diff);
|
||||
move32();
|
||||
mem[4] = L_deposit_l(prescale);
|
||||
}
|
||||
|
||||
IF ( L_sub(sFreq,8000) == 0 )
|
||||
{
|
||||
/* hp filter 20Hz at 3dB for 8000 Hz input sampling rate
|
||||
[b,a] = butter(2, 20.0/4000.0, 'high');
|
||||
b = [0.988954248067140 -1.977908496134280 0.988954248067140]
|
||||
a = [1.000000000000000 -1.977786483776764 0.978030508491796]*/
|
||||
a1 = L_add(0,1061816033l/* 1.977786483776764 Q29*/);
|
||||
a2 = L_add(0,-525076131l/*-0.978030508491796 Q29*/);
|
||||
b1 = L_add(0,-1061881538l/*-1.977908496134280 Q29*/);
|
||||
b2 = L_add(0,530940769l/* 0.988954248067140 Q29*/);
|
||||
|
||||
}
|
||||
ELSE IF ( L_sub(sFreq,16000) == 0 )
|
||||
{
|
||||
/* hp filter 20Hz at 3dB for 16000KHz sampling rate
|
||||
[b,a] = butter(2, 20.0/8000.0, 'high');
|
||||
b = [0.994461788958195 -1.988923577916390 0.994461788958195]
|
||||
a = [1.000000000000000 -1.988892905899653 0.988954249933127] */
|
||||
a1 = L_add(0,1067778748l/* 1.988892905899653 Q29*/);
|
||||
a2 = L_add(0,-530940770l/*-0.988954249933127 Q29*/);
|
||||
b1 = L_add(0,-1067795215l/*-1.988923577916390 Q29*/);
|
||||
b2 = L_add(0,533897608l/* 0.994461788958195 Q29*/);
|
||||
|
||||
}
|
||||
ELSE IF ( L_sub(sFreq,32000) == 0 )
|
||||
{
|
||||
/* hp filter 20Hz at 3dB for 32000KHz sampling rate
|
||||
[b,a] = butter(2, 20.0/16000.0, 'high');
|
||||
b = [0.997227049904470 -1.994454099808940 0.997227049904470]
|
||||
a = [1.000000000000000 -1.994446410541927 0.994461789075954]*/
|
||||
a1 = L_add(0,1070760263l/* 1.994446410541927 Q29*/);
|
||||
a2 = L_add(0,-533897608l/*-0.994461789075954 Q29*/);
|
||||
b1 = L_add(0,-1070764392l/*-1.994454099808940 Q29*/);
|
||||
b2 = L_add(0,535382196l/* 0.997227049904470 Q29*/);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
assert (sFreq == 48000);
|
||||
/* hp filter 20Hz at 3dB for 48000KHz sampling rate
|
||||
[b,a] = butter(2, 20.0/24000.0, 'high');
|
||||
b =[0.998150511190452 -1.996301022380904 0.998150511190452]
|
||||
a =[1.000000000000000 -1.996297601769122 0.996304442992686]*/
|
||||
a1 = L_add(0,1071754114l/* 1.996297601769122 Q29*/);
|
||||
a2 = L_add(0,-534886875l/*-0.996304442992686 Q29*/);
|
||||
b1 = L_add(0,-1071755951l/*-1.996301022380904 Q29*/);
|
||||
b2 = L_add(0,535877975l/* 0.998150511190452 Q29*/);
|
||||
}
|
||||
|
||||
|
||||
filter_2nd_order(signal,
|
||||
stride,
|
||||
prescale,
|
||||
lg,
|
||||
mem,
|
||||
a1,
|
||||
a2,
|
||||
b1,
|
||||
b2);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Executable
+912
@@ -0,0 +1,912 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
|
||||
#define MIN_BITS_FIX 0 /* QRk=18 */
|
||||
#define HQ_16k40_BIT (HQ_16k40/50) /* 16400/50=328 */
|
||||
#define Qbf 14 /* Q value for bits_fact */
|
||||
#define C1_QRk (1<<SWB_BWE_LR_QRk) /* 1 */
|
||||
#define C1_Qbf (1<<Qbf) /* 1 */
|
||||
#define BITS_FACT_1p10 18022 /* (Word16)(1.10f*(float)pow(2, Qbf)+0.5f) */
|
||||
#define BITS_FACT_1p05 17203 /* (Word16)(1.05f*(float)pow(2, Qbf)+0.5f) */
|
||||
#define BITS_FACT_1p00 16384 /* (Word16)(1.00f*(float)pow(2, Qbf)+0.5f) */
|
||||
#define BITS_FACT_0p97 15892 /* (Word16)(0.97f*(float)pow(2, Qbf)+0.5f) */
|
||||
#define BITS_FACT_0p92 15073 /* (Word16)(0.92f*(float)pow(2, Qbf)+0.5f) */
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Bits2indvsb()
|
||||
*
|
||||
* Bit allocation to individual SB's in a group
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void Bits2indvsb_fx (
|
||||
const Word32 *L_be, /* i : Qbe Band Energy of sub-band */
|
||||
const Word16 start_band, /* i : Q0 start band indices */
|
||||
const Word16 end_band, /* i : Q0 end band indices */
|
||||
const Word16 Bits, /* i : Q0 Total number of bits allocated to a group */
|
||||
const Word32 L_Bits_needed, /* i : QRk smallest bit number for allocation in group */
|
||||
Word32 *L_Rsubband, /* o : QRk bit allocation of sub-band */
|
||||
Word16 *p2aflags_fx /* i/o: Q0 peaky/noise subband flag */
|
||||
)
|
||||
{
|
||||
Word16 i,j,k;
|
||||
Word32 L_R_temp[14]; /* QRk = QL_Rsubband; */
|
||||
Word16 Ravg_fx;
|
||||
Word16 QRavg;
|
||||
|
||||
const Word32 *L_y_ptr;
|
||||
Word32 *L_R_ptr;
|
||||
|
||||
Word16 Bits_avg_fx;
|
||||
Word16 QBavg;
|
||||
Word16 scale_fact_fx;
|
||||
|
||||
Word16 band_num_fx;
|
||||
Word16 index_fx[14];
|
||||
|
||||
Word16 y_index_fx[14];
|
||||
|
||||
Word16 be_sum_fx; /* Q0 */
|
||||
|
||||
Word16 exp_normn, exp_normd;
|
||||
Word16 enr_diffcnt_fx;
|
||||
Word16 th_5_fx;
|
||||
Word16 Rcnt_fx;
|
||||
|
||||
Word16 be_cnt_fx;
|
||||
Word16 *p2aflags_fx_ptr;
|
||||
|
||||
Word32 L_temp1;
|
||||
Word32 L_temp2;
|
||||
|
||||
band_num_fx = sub(end_band, start_band);
|
||||
L_y_ptr = L_be + start_band;
|
||||
L_R_ptr = L_Rsubband + start_band;
|
||||
p2aflags_fx_ptr = p2aflags_fx+start_band;
|
||||
|
||||
FOR ( i = 0; i < band_num_fx; i++ )
|
||||
{
|
||||
y_index_fx[i] = extract_h(L_shr(L_y_ptr[i], sub(SWB_BWE_LR_Qbe,16)));
|
||||
index_fx[i] = i;
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
/* Rearrange norm vector in decreasing order */
|
||||
reordvct_fx(y_index_fx, band_num_fx, index_fx);
|
||||
|
||||
be_sum_fx = 0;
|
||||
move16();
|
||||
be_cnt_fx = 0;
|
||||
move16();
|
||||
FOR( j=0; j<band_num_fx; j++ )
|
||||
{
|
||||
test();
|
||||
IF ( y_index_fx[j] <= 0 || p2aflags_fx_ptr[index_fx[j]] == 0 )
|
||||
{
|
||||
y_index_fx[j] = 0;
|
||||
move16();
|
||||
L_R_temp[j] = L_deposit_l(0);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_R_temp[j] = C1_QRk;
|
||||
move32(); /* filled not zero value */
|
||||
be_cnt_fx = add(be_cnt_fx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
i = sub(be_cnt_fx, 1);
|
||||
FOR(k = 0; k <=i ; k++)
|
||||
{
|
||||
if( L_R_temp[k] > 0 )
|
||||
{
|
||||
be_sum_fx = add(be_sum_fx, y_index_fx[k]);
|
||||
}
|
||||
}
|
||||
QBavg = 0;
|
||||
move16();
|
||||
|
||||
/*Ravg = (float) be_sum/be_cnt;*/
|
||||
Ravg_fx = 0;
|
||||
move16();
|
||||
QRavg = 0;
|
||||
move16();
|
||||
IF( be_cnt_fx != 0x0 )
|
||||
{
|
||||
exp_normn = norm_s(be_sum_fx);
|
||||
exp_normn = sub(exp_normn, 1);
|
||||
exp_normd = norm_s(be_cnt_fx);
|
||||
Ravg_fx = div_s(shl(be_sum_fx, exp_normn), shl(be_cnt_fx, exp_normd));
|
||||
|
||||
Ravg_fx = shr(Ravg_fx, 2); /* safe shift */
|
||||
QRavg = add(sub(exp_normn, exp_normd), 15-2);
|
||||
}
|
||||
|
||||
enr_diffcnt_fx = 0;
|
||||
move16();
|
||||
th_5_fx = shl(5, QRavg);
|
||||
FOR (j = 0; j < be_cnt_fx; j++)
|
||||
{
|
||||
if( sub(abs_s(sub(Ravg_fx, shl(y_index_fx[j], QRavg))), th_5_fx) > 0 )
|
||||
{
|
||||
enr_diffcnt_fx = add(enr_diffcnt_fx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
scale_fact_fx = 19661;
|
||||
move16(); /* 0.60f 19660.8(Q15) */
|
||||
if( enr_diffcnt_fx > 0 )
|
||||
{
|
||||
scale_fact_fx = 11468;
|
||||
move16(); /* 0.35f 11468.8(Q15) */
|
||||
}
|
||||
|
||||
/* Bits allocation to individual SB's in a group based on Band Energies */
|
||||
FOR (j = 0; j < be_cnt_fx; j++)
|
||||
{
|
||||
Rcnt_fx = add(i, 1);
|
||||
|
||||
/* Ravg = (float) be_sum/Rcnt; */
|
||||
exp_normn = norm_s(be_sum_fx);
|
||||
exp_normn = sub(exp_normn, 1);
|
||||
exp_normd = norm_s(Rcnt_fx);
|
||||
Ravg_fx = div_s(shl(be_sum_fx, exp_normn), shl(Rcnt_fx, exp_normd));
|
||||
Ravg_fx = shr(Ravg_fx, 2); /* safe shift */
|
||||
QRavg = add(sub(exp_normn, exp_normd), 15-2);
|
||||
|
||||
if(be_sum_fx <= 0)
|
||||
{
|
||||
be_sum_fx = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Bits_avg = (float) Bits/(be_sum+EPSILON); */
|
||||
Bits_avg_fx = 0;
|
||||
move16();
|
||||
QBavg = 0;
|
||||
move16();
|
||||
IF ( Bits != 0 )
|
||||
{
|
||||
exp_normn = norm_s(Bits);
|
||||
exp_normn = sub(exp_normn, 1);
|
||||
exp_normd = norm_s(be_sum_fx);
|
||||
Bits_avg_fx = div_s(shl(Bits, exp_normn), shl(be_sum_fx, exp_normd));
|
||||
Bits_avg_fx = shr(Bits_avg_fx, 2); /* safe_shift */
|
||||
QBavg = add(sub(exp_normn, exp_normd), 15-2);
|
||||
}
|
||||
FOR (k = 0; k <=i; k++)
|
||||
{
|
||||
IF(L_R_temp[k] > 0) /* Rtemp -> SWB_BWE_LR_QRk */
|
||||
{
|
||||
/* Allocate more bits to SB, if SB bandenergy is higher than average energy */
|
||||
/* R_temp[k] = (float)( Bits_avg * y_index[k]+( scale_fact * (y_index[k] - Ravg))); */
|
||||
L_temp1 = L_mult(Bits_avg_fx, y_index_fx[k]); /* QBavg+1 */
|
||||
L_temp2 = L_mult(scale_fact_fx, sub(shl(y_index_fx[k], QRavg), Ravg_fx)); /* 15+QRavg+1 */
|
||||
L_R_temp[k] = L_add(L_shr(L_temp1, sub(add(QBavg, 1), SWB_BWE_LR_QRk)), L_shr(L_temp2, sub(add(QRavg, 16), SWB_BWE_LR_QRk))); /* SWB_BWE_LR_QRk */
|
||||
}
|
||||
}
|
||||
IF ( L_sub(L_R_temp[i], L_Bits_needed) < 0 )
|
||||
{
|
||||
L_R_temp[i] = L_deposit_l(0);
|
||||
|
||||
p2aflags_fx_ptr[index_fx[i]] = 0;
|
||||
move16();
|
||||
|
||||
/* be_sum -= y_index[i]; */
|
||||
be_sum_fx = sub(be_sum_fx, y_index_fx[i]);
|
||||
|
||||
i = sub(i, 1);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Rearrange the bit allocation to align with original */
|
||||
FOR ( k = 0 ; k < band_num_fx; k++ )
|
||||
{
|
||||
j = index_fx[k];
|
||||
move16();
|
||||
L_R_ptr[j] = L_R_temp[k];
|
||||
move32();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* hq2_bit_alloc_har()
|
||||
*
|
||||
* Bit allocation mechanism for HQ_HARMONIC mode
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void hq2_bit_alloc_har_fx (
|
||||
const Word32 *L_y, /* i : Qbe band energy of sub-vectors */
|
||||
Word16 B_fx, /* i : Q0 number of available bits */
|
||||
const Word16 N_fx, /* i : Q0 number of sub-vectors */
|
||||
Word32 *L_Rsubband, /* o : QRk sub-band bit-allocation vector */
|
||||
Word16 p2a_bands_fx, /* i : highfreq bands */
|
||||
const Word32 L_core_brate, /* i : Q0 core bit rate */
|
||||
Word16 p2a_flags_fx[], /* i/o: Q0 p2a_flags */
|
||||
const Word16 band_width_fx[] /* i : Q0 table of band_width */
|
||||
)
|
||||
{
|
||||
Word16 i, j, k;
|
||||
|
||||
Word32 L_norm_sum; /* Qbe */
|
||||
Word32 L_Ravg_sub[GRP_SB]; /* Qbe */
|
||||
Word32 L_temp_band_energy[BANDS_MAX]; /* Qbe */
|
||||
|
||||
Word16 j_fx, k_fx, Bits_grp_fx[GRP_SB];
|
||||
|
||||
Word32 L_temp_band_energydiff[BANDS_MAX];
|
||||
Word16 G1_BE_DIFF_POS_fx; /* Q0 */
|
||||
Word32 L_G1_BE_DIFF_VAL; /* Qbe Word32 */
|
||||
Word16 final_gr_fact_pos_fx, gmax_range_fx[2], temp_fx;
|
||||
Word16 bits_fact_fx, bits_fact1_fx; /* Q? */
|
||||
Word16 grp_rngmax_fx[2] = {0};
|
||||
Word16 index_fx[NB_SWB_SUBBANDS_HAR], y_index_fx[NB_SWB_SUBBANDS_HAR], esthf_bits_fx, grp_bit_avg_fx, harmonic_band_fx;
|
||||
Word32 L_norm_sum_avg;
|
||||
Word32 L_norm_diff; /* Qbe */
|
||||
Word16 bits_allocweigh_fx; /* Q15 */
|
||||
Word16 grp_bound_fx[5];
|
||||
Word32 L_grp_thr[GRP_SB]; /* not require Word32 precission */
|
||||
Word16 lf_hf_ge_r_fx; /* Q15 */
|
||||
Word32 L_avg_enhf_en_diff; /* Qbe */
|
||||
|
||||
Word16 B_norm_fx;
|
||||
|
||||
Word32 L_temp, L_temp2;
|
||||
Word16 exp, frac;
|
||||
|
||||
Word32 L_THR1, L_THR2, L_THR3;
|
||||
|
||||
Word16 exp_norm;
|
||||
Word16 norm_sum_fx;
|
||||
Word16 Qns; /* Q value for norm_sum_fx */
|
||||
Word16 Inv_norm_sum_fx; /* 1/norm_sum */
|
||||
Word16 QIns; /* Q value for Inv_norm_sum_fx */
|
||||
|
||||
Word16 exp_normn, exp_normd;
|
||||
Word16 div_fx;
|
||||
|
||||
Word16 Inv_p2a_bands_fx;
|
||||
Word16 QIpb;
|
||||
|
||||
Word16 exp_shift;
|
||||
|
||||
L_THR1 = L_shl(L_deposit_l(THR1), SWB_BWE_LR_QRk);
|
||||
L_THR2 = L_shl(L_deposit_l(THR2), SWB_BWE_LR_QRk);
|
||||
L_THR3 = L_shl(L_deposit_l(THR3), SWB_BWE_LR_QRk);
|
||||
|
||||
set16_fx(Bits_grp_fx, 0, GRP_SB);
|
||||
|
||||
/* Initialize subbands bits allocation vector based on harmonic bands */
|
||||
harmonic_band_fx = add(sub(N_fx, p2a_bands_fx), 1);
|
||||
/*printf("harmonic_band= %d %d\n", harmonic_band, harmonic_band_fx);*/
|
||||
FOR (k = 0; k < N_fx; k++)
|
||||
{
|
||||
L_Rsubband[k] = (Word32)(C1_QRk);
|
||||
move32(); /* Constant Value */
|
||||
L_temp_band_energy[k] = L_y[k];
|
||||
move32(); /* SWB_BWE_LR_Qbe */
|
||||
}
|
||||
final_gr_fact_pos_fx = 2;
|
||||
move16();
|
||||
bits_fact_fx = C1_Qbf;
|
||||
move16();
|
||||
bits_fact1_fx = C1_Qbf;
|
||||
move16();
|
||||
|
||||
gmax_range_fx[0]= G1_RANGE;
|
||||
move16();
|
||||
gmax_range_fx[1]= G1G2_RANGE;
|
||||
move16();
|
||||
|
||||
IF( L_sub(L_core_brate, HQ_16k40) == 0 )
|
||||
{
|
||||
gmax_range_fx[1] = add(gmax_range_fx[1], 2);
|
||||
move16();
|
||||
}
|
||||
|
||||
/* decide each group range, for grouping spectral coefficients */
|
||||
grp_rngmax_fx[1] = 16;
|
||||
move16();
|
||||
grp_rngmax_fx[0] = 7;
|
||||
move16();
|
||||
temp_fx = 0;
|
||||
move16();
|
||||
FOR( i=0; i<2; i++ )
|
||||
{
|
||||
j_fx = gmax_range_fx[i];
|
||||
move16();
|
||||
k_fx = 0;
|
||||
move16();
|
||||
WHILE( L_sub(L_temp_band_energy[gmax_range_fx[i]-1], L_temp_band_energy[j_fx] ) >= 0x0L && sub(j_fx, grp_rngmax_fx[i]) < 0x0 )
|
||||
{
|
||||
test();
|
||||
k_fx = add(k_fx, 1);
|
||||
j_fx = add(j_fx, 1);
|
||||
}
|
||||
|
||||
temp_fx = k_fx;
|
||||
move16();
|
||||
IF( sub(temp_fx, 1) > 0 )
|
||||
{
|
||||
FOR( temp_fx = 2; temp_fx <= k_fx ; )
|
||||
{
|
||||
IF( L_sub(L_temp_band_energy[gmax_range_fx[i]+temp_fx-1], L_temp_band_energy[gmax_range_fx[i]+temp_fx]) < 0 )
|
||||
{
|
||||
BREAK;
|
||||
}
|
||||
ELSE IF( L_sub(L_temp_band_energy[gmax_range_fx[i]+temp_fx-1], L_temp_band_energy[gmax_range_fx[i]+temp_fx]) >= 0 )
|
||||
{
|
||||
temp_fx = add(temp_fx, 1);;
|
||||
IF( sub(temp_fx, k_fx) > 0 )
|
||||
{
|
||||
temp_fx = sub(temp_fx, 1);
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gmax_range_fx[i] = add(gmax_range_fx[i], temp_fx);
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
gmax_range_fx[i] = add(gmax_range_fx[i], temp_fx);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
grp_bound_fx[0] = 0;
|
||||
move16();
|
||||
FOR(i=1; i<GRP_SB-1; i++)
|
||||
{
|
||||
grp_bound_fx[i] = gmax_range_fx[i-1];
|
||||
move16();
|
||||
}
|
||||
grp_bound_fx[i] = harmonic_band_fx;
|
||||
move16();
|
||||
grp_bound_fx[i+1] = N_fx;
|
||||
move16();
|
||||
|
||||
|
||||
FOR(i=0; i<GRP_SB; i++)
|
||||
{
|
||||
L_Ravg_sub[i] = L_deposit_l(0);
|
||||
FOR ( j = grp_bound_fx[i]; j < grp_bound_fx[i+1]; j++ )
|
||||
{
|
||||
IF ( L_temp_band_energy[j] > 0x0L )
|
||||
{
|
||||
L_Ravg_sub[i] = L_add(L_Ravg_sub[i], L_temp_band_energy[j]);
|
||||
move32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
L_temp_band_energydiff[0] = L_temp_band_energy[0];
|
||||
move32();
|
||||
FOR ( j = 1; j < harmonic_band_fx; j++ )
|
||||
{
|
||||
L_temp_band_energydiff[j]= L_abs(L_sub(L_temp_band_energy[j], L_temp_band_energy[j-1]));
|
||||
move32();
|
||||
}
|
||||
|
||||
G1_BE_DIFF_POS_fx = 0;
|
||||
move16();
|
||||
L_G1_BE_DIFF_VAL = L_deposit_l(0);
|
||||
|
||||
FOR(j=1; j< harmonic_band_fx; j++)
|
||||
{
|
||||
IF( L_sub(L_temp_band_energydiff[j], L_G1_BE_DIFF_VAL) > 0 )
|
||||
{
|
||||
G1_BE_DIFF_POS_fx = j;
|
||||
move16();
|
||||
L_G1_BE_DIFF_VAL = L_add(0,L_temp_band_energydiff[j]);
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
||||
test();
|
||||
IF( sub(G1_BE_DIFF_POS_fx, gmax_range_fx[0] ) < 0 && G1_BE_DIFF_POS_fx > 0 )
|
||||
{
|
||||
final_gr_fact_pos_fx = 0;
|
||||
move16();
|
||||
}
|
||||
ELSE IF ( sub(G1_BE_DIFF_POS_fx, gmax_range_fx[0]) >= 0 && sub(G1_BE_DIFF_POS_fx, gmax_range_fx[1] ) < 0 )
|
||||
{
|
||||
final_gr_fact_pos_fx = 1;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
final_gr_fact_pos_fx = 2;
|
||||
move16();
|
||||
}
|
||||
|
||||
test();
|
||||
IF( final_gr_fact_pos_fx == 0 || sub(final_gr_fact_pos_fx, 1) == 0 )
|
||||
{
|
||||
IF( L_sub(L_core_brate, HQ_16k40 ) == 0 )
|
||||
{
|
||||
bits_fact_fx = BITS_FACT_1p10;
|
||||
move16(); /* 1.10f; */ /* G1 */
|
||||
bits_fact1_fx = BITS_FACT_0p92;
|
||||
move16(); /* 0.92f; */ /* G3 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
bits_fact_fx = BITS_FACT_1p05;
|
||||
move16(); /* 1.05f; */ /* G1 */
|
||||
bits_fact1_fx = BITS_FACT_0p97;
|
||||
move16(); /* 0.97f; */ /* G3 */
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
IF( L_sub(L_core_brate, HQ_16k40) == 0 )
|
||||
{
|
||||
bits_fact_fx = BITS_FACT_0p97;
|
||||
move16(); /* 0.97f; */ /* G1 */
|
||||
bits_fact1_fx = BITS_FACT_1p00;
|
||||
move16(); /* 1.00f; */ /* G3 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
bits_fact_fx = BITS_FACT_0p92;
|
||||
move16(); /* 0.92f; */ /* G1 */
|
||||
bits_fact1_fx = BITS_FACT_1p00;
|
||||
move16(); /* 1.00f; */ /* G3 */
|
||||
}
|
||||
}
|
||||
|
||||
j = sub(N_fx, harmonic_band_fx);
|
||||
FOR ( i = 0; i < j; i++ )
|
||||
{
|
||||
y_index_fx[i] = extract_h(L_shl(L_temp_band_energy[harmonic_band_fx+i], sub(16, SWB_BWE_LR_Qbe)));
|
||||
index_fx[i] = add(harmonic_band_fx, i);
|
||||
move16();
|
||||
}
|
||||
|
||||
reordvct_fx(y_index_fx, sub(N_fx, harmonic_band_fx), index_fx);
|
||||
|
||||
/* Log2 */
|
||||
L_temp = L_deposit_l(band_width_fx[index_fx[0]]);
|
||||
exp = norm_l(L_temp);
|
||||
frac = Log2_norm_lc(L_shl(L_temp, exp));
|
||||
exp = sub(30, exp);
|
||||
L_temp = L_Comp(exp, frac);
|
||||
/* ceil */
|
||||
if( L_and(0x0000ffff, L_temp) > 0 )
|
||||
{
|
||||
L_temp = L_add(L_temp, 0x00010000);
|
||||
}
|
||||
esthf_bits_fx = extract_h(L_temp);
|
||||
|
||||
L_grp_thr[0] = L_THR1;
|
||||
move32();
|
||||
L_grp_thr[1] = L_THR2;
|
||||
move32();
|
||||
L_grp_thr[2] = L_THR3;
|
||||
move32();
|
||||
L_grp_thr[3] = L_shl(L_deposit_l(esthf_bits_fx), SWB_BWE_LR_QRk);
|
||||
move16();
|
||||
|
||||
L_norm_sum = L_deposit_l(1);
|
||||
FOR(i=0; i<3; i++)
|
||||
{
|
||||
L_norm_sum = L_add( L_norm_sum, L_Ravg_sub[i]);
|
||||
}
|
||||
|
||||
/*reserve bits for HF coding */
|
||||
L_temp = L_add(L_norm_sum, L_Ravg_sub[GRP_SB-1]);
|
||||
exp_normn = norm_l(L_temp);
|
||||
exp_normn = sub(exp_normn, 1);
|
||||
exp_normd = norm_s(N_fx);
|
||||
|
||||
div_fx = div_l(L_shl(L_temp, exp_normn), shl(N_fx, exp_normd)); /* (Qbe+exp_normn)-(0+exp_normd)-1) */
|
||||
L_norm_sum_avg = L_shr(L_deposit_h(div_fx), add(sub(exp_normn, exp_normd), 15)); /* -> Qbe */
|
||||
|
||||
exp_norm = norm_l(L_norm_sum);
|
||||
norm_sum_fx = extract_h( L_shl(L_norm_sum, exp_norm) ); /* SWB_BWE_LR_Qbe+exp_norm-16 */
|
||||
Qns = sub(add(SWB_BWE_LR_Qbe, exp_norm), 16);
|
||||
|
||||
Inv_norm_sum_fx = div_s( 0x4000 /* Q15 */ , norm_sum_fx );
|
||||
QIns = sub(31, exp_norm); /* 14 - (14+exp_norm-16) + 15 */
|
||||
|
||||
grp_bit_avg_fx = div_s_ss(B_fx, GRP_SB); /* Q0 */
|
||||
|
||||
exp_normd = norm_s(p2a_bands_fx);
|
||||
Inv_p2a_bands_fx = div_s(0x3fff, shl(p2a_bands_fx, exp_normd)); /* 14-exp_normd+15 */
|
||||
QIpb = sub(29, exp_normd);
|
||||
|
||||
L_temp = L_shl(Mult_32_16(L_Ravg_sub[GRP_SB-1], Inv_p2a_bands_fx), sub(SWB_BWE_LR_Qbe, sub(QIpb,1)));
|
||||
L_norm_diff = L_sub(L_temp, L_norm_sum_avg); /* Qbe */
|
||||
|
||||
L_temp = Mult_32_16(L_Ravg_sub[GRP_SB-1], sub(GRP_SB, 1)); /* Qbe+0+1 */
|
||||
L_temp = Mult_32_16(L_temp, Inv_norm_sum_fx); /* Qbe+1+QIpb+1 */
|
||||
lf_hf_ge_r_fx = round_fx(L_shl(L_temp, sub(15+16, sub(add(SWB_BWE_LR_Qbe, QIns),30))));
|
||||
|
||||
exp_normn = norm_s(norm_sum_fx);
|
||||
exp_normn = sub(exp_normn, 1);
|
||||
exp_normd = norm_s(harmonic_band_fx);
|
||||
|
||||
div_fx = div_s(shl(norm_sum_fx, exp_normn), shl(harmonic_band_fx, exp_normd));
|
||||
L_avg_enhf_en_diff = L_sub(L_temp_band_energy[index_fx[0]], L_shl(L_deposit_h(div_fx), sub(sub(SWB_BWE_LR_Qbe, (add(Qns,sub(exp_normn,exp_normd)))),31))); /* Qbe - (Qns+exp_normn-(exp_normd)+15) -16 */
|
||||
|
||||
test();
|
||||
IF( sub(lf_hf_ge_r_fx , 26214) > 0x0 && L_sub(L_avg_enhf_en_diff, (Word32)(8<<SWB_BWE_LR_Qbe)) > 0x0L) /* 0.8=26214.4(Q15) 8.0f=131072(Qbe) */
|
||||
{
|
||||
bits_allocweigh_fx = 6554;
|
||||
move16(); /* 0.2 6553.6(Q15) */
|
||||
if(L_norm_diff < 0x0L)
|
||||
{
|
||||
bits_allocweigh_fx = 13107;
|
||||
move16(); /* 0.4 13107.2(Q15) */
|
||||
}
|
||||
|
||||
/*allocate bits*/
|
||||
/*Bits_grp[GRP_SB-1] = (short)min((grp_bit_avg/p2a_bands + bits_allocweigh*norm_diff),10);*/
|
||||
L_temp = L_mult(grp_bit_avg_fx, Inv_p2a_bands_fx); /* Q0+QIpb+1 */
|
||||
L_temp2 = Mult_32_16(L_norm_diff, bits_allocweigh_fx); /* Qbe+Q15-15 */
|
||||
|
||||
L_temp = L_shr(L_temp, add(QIpb, 1));
|
||||
L_temp = L_add(L_shl(L_temp,SWB_BWE_LR_Qbe), L_temp2);
|
||||
|
||||
Bits_grp_fx[GRP_SB-1] = extract_h(L_shl(L_temp, sub(16, SWB_BWE_LR_Qbe)));
|
||||
Bits_grp_fx[GRP_SB-1] = s_min(Bits_grp_fx[GRP_SB-1], 10);
|
||||
move16();
|
||||
|
||||
if( sub(Bits_grp_fx[GRP_SB-1], esthf_bits_fx) < 0 )
|
||||
{
|
||||
Bits_grp_fx[GRP_SB-1] = 0;
|
||||
move16();
|
||||
}
|
||||
B_fx = sub(B_fx, Bits_grp_fx[GRP_SB-1]);
|
||||
}
|
||||
|
||||
exp_shift = sub(add(SWB_BWE_LR_Qbe, QIns), 47); /* (SWB_BWE_LR_Qbe+14+1+QIns-15-16) */
|
||||
exp_norm = norm_s(B_fx);
|
||||
B_norm_fx = shl(B_fx, exp_norm);
|
||||
exp_shift = add(exp_shift, exp_norm);
|
||||
|
||||
IF( sub(final_gr_fact_pos_fx, 1) == 0 )
|
||||
{
|
||||
L_temp = Mult_32_16(L_Ravg_sub[1], extract_h(L_mult(bits_fact_fx, B_norm_fx)));
|
||||
L_temp = Mult_32_16(L_temp, Inv_norm_sum_fx);
|
||||
Bits_grp_fx[1] = extract_h(L_shr(L_temp, exp_shift));
|
||||
|
||||
L_temp = Mult_32_16(L_Ravg_sub[2], extract_h(L_mult(bits_fact1_fx, B_norm_fx)));
|
||||
L_temp = Mult_32_16(L_temp, Inv_norm_sum_fx);
|
||||
Bits_grp_fx[2] = extract_h(L_shr(L_temp, exp_shift));
|
||||
|
||||
Bits_grp_fx[0] = sub(sub(B_fx, Bits_grp_fx[1]), Bits_grp_fx[2]);
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_temp = Mult_32_16(L_Ravg_sub[0], extract_h(L_mult(bits_fact_fx, B_norm_fx)));
|
||||
L_temp = Mult_32_16(L_temp, Inv_norm_sum_fx);
|
||||
Bits_grp_fx[0] = extract_h(L_shr(L_temp, exp_shift));
|
||||
|
||||
L_temp = Mult_32_16(L_Ravg_sub[2], extract_h(L_mult(bits_fact1_fx, B_norm_fx)));
|
||||
L_temp = Mult_32_16(L_temp, Inv_norm_sum_fx);
|
||||
Bits_grp_fx[2] = extract_h(L_shr(L_temp, exp_shift));
|
||||
|
||||
Bits_grp_fx[1] = sub(sub(B_fx, Bits_grp_fx[0]), Bits_grp_fx[2]);
|
||||
move16();
|
||||
}
|
||||
|
||||
IF( sub(Bits_grp_fx[2], THR2 ) < 0 )
|
||||
{
|
||||
Bits_grp_fx[1] = add(Bits_grp_fx[1], Bits_grp_fx[2]);
|
||||
move16();
|
||||
Bits_grp_fx[2] = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR(i=0; i<GRP_SB; i++)
|
||||
{
|
||||
IF(Bits_grp_fx[i] > 0)
|
||||
{
|
||||
Bits2indvsb_fx( L_temp_band_energy, grp_bound_fx[i], grp_bound_fx[i+1] , Bits_grp_fx[i], L_grp_thr[i], L_Rsubband, p2a_flags_fx);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
set32_fx(L_Rsubband+grp_bound_fx[i], 0x0L, sub(grp_bound_fx[i+1], grp_bound_fx[i]));
|
||||
IF( sub(i, GRP_SB-1) == 0 )
|
||||
{
|
||||
set16_fx(p2a_flags_fx+grp_bound_fx[i], 0, sub(grp_bound_fx[i+1], grp_bound_fx[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* hq2_bit_alloc()
|
||||
*
|
||||
* HQ2 bit-allocation
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
Word32 hq2_bit_alloc_fx (
|
||||
const Word32 L_band_energy[], /* i : band energy of each subband */
|
||||
const Word16 bands, /* i : total number of subbands in a frame */
|
||||
Word32 L_Rk[], /* i/o: Bit allocation/Adjusted bit alloc. */
|
||||
Word16 *bit_budget_fx, /* i/o: bit bugdet */
|
||||
Word16 *p2a_flags, /* i : HF tonal indicator */
|
||||
const Word16 weight_fx, /* i : weight */
|
||||
const Word16 band_width[], /* i : Sub band bandwidth */
|
||||
const Word16 num_bits, /* i : available bits */
|
||||
const Word16 hqswb_clas, /* i : HQ2 class information */
|
||||
const Word16 bwidth, /* i : input bandwidth */
|
||||
const Word16 is_transient /* i : indicator HQ_TRANSIENT or not */
|
||||
)
|
||||
{
|
||||
Word16 j, k;
|
||||
Word16 tmp;
|
||||
Word16 bit_budget_norm_fx;
|
||||
|
||||
Word32 L_Rcalc, L_Ravg, L_Rcalc1;
|
||||
|
||||
Word16 exp_normn, exp_normd;
|
||||
|
||||
Word16 Rcnt_fx;
|
||||
|
||||
Word16 div_fx;
|
||||
Word16 Qdiv;
|
||||
|
||||
Word32 L_tmp;
|
||||
Word16 tmp_fx;
|
||||
|
||||
Word32 L_maxxy;
|
||||
Word16 maxdex_fx;
|
||||
Word32 L_dummy;
|
||||
|
||||
Word16 bit_budget_temp_fx;
|
||||
|
||||
Word16 negflag;
|
||||
|
||||
Word32 L_THR1, L_THR2, L_THR3;
|
||||
|
||||
L_THR1 = L_shl(L_deposit_l(THR1), SWB_BWE_LR_QRk);
|
||||
L_THR2 = L_shl(L_deposit_l(THR2), SWB_BWE_LR_QRk);
|
||||
L_THR3 = L_shl(L_deposit_l(THR3), SWB_BWE_LR_QRk);
|
||||
|
||||
/* Init Rk to non-zero values for bands to be allocated bits */
|
||||
IF( sub(num_bits, HQ_16k40_BIT) <= 0 )
|
||||
{
|
||||
set32_fx( L_Rk, (Word32)(C1_QRk), bands); /* 1<<SWB_BWE_LR_QRk */
|
||||
|
||||
test();
|
||||
IF( is_transient && sub(bands, 32) == 0 )
|
||||
{
|
||||
L_Rk[6] = L_deposit_l(0);
|
||||
L_Rk[7] = L_deposit_l(0);
|
||||
L_Rk[14] = L_deposit_l(0);
|
||||
L_Rk[15] = L_deposit_l(0);
|
||||
L_Rk[22] = L_deposit_l(0);
|
||||
L_Rk[23] = L_deposit_l(0);
|
||||
L_Rk[30] = L_deposit_l(0);
|
||||
L_Rk[31] = L_deposit_l(0);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/*mvs2r( p2a_flags, Rk, bands ); */
|
||||
FOR(k=0; k<bands; k++)
|
||||
{
|
||||
L_Rk[k] = L_shl(L_deposit_l(p2a_flags[k]), SWB_BWE_LR_QRk);
|
||||
}
|
||||
}
|
||||
|
||||
L_Rcalc = L_deposit_l(0);
|
||||
L_Rcalc1 = L_deposit_l(0);
|
||||
|
||||
FOR (j = 0; j < bands; j++)
|
||||
{
|
||||
Rcnt_fx = 0;
|
||||
move16();
|
||||
L_Ravg = L_add(0,0x0L);
|
||||
|
||||
FOR (k = 0; k < bands; k++)
|
||||
{
|
||||
IF ( L_Rk[k] > 0 )
|
||||
{
|
||||
L_Ravg = L_add(L_Ravg, L_shl(L_band_energy[k], sub(SWB_BWE_LR_QRk, SWB_BWE_LR_Qbe))); /* SWB_BWE_LR_QRk-SWB_BWE_LR_Qbe */
|
||||
Rcnt_fx = add(Rcnt_fx, 1);
|
||||
}
|
||||
}
|
||||
/* Ravg Qband_energy */
|
||||
|
||||
/*L_Ravg /= Rcnt; */
|
||||
exp_normd = norm_l(L_Ravg);
|
||||
exp_normd = sub(exp_normd, 1);
|
||||
exp_normn = norm_s(Rcnt_fx);
|
||||
|
||||
tmp = shl(Rcnt_fx, exp_normn);
|
||||
tmp = s_max(tmp,1);
|
||||
IF ( L_Ravg > 0 )
|
||||
{
|
||||
div_fx = div_l(L_shl(L_Ravg, exp_normd), tmp); /* Qdiv = 14+exp_normd-(exp_normn)-1 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
div_fx = div_l(L_shl(L_abs(L_Ravg), exp_normd), tmp); /* Qdiv = 14+exp_normd-(exp_normn)-1 */
|
||||
div_fx = negate(div_fx);
|
||||
}
|
||||
|
||||
Qdiv = sub(sub(add(SWB_BWE_LR_QRk, exp_normd), exp_normn), 1);
|
||||
|
||||
L_Ravg = L_shr(L_deposit_l(div_fx), sub(Qdiv, SWB_BWE_LR_QRk));
|
||||
|
||||
exp_normd = norm_s(*bit_budget_fx);
|
||||
exp_normd = sub(exp_normd, 1);
|
||||
bit_budget_norm_fx = shl(*bit_budget_fx, exp_normd);
|
||||
div_fx = 0;
|
||||
move16();
|
||||
|
||||
test();
|
||||
IF( bit_budget_norm_fx > 0 && sub(bit_budget_norm_fx, tmp) < 0 )
|
||||
{
|
||||
div_fx = div_s(bit_budget_norm_fx, tmp);
|
||||
}
|
||||
Qdiv = add(sub(exp_normd, exp_normn), 15);
|
||||
FOR (k = 0; k < bands; k++)
|
||||
{
|
||||
IF ( L_Rk[k] > 0)
|
||||
{
|
||||
/*Rk[k] = ((float) *bit_budget / Rcnt + weight * (band_energy[k] - Ravg)); */
|
||||
|
||||
L_tmp = Mult_32_16(L_sub(L_shl(L_band_energy[k], sub(SWB_BWE_LR_QRk, SWB_BWE_LR_Qbe)), L_Ravg), weight_fx); /* SWB_BWE_LR_QRk + Q13 - 15 */
|
||||
L_tmp = L_shl(L_tmp, 2); /* -> SWB_BWE_LR_QRk */
|
||||
|
||||
L_Rk[k] = L_add(L_shr(L_deposit_l(div_fx), sub(Qdiv, SWB_BWE_LR_QRk)) , L_tmp);
|
||||
move32();
|
||||
}
|
||||
}
|
||||
|
||||
negflag = 0;
|
||||
move16();
|
||||
L_Rcalc = L_deposit_l(0);
|
||||
FOR (k = 0; k < bands; k++)
|
||||
{
|
||||
IF ( L_sub(L_Rk[k], MIN_BITS_FIX) < 0 )
|
||||
{
|
||||
L_Rk[k] = L_deposit_l(0);
|
||||
negflag = 1;
|
||||
move16();
|
||||
}
|
||||
L_Rcalc = L_add( L_Rcalc , L_Rk[k]); /*SWB_BWE_LR_QRk */
|
||||
}
|
||||
|
||||
/* prune noiselike bands with low allocation */
|
||||
test();
|
||||
IF ( sub(num_bits, HQ_16k40_BIT) <= 0 && negflag == 0)
|
||||
{
|
||||
L_maxxy = L_deposit_l(0);
|
||||
maxdex_fx = -1;
|
||||
move16();
|
||||
L_Rcalc = L_deposit_l(0);
|
||||
|
||||
/* find worst under-allocation */
|
||||
FOR (k = sub(bands, 1); k >= 0; k--)
|
||||
{
|
||||
tmp_fx = s_min( band_width[k], s_max(12, shr( band_width[k], 2)));
|
||||
L_dummy = L_sub(L_shl(L_deposit_l(tmp_fx), SWB_BWE_LR_QRk), L_Rk[k]) ; /*SWB_BWE_LR_QRk */
|
||||
test();
|
||||
test();
|
||||
IF ( p2a_flags[k] == 0 && L_sub(L_dummy, L_maxxy) > 0 && L_Rk[k] > 0 )
|
||||
{
|
||||
maxdex_fx = k;
|
||||
move16();
|
||||
L_maxxy = L_add(0,L_dummy); /*SWB_BWE_LR_QRk */
|
||||
}
|
||||
}
|
||||
|
||||
/* prune worst allocation and recalculate total allocation */
|
||||
if ( sub(maxdex_fx, -1) > 0)
|
||||
{
|
||||
L_Rk[maxdex_fx] = L_deposit_l(0);
|
||||
}
|
||||
FOR (k = 0; k < bands; k++)
|
||||
{
|
||||
L_Rcalc = L_add(L_Rcalc, L_Rk[k]); /*SWB_BWE_LR_QRk */
|
||||
}
|
||||
}
|
||||
test();
|
||||
test();
|
||||
IF ( L_sub(L_Rcalc, L_Rcalc1) == 0 && sub(bwidth, SWB) == 0 )
|
||||
{
|
||||
/* Reallocate bits to individual subbands for HQ_NORMAL mode */
|
||||
/* if bits allocated to subbands areless than predefined threshold */
|
||||
test();
|
||||
IF( sub(hqswb_clas, HQ_NORMAL) == 0 && sub(num_bits, HQ_16k40_BIT) < 0 )
|
||||
{
|
||||
L_dummy = L_deposit_l(0);
|
||||
FOR( k = 0; k < bands; k++ )
|
||||
{
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF( sub(k, 11) < 0 && L_sub(L_Rk[k], L_THR1) < 0 )
|
||||
{
|
||||
L_Rk[k] = L_deposit_l(0);
|
||||
}
|
||||
ELSE IF( sub(k, 11) >= 0 && sub(k, 16) < 0 && L_sub(L_Rk[k], L_THR2) < 0 )
|
||||
{
|
||||
L_Rk[k] = L_deposit_l(0);
|
||||
}
|
||||
ELSE if( sub(k, 16) >= 0 && sub(k, bands ) < 0 && L_sub(L_Rk[k], L_THR3) < 0 )
|
||||
{
|
||||
L_Rk[k] = L_deposit_l(0);
|
||||
}
|
||||
|
||||
L_dummy = L_add(L_dummy, L_Rk[k]);
|
||||
}
|
||||
|
||||
IF( L_sub(L_dummy, L_Rcalc ) == 0 )
|
||||
{
|
||||
test();
|
||||
IF( sub(hqswb_clas, HQ_NORMAL) == 0 && sub(num_bits, HQ_16k40_BIT) < 0)
|
||||
{
|
||||
bit_budget_temp_fx = *bit_budget_fx;
|
||||
move16();
|
||||
FOR( k=0; k<NB_SWB_SUBBANDS; k++ )
|
||||
{
|
||||
test();
|
||||
IF( p2a_flags[bands-NB_SWB_SUBBANDS+k] == 1 && L_Rk[bands-NB_SWB_SUBBANDS+k] == 0 )
|
||||
{
|
||||
p2a_flags[bands-NB_SWB_SUBBANDS+k] = 0;
|
||||
move16();
|
||||
bit_budget_temp_fx = sub(bit_budget_temp_fx, bits_lagIndices_modeNormal_fx[k]);
|
||||
}
|
||||
}
|
||||
|
||||
IF( sub(bit_budget_temp_fx, *bit_budget_fx ) < 0)
|
||||
{
|
||||
*bit_budget_fx = bit_budget_temp_fx;
|
||||
move16();
|
||||
/* a negative *bit_budget_fx may occur here due to Bit Errors */
|
||||
/* handled outside this function to properly set flag: st_fx->BER_detect */
|
||||
}
|
||||
ELSE IF( sub(bit_budget_temp_fx, *bit_budget_fx ) == 0 )
|
||||
{
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
ELSE IF ( L_sub(L_Rcalc, L_Rcalc1 ) == 0 && sub(bwidth, SWB) != 0)
|
||||
{
|
||||
BREAK;
|
||||
}
|
||||
|
||||
L_Rcalc1 = L_Rcalc;
|
||||
move32();
|
||||
|
||||
}
|
||||
|
||||
return L_Rcalc;
|
||||
}
|
||||
|
||||
Executable
+770
@@ -0,0 +1,770 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "cnst_fx.h" /* Audio core constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
#include "basop_mpy.h"
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* mdct_spectrum_denorm()
|
||||
*
|
||||
*
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void mdct_spectrum_denorm_fx(
|
||||
const Word16 inp_vector[], /* i : Q0 : */
|
||||
Word32 L_y2[], /* i/o : Qs : decoded spectrum */
|
||||
const Word16 band_start[], /* i : Q0 : table of start freq for every subband */
|
||||
const Word16 band_end[], /* i : Q0 : table of end freq for every subband */
|
||||
const Word16 band_width[], /* i : Q0 : table of bandwidth for every subband */
|
||||
const Word32 L_band_energy[], /* i : Qbe : band energy */
|
||||
const Word16 npulses[], /* i : Q0 : number of coded spectrum */
|
||||
const Word16 bands, /* i : Q0 : number of subbands */
|
||||
const Word16 ld_slope_fx, /* i : Q15 : */
|
||||
const Word16 pd_thresh_fx /* i : Q15 : */
|
||||
)
|
||||
{
|
||||
Word16 i, k;
|
||||
Word32 L_Eyy;
|
||||
Word32 L_tmp, L_temp;
|
||||
Word16 temp_fx, temp_lo_fx, temp_hi_fx;
|
||||
Word32 L_inp_tmp[L_FRAME48k];
|
||||
Word16 exp_norm;
|
||||
Word16 exp_safe;
|
||||
Word16 exp_normn, exp_normd;
|
||||
|
||||
Word16 pd_fx;
|
||||
Word16 Qpd;
|
||||
|
||||
Word16 div_pd_fx;
|
||||
Word16 Qdivpd;
|
||||
Word32 L_div_pd;
|
||||
|
||||
Word16 frac, exp;
|
||||
|
||||
Word16 gain_tweak_fx;
|
||||
Word16 Qtweak;
|
||||
|
||||
Word16 exp_shift;
|
||||
|
||||
Word16 QEyy;
|
||||
Word16 pow_fx;
|
||||
Word16 Qpow;
|
||||
Word16 Qdiv;
|
||||
Word16 Qgamma;
|
||||
Word16 gamma_fx;
|
||||
|
||||
Word16 cond_fx;
|
||||
|
||||
exp_safe = 4; /* safe bit for overflow */
|
||||
|
||||
FOR (k = 0; k < bands; k++)
|
||||
{
|
||||
L_tmp = L_deposit_l(0);
|
||||
FOR (i = band_start[k]; i <= band_end[k]; i++)
|
||||
{
|
||||
L_inp_tmp[i] = L_mult(inp_vector[i], inp_vector[i]);
|
||||
move32(); /* Q0+Q0+1 */
|
||||
L_tmp = L_or(L_tmp, L_inp_tmp[i]);
|
||||
}
|
||||
exp_norm = norm_l(L_tmp);
|
||||
exp_norm = sub(exp_norm, exp_safe);
|
||||
|
||||
L_Eyy = L_deposit_l(0);
|
||||
FOR (i = band_start[k]; i <= band_end[k]; i++)
|
||||
{
|
||||
/*Eyy += (float) inp_vector[i] * inp_vector[i]; */
|
||||
L_Eyy = L_add(L_Eyy, L_shl(L_inp_tmp[i], exp_norm)); /* Q1+exp_norm */
|
||||
}
|
||||
QEyy = add(1, exp_norm);
|
||||
|
||||
IF ( L_Eyy > 0x0L )
|
||||
{
|
||||
/* Set gamma to be pulse gain which results in perfect quantized subband energy */
|
||||
/*gamma = (float) sqrt (pow (2.0f, band_energy[k]) / Eyy); */
|
||||
|
||||
/* Pow part (pow(2.0f, band_energy) ) */
|
||||
L_temp = L_shr(L_band_energy[k], sub(SWB_BWE_LR_Qbe, 16));
|
||||
temp_lo_fx = L_Extract_lc(L_temp, &temp_hi_fx);
|
||||
Qpow = sub(14, temp_hi_fx);
|
||||
pow_fx = extract_l(Pow2(14, temp_lo_fx)); /* Qpow */
|
||||
|
||||
/* Div part ( pow (2.0f, band_energy[i])/Eyy ) */
|
||||
exp_normn = norm_s(pow_fx);
|
||||
exp_normn = sub(exp_normn, 1);
|
||||
exp_normd = norm_l(L_Eyy);
|
||||
temp_fx = div_s( shl( pow_fx, exp_normn), extract_h(L_shl(L_Eyy, exp_normd)));
|
||||
Qdiv = add(sub(add(Qpow, exp_normn) , add(QEyy, exp_normd)), 31);
|
||||
|
||||
exp_norm = norm_s(temp_fx);
|
||||
temp_fx = shl(temp_fx, exp_norm);
|
||||
Qdiv = add(Qdiv, exp_norm);
|
||||
|
||||
/* Sqrt part sqrt(pow (2.0f, band_energy[i])/Eyy) */
|
||||
Qgamma = add(Qdiv, 16);
|
||||
IF ( s_and(Qdiv, 1) == 0 ) /* Qdiv % 2 == 0 */
|
||||
{
|
||||
L_temp = Sqrt_l(L_shr(L_deposit_h(temp_fx),1), &exp_norm);
|
||||
L_temp = L_shr(L_temp, exp_norm);
|
||||
Qgamma = sub(shr(Qgamma, 1), 1);
|
||||
gamma_fx = round_fx(L_temp);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_temp = Sqrt_l(L_deposit_h(temp_fx), &exp_norm);
|
||||
L_temp = L_shr(L_temp, exp_norm);
|
||||
Qgamma = shr(Qgamma, 1);
|
||||
gamma_fx = round_fx(L_temp);
|
||||
}
|
||||
|
||||
/* Adjust gamma based on pulse density (0 bit MSE gain estimator) */
|
||||
/*pd = (float) npulses[k] / band_width[k]; */
|
||||
exp_normn = norm_s(npulses[k]);
|
||||
exp_normn = sub(exp_normn, 1);
|
||||
exp_normd = norm_s(band_width[k]);
|
||||
pd_fx = div_s(shl(npulses[k],exp_normn), shl(band_width[k], exp_normd));
|
||||
Qpd = add(sub(exp_normn, exp_normd), 15);
|
||||
|
||||
cond_fx = sub(shl(pd_fx, sub(15, Qpd)), pd_thresh_fx/*Q15*/);
|
||||
Overflow = 0;
|
||||
move16(); /* allow overflow happen. */
|
||||
IF ( cond_fx < 0 )
|
||||
{
|
||||
/*gain_tweak = (float) pow (2.0f, (ld_slope * log2_f (pd / pd_thresh))); */
|
||||
/* Div part */
|
||||
exp_normn = norm_s(pd_fx);
|
||||
exp_normn = sub(exp_normn, 1);
|
||||
exp_normd = norm_s(pd_thresh_fx);
|
||||
div_pd_fx = div_s(shl(pd_fx, exp_normn), shl(pd_thresh_fx, exp_normd)); /* Qpd+exp_normn - (15 + exp_normd) + 15 */
|
||||
Qdivpd = add(sub(add(Qpd, exp_normn), add(15, exp_normd)), 15);
|
||||
|
||||
/* Log2 part */
|
||||
exp_norm = norm_s(div_pd_fx);
|
||||
L_div_pd = L_deposit_h(shl(div_pd_fx, exp_norm));
|
||||
Qdivpd = add(add(Qdivpd, exp_norm), 16);
|
||||
|
||||
frac = Log2_norm_lc(L_div_pd);
|
||||
exp = sub(30, Qdivpd);
|
||||
L_tmp = L_Comp(exp, frac); /* Q16 */
|
||||
|
||||
/* Mult part */
|
||||
L_tmp = Mpy_32_16_1(L_tmp, ld_slope_fx);
|
||||
|
||||
/* Pow part */
|
||||
temp_lo_fx = L_Extract_lc(L_tmp, &temp_hi_fx);
|
||||
Qtweak = sub(14, temp_hi_fx);
|
||||
gain_tweak_fx = extract_l(Pow2(14, temp_lo_fx));
|
||||
|
||||
/*gamma *= gain_tweak; */
|
||||
L_tmp = L_mult(gamma_fx, gain_tweak_fx); /* Qgamma+Qtweak+1 */
|
||||
exp_norm = norm_l(L_tmp);
|
||||
gamma_fx = round_fx(L_shl(L_tmp, exp_norm));
|
||||
Qgamma = sub(add(add(Qgamma, Qtweak), exp_norm), 15);/*Qgamma+Qtweak+1+exp_norm-16; */
|
||||
}
|
||||
|
||||
exp_shift = sub(SWB_BWE_LR_Qs-1, Qgamma);
|
||||
FOR (i = band_start[k]; i <= band_end[k]; i++)
|
||||
{
|
||||
/*y2[i] = gamma * inp_vector[i]; */
|
||||
L_tmp = L_mult(gamma_fx, (Word16)inp_vector[i]); /* Qgamma+0+1=Qgamma+1 */
|
||||
L_y2[i] = L_shl(L_tmp, exp_shift);
|
||||
move32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*==========================================================================*/
|
||||
/* FUNCTION : void hq2_core_configure_fx() */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* PURPOSE : */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* Word16 *qint o: Q13 */
|
||||
/* Word16 *eref o: Q10 */
|
||||
/* Word16 *bit_alloc_weight o: Q13 */
|
||||
/* Word16 *p2a_th o: Q11 */
|
||||
/* Word16 *pd_thresh o: Q15 */
|
||||
/* Word16 *ld_slope o: Q15 */
|
||||
/* Word16 *ni_coef o: Q14 */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* CALLED FROM : */
|
||||
/*==========================================================================*/
|
||||
|
||||
void hq2_core_configure_fx (
|
||||
const Word16 frame_length,
|
||||
const Word16 num_bits,
|
||||
const Word16 is_transient,
|
||||
Word16 *bands,
|
||||
Word16 *length,
|
||||
Word16 band_width[],
|
||||
Word16 band_start[],
|
||||
Word16 band_end[],
|
||||
Word32 *L_qint,
|
||||
Word16 *eref,
|
||||
Word16 *bit_alloc_weight,
|
||||
Word16 *gqlevs,
|
||||
Word16 *Ngq,
|
||||
Word16 *p2a_bands,
|
||||
Word16 *p2a_th,
|
||||
Word16 *pd_thresh,
|
||||
Word16 *ld_slope,
|
||||
Word16 *ni_coef,
|
||||
Word32 L_bwe_br
|
||||
)
|
||||
{
|
||||
const Xcore_Config_fx *xcore_config_fx;
|
||||
|
||||
Word16 i, k;
|
||||
Word16 bands_sh;
|
||||
|
||||
xcore_config_fx = &xcore_config_32kHz_013200bps_long_fx; /* default set for VC Warning */
|
||||
|
||||
IF ( sub(frame_length, L_FRAME8k) == 0 )
|
||||
{
|
||||
IF( is_transient )
|
||||
{
|
||||
IF ( sub(num_bits, ACELP_7k20 / 50) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_8kHz_007200bps_short_fx;
|
||||
}
|
||||
ELSE IF ( sub(num_bits, ACELP_8k00 / 50) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_8kHz_008000bps_short_fx;
|
||||
}
|
||||
ELSE IF ( sub(num_bits, ACELP_13k20 / 50) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_8kHz_013200bps_short_fx;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
xcore_config_fx = &xcore_config_8kHz_016400bps_short_fx;
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
IF ( sub(num_bits, ACELP_7k20 / 50) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_8kHz_007200bps_long_fx;
|
||||
}
|
||||
ELSE IF ( sub(num_bits, ACELP_8k00 / 50) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_8kHz_008000bps_long_fx;
|
||||
}
|
||||
ELSE IF ( sub(num_bits, ACELP_13k20 / 50) <= 0)
|
||||
{
|
||||
xcore_config_fx = &xcore_config_8kHz_013200bps_long_fx;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
xcore_config_fx = &xcore_config_8kHz_016400bps_long_fx;
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE IF ( sub(frame_length, L_FRAME16k) == 0 )
|
||||
{
|
||||
IF (is_transient)
|
||||
{
|
||||
IF ( sub(num_bits, ACELP_13k20 / 50) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_16kHz_013200bps_short_fx;
|
||||
move16();
|
||||
}
|
||||
ELSE if ( sub(num_bits, ACELP_16k40 / 50) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_16kHz_016400bps_short_fx;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
IF ( sub(num_bits, ACELP_13k20 / 50) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_16kHz_013200bps_long_fx;
|
||||
move16();
|
||||
}
|
||||
ELSE if ( sub(num_bits, ACELP_16k40 / 50) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_16kHz_016400bps_long_fx;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE /* (frame_length == SWB) */
|
||||
{
|
||||
IF (is_transient)
|
||||
{
|
||||
IF ( L_sub(L_bwe_br, ACELP_13k20) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_32kHz_013200bps_short_fx;
|
||||
move16();
|
||||
}
|
||||
ELSE if ( L_sub(L_bwe_br, ACELP_16k40) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_32kHz_016400bps_short_fx;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
IF ( L_sub(L_bwe_br, ACELP_13k20) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_32kHz_013200bps_long_fx;
|
||||
move16();
|
||||
}
|
||||
ELSE if ( L_sub(L_bwe_br, ACELP_16k40) <= 0 )
|
||||
{
|
||||
xcore_config_fx = &xcore_config_32kHz_016400bps_long_fx;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*bands = xcore_config_fx->bands;
|
||||
move16();
|
||||
*length = xcore_config_fx->bw;
|
||||
move16();
|
||||
*L_qint = xcore_config_fx->L_qint;
|
||||
move32();
|
||||
|
||||
*eref = xcore_config_fx->eref;
|
||||
move16();
|
||||
*bit_alloc_weight = xcore_config_fx->bit_alloc_weight;
|
||||
move16();
|
||||
*gqlevs = xcore_config_fx->gqlevs;
|
||||
move16();
|
||||
*Ngq = xcore_config_fx->Ngq;
|
||||
move16();
|
||||
|
||||
*p2a_bands = xcore_config_fx->p2a_bands;
|
||||
move16();
|
||||
*p2a_th = xcore_config_fx->p2a_th;
|
||||
move16();
|
||||
|
||||
*pd_thresh = xcore_config_fx->pd_thresh;
|
||||
move16();
|
||||
*ld_slope = xcore_config_fx->ld_slope;
|
||||
move16();
|
||||
*ni_coef = xcore_config_fx->ni_coef;
|
||||
move16();
|
||||
|
||||
/*mvs2s_fx (xcore_config_fx->band_width, band_width, *bands); */
|
||||
Copy(xcore_config_fx->band_width, band_width, *bands);
|
||||
|
||||
/* Expand band_width[] table for short windows */
|
||||
IF (is_transient)
|
||||
{
|
||||
bands_sh = *bands;
|
||||
move16();
|
||||
*bands = shl(bands_sh,2);
|
||||
*length = shl(*length, 2);
|
||||
|
||||
FOR (i = 1; i <= 3; i++)
|
||||
{
|
||||
FOR (k = 0; k < bands_sh; k++)
|
||||
{
|
||||
band_width[i * bands_sh + k] = band_width[k];
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Formulate band_start and band_end tables from band_width table */
|
||||
band_start[0] = 0;
|
||||
move16();
|
||||
band_end[0] = sub(band_width[0], 1);
|
||||
move16();
|
||||
FOR (k = 1; k < *bands; k++)
|
||||
{
|
||||
band_start[k] = add( band_start[k - 1] , band_width[k - 1]);
|
||||
move16();
|
||||
band_end[k] = sub(add( band_start[k] , band_width[k]) , 1);
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* reverse_transient_frame_energies()
|
||||
*
|
||||
*
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void reverse_transient_frame_energies_fx(
|
||||
Word32 L_band_energy[], /* o : Q14 : band energies */
|
||||
const Word16 bands /* i : Q0 : number of bands */
|
||||
)
|
||||
{
|
||||
Word16 k, k1, k2;
|
||||
Word32 L_be;
|
||||
Word16 bands_2, bands_4, bands_8;
|
||||
Word32 *p_be1, *p_be2;
|
||||
|
||||
bands_2 = shr(bands, 1);
|
||||
bands_4 = shr(bands, 2);
|
||||
bands_8 = shr(bands, 3);
|
||||
|
||||
k1 = bands_4;
|
||||
k2 = sub(bands_2, 1);
|
||||
p_be1 = &L_band_energy[k1];
|
||||
p_be2 = &L_band_energy[k2];
|
||||
FOR( k = 0; k < bands_8; k++ )
|
||||
{
|
||||
L_be = *p_be1;
|
||||
move32();
|
||||
*p_be1 = *p_be2;
|
||||
move32();
|
||||
*p_be2 = L_be;
|
||||
move32();
|
||||
p_be1++;
|
||||
p_be2--;
|
||||
}
|
||||
|
||||
k1 = sub(bands, bands_4); /* 3*bands/4 */
|
||||
k2 = sub(bands, 1);
|
||||
p_be1 = &L_band_energy[k1];
|
||||
p_be2 = &L_band_energy[k2];
|
||||
FOR( k = 0; k < bands_8; k++ )
|
||||
{
|
||||
L_be = *p_be1;
|
||||
move32();
|
||||
*p_be1 = *p_be2;
|
||||
move32();
|
||||
*p_be2 = L_be;
|
||||
move32();
|
||||
p_be1++;
|
||||
p_be2--;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* spt_shorten_domain_pre()
|
||||
*
|
||||
* Compute shorten subband if previous frame has spectral peak.
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void spt_shorten_domain_pre_fx(
|
||||
const Word16 band_start[], /* i: Starting position of sub band */
|
||||
const Word16 band_end[], /* i: End position of sub band */
|
||||
const Word16 prev_SWB_peak_pos[], /* i: Spectral peak */
|
||||
const Word16 BANDS, /* i: total number of bands */
|
||||
const Word32 L_bwe_br, /* i: bitrate information */
|
||||
Word16 new_band_start[], /* o: Starting position of new shorten sub band */
|
||||
Word16 new_band_end[], /* o: End position of new shorten sub band */
|
||||
Word16 new_band_width[] /* o: new sub band bandwidth */
|
||||
)
|
||||
{
|
||||
Word16 j;
|
||||
Word16 k;
|
||||
Word16 kpos;
|
||||
|
||||
Word16 new_band_width_half;
|
||||
const Word16 *p_bw_SPT_tbl; /* pointer of bw_SPT_tbl */
|
||||
|
||||
p_bw_SPT_tbl = bw_SPT_tbl[0];
|
||||
if( L_sub(L_bwe_br, HQ_16k40) == 0 )
|
||||
{
|
||||
p_bw_SPT_tbl = bw_SPT_tbl[1];
|
||||
}
|
||||
|
||||
kpos = 0;
|
||||
j = 0;
|
||||
move16();
|
||||
FOR(k=sub(BANDS,SPT_SHORTEN_SBNUM); k<BANDS; k++)
|
||||
{
|
||||
IF ( prev_SWB_peak_pos[kpos] != 0)
|
||||
{
|
||||
new_band_width[j] = p_bw_SPT_tbl[j];
|
||||
|
||||
/*shorten the bandwidth for pulse resolution*/
|
||||
new_band_width_half = shr(new_band_width[j], 1);
|
||||
move16();
|
||||
new_band_start[j] = sub(prev_SWB_peak_pos[kpos], new_band_width_half);
|
||||
move16();
|
||||
new_band_end[j] = add(prev_SWB_peak_pos[kpos], new_band_width_half);
|
||||
move16();
|
||||
|
||||
IF( sub(new_band_start[j], band_start[k]) < 0 )
|
||||
{
|
||||
new_band_start[j] = band_start[k];
|
||||
move16();
|
||||
new_band_end[j] = add(new_band_start[j], sub(new_band_width[j],1));
|
||||
move16();
|
||||
}
|
||||
ELSE IF ( sub(new_band_end[j], band_end[k]) > 0 )
|
||||
{
|
||||
new_band_end[j] = band_end[k];
|
||||
move16();
|
||||
new_band_start[j] = sub(new_band_end[j], sub(new_band_width[j],1));
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
new_band_width[j] = p_bw_SPT_tbl[j];
|
||||
|
||||
/*shorten the bandwidth for pulse resolution*/
|
||||
new_band_width_half = shr(new_band_width[j], 1);
|
||||
move16();
|
||||
new_band_start[j] = sub(shr(add(band_start[k], band_end[k]), 1), new_band_width_half);
|
||||
move16();
|
||||
new_band_end[j] = add(shr(add(band_start[k], band_end[k]), 1), new_band_width_half);
|
||||
move16();
|
||||
}
|
||||
|
||||
kpos = add(kpos, 1);
|
||||
j = add(j, 1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* spt_shorten_domain_band_save()
|
||||
*
|
||||
* Store the original subband information
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void spt_shorten_domain_band_save_fx(
|
||||
const Word16 bands, /* i: total subband */
|
||||
const Word16 band_start[], /* i: starting position of subband */
|
||||
const Word16 band_end[], /* i: end position of subband */
|
||||
const Word16 band_width[], /* i: band width of subband */
|
||||
Word16 org_band_start[], /* o: starting position of subband */
|
||||
Word16 org_band_end[], /* o: end position of subband */
|
||||
Word16 org_band_width[] /* o: band width of subband */
|
||||
)
|
||||
{
|
||||
Word16 k;
|
||||
Word16 kpos;
|
||||
|
||||
kpos = 0;
|
||||
move16();
|
||||
FOR(k=sub(bands,SPT_SHORTEN_SBNUM); k<bands; k++)
|
||||
{
|
||||
org_band_start[kpos] = band_start[k];
|
||||
move16();
|
||||
org_band_end[kpos] = band_end[k];
|
||||
move16();
|
||||
org_band_width[kpos] = band_width[k];
|
||||
move16();
|
||||
kpos = add(kpos, 1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* spt_shorten_domain_band_restore()
|
||||
*
|
||||
* Restrore the subband information
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void spt_shorten_domain_band_restore_fx(
|
||||
const Word16 bands, /* i: total subband */
|
||||
Word16 band_start[], /* i/o: starting position of subband */
|
||||
Word16 band_end[], /* i/o: end position of subband */
|
||||
Word16 band_width[], /* i/o: band width of subband */
|
||||
const Word16 org_band_start[], /* o: starting position of subband */
|
||||
const Word16 org_band_end[], /* o: end position of subband */
|
||||
const Word16 org_band_width[] /* o: band width of subband */
|
||||
)
|
||||
{
|
||||
Word16 k;
|
||||
Word16 kpos;
|
||||
|
||||
kpos = 0;
|
||||
move16();
|
||||
FOR(k=sub(bands,SPT_SHORTEN_SBNUM); k<bands; k++)
|
||||
{
|
||||
band_start[k] = org_band_start[kpos];
|
||||
move16();
|
||||
band_end[k] = org_band_end[kpos];
|
||||
move16();
|
||||
band_width[k] = org_band_width[kpos];
|
||||
move16();
|
||||
kpos = add(kpos, 1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* spt_swb_peakpos_tmp_save
|
||||
*
|
||||
* Save Peak position for every higher subband
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void spt_swb_peakpos_tmp_save_fx(
|
||||
const Word32 L_y2[], /* i: coded spectral information */
|
||||
const Word16 bands, /* i: total number of bands */
|
||||
const Word16 band_start[], /* i: starting position of subband */
|
||||
const Word16 band_end[], /* i: end position of subband */
|
||||
Word16 prev_SWB_peak_pos_tmp[] /* o: spectral peaks */
|
||||
)
|
||||
{
|
||||
|
||||
Word16 i, j, k;
|
||||
Word32 L_peak_max;
|
||||
Word32 L_abs_y2;
|
||||
|
||||
j = 0;
|
||||
move16();
|
||||
FOR(k=sub(bands, SPT_SHORTEN_SBNUM); k<bands; k++)
|
||||
{
|
||||
L_peak_max = L_deposit_l(0);
|
||||
prev_SWB_peak_pos_tmp[j] = 0;
|
||||
move16();
|
||||
FOR(i=band_start[k]; i<=band_end[k]; i++)
|
||||
{
|
||||
L_abs_y2 = L_abs(L_y2[i]);
|
||||
move32();
|
||||
IF( L_sub( L_peak_max, L_abs_y2) < 0x0L )
|
||||
{
|
||||
L_peak_max = L_abs_y2;
|
||||
move32();
|
||||
prev_SWB_peak_pos_tmp[j] = i;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
j = add(j, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void bit_allocation_second_fx(
|
||||
Word32 *Rk,
|
||||
Word32 *Rk_sort,
|
||||
Word16 BANDS,
|
||||
const Word16 *band_width,
|
||||
Word16 *k_sort,
|
||||
Word16 *k_num,
|
||||
const Word16 *p2a_flags,
|
||||
const Word16 p2a_bands,
|
||||
const Word16 *last_bitalloc,
|
||||
const Word16 input_frame
|
||||
)
|
||||
{
|
||||
Word16 k, k2 = 0;
|
||||
Word16 ever_bits[BANDS_MAX], ever_sort[BANDS_MAX];/*Q12 */
|
||||
Word16 class_flag = 0;
|
||||
Word16 rk_temp = 32767, ever_temp = 32767;/*Q12 */
|
||||
Word16 exp;
|
||||
Word16 tmp;
|
||||
Word32 L_tmp;
|
||||
|
||||
FOR (k = 0; k < BANDS; k++)
|
||||
{
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF((( sub(k_sort[k],sub(BANDS,p2a_bands)) >= 0 )&&( sub(p2a_flags[k_sort[k]],1) == 0 )) ||
|
||||
(( sub(k_sort[k],sub(BANDS,2)) >= 0 )&&( sub(last_bitalloc[sub(k_sort[k], sub(BANDS,2))], 1) == 0 )))
|
||||
{
|
||||
exp = norm_s(band_width[k_sort[k]]);
|
||||
tmp = shl(band_width[k_sort[k]],exp);/*Q(exp) */
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-exp = 29-exp) */
|
||||
L_tmp = Mult_32_16(Rk_sort[k],tmp);/* Q(16+29-exp-15 = 30-exp) */
|
||||
tmp = sub(18,exp);
|
||||
ever_bits[k] = extract_l(L_shr(L_tmp,tmp));/*Q12 */
|
||||
IF( sub(ever_bits[k],rk_temp) < 0 )
|
||||
{
|
||||
rk_temp = ever_bits[k];
|
||||
move16();
|
||||
k2 = k;
|
||||
move16();
|
||||
}
|
||||
class_flag = 1;
|
||||
}
|
||||
}
|
||||
test();
|
||||
IF( class_flag ==0 || sub(input_frame,L_FRAME8k) == 0)
|
||||
{
|
||||
FOR(k = 0; k < BANDS; k++)
|
||||
{
|
||||
test();
|
||||
IF( sub(k_sort[k],sub(BANDS,p2a_bands)) < 0 && Rk_sort[k] > 0 )
|
||||
{
|
||||
exp = norm_s(band_width[k_sort[k]]);
|
||||
tmp = shl(band_width[k_sort[k]],exp);/*Q(exp) */
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-exp = 29-exp) */
|
||||
L_tmp = Mult_32_16(Rk_sort[k],tmp);/* Q(16+29-exp-15 = 30-exp) */
|
||||
tmp = sub(18,exp);
|
||||
ever_sort[k] = extract_l(L_shr(L_tmp,tmp));/*Q12 */
|
||||
IF(sub(ever_sort[k],ever_temp) < 0)
|
||||
{
|
||||
ever_temp = ever_sort[k];
|
||||
move16();
|
||||
k2 = k;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
k_num[0] = k2;
|
||||
IF(sub(k_sort[k2],sub(BANDS,1)) == 0)
|
||||
{
|
||||
FOR (k = 0; k < BANDS; k++)
|
||||
{
|
||||
if(sub(k_sort[k],sub(k_sort[k2],1)) == 0)
|
||||
{
|
||||
k_num[1] = k;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE IF(k_sort[k2] == 0)
|
||||
{
|
||||
FOR (k = 0; k < BANDS; k++)
|
||||
{
|
||||
if(sub(k_sort[k],add(k_sort[k2],1)) == 0)
|
||||
{
|
||||
k_num[1] = k;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
IF ( L_sub( Rk[sub(k_sort[k2],1)],Rk[add(k_sort[k2],1)] ) < 0 )
|
||||
{
|
||||
FOR (k = 0; k < BANDS; k++)
|
||||
{
|
||||
if(sub(k_sort[k],sub(k_sort[k2],1)) == 0)
|
||||
{
|
||||
k_num[1] = k;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
FOR (k = 0; k < BANDS; k++)
|
||||
{
|
||||
if(sub(k_sort[k],add(k_sort[k2],1)) == 0)
|
||||
{
|
||||
k_num[1] = k;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+615
@@ -0,0 +1,615 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h"
|
||||
#include "math_op.h"
|
||||
#include "math_32.h"
|
||||
#include "oper_32b.h"
|
||||
#include "move.h"
|
||||
#include "count.h"
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* hq2_noise_inject()
|
||||
*
|
||||
* HQ2 noise injection for WB signals
|
||||
*--------------------------------------------------------------------------*/
|
||||
void hq2_noise_inject_fx(
|
||||
Word32 L_y2[],
|
||||
const Word16 band_start[],
|
||||
const Word16 band_end[],
|
||||
const Word16 band_width[],
|
||||
Word32 Ep_fx[],
|
||||
Word32 Rk_fx[],
|
||||
const Word16 npulses[],
|
||||
Word16 ni_seed,
|
||||
const Word16 bands,
|
||||
const Word16 ni_start_band,
|
||||
const Word16 bw_low,
|
||||
const Word16 bw_high,
|
||||
const Word32 enerL_fx,
|
||||
const Word32 enerH_fx,
|
||||
Word32 last_ni_gain_fx[],
|
||||
Word16 last_env_fx[],
|
||||
Word16 *last_max_pos_pulse,
|
||||
Word16 *p2a_flags,
|
||||
Word16 p2a_bands,
|
||||
const Word16 hqswb_clas,
|
||||
const Word16 bwidth,
|
||||
const Word32 bwe_br
|
||||
)
|
||||
{
|
||||
Word32 L_tmp,L_tmp2,L_tmp2x,L_tmp3,L_tmp1;
|
||||
Word16 exp,exp2,Q_speech;
|
||||
Word16 pd_fx[BANDS_MAX], rand_fx, peak_fx[BANDS_MAX], fac_fx;
|
||||
|
||||
Word16 tmp,tmpx,tmp1,tmp2,tmp3,tmp4,Q_env_fx[BANDS_MAX],Q_Ep_fx[BANDS_MAX];
|
||||
|
||||
Word16 Qs=SWB_BWE_LR_Qs;
|
||||
Word32 env_fx[BANDS_MAX];
|
||||
Word16 env_fx2[BANDS_MAX];
|
||||
Word32 ni_gain_fx[BANDS_MAX];
|
||||
Word16 y2hat_fx[L_FRAME48k];
|
||||
|
||||
Word16 i, j, k, ni_end_band, satur, count[BANDS_MAX], max_pos_pulse, pos;
|
||||
Word16 sb = bands;
|
||||
|
||||
satur = 0;
|
||||
move16();
|
||||
|
||||
FOR(i = 0 ; i < bands; i++)
|
||||
{
|
||||
Ep_fx[i] = L_shl(Ep_fx[i], 6);/* Q-6 -> Q0 */ move32();
|
||||
}
|
||||
|
||||
tmp = add(band_end[bands-1], 1);
|
||||
FOR (k = 0; k < tmp; k++)
|
||||
{
|
||||
y2hat_fx[k] = (Word16)L_min(L_max(L_shr(L_y2[k],Qs),-32768),32767);
|
||||
move16(); /* Extract_l or something else is missing here */
|
||||
}
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF( (sub(hqswb_clas,HQ_HARMONIC) ==0 || sub(hqswb_clas,HQ_NORMAL) ==0 ) && (L_sub(bwe_br,HQ_16k40) ==0 || L_sub(bwe_br,HQ_13k20) ==0 ) && sub(bwidth,SWB) ==0 )
|
||||
{
|
||||
sb = 17;
|
||||
move16();
|
||||
if( L_sub(bwe_br,HQ_16k40) == 0 )
|
||||
{
|
||||
sb = 19;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate the envelopes/ the decoded peak coeff./number of the decoded coeff./ the last subbands of the bit-allocated/saturation of bit-allocation */
|
||||
ni_end_band = bands;
|
||||
max_pos_pulse = bands;
|
||||
FOR (k = ni_start_band; k < ni_end_band; k++)
|
||||
{
|
||||
tmp = div_s(1, band_width[k]); /*Q15 */
|
||||
L_tmp = Mult_32_16(Rk_fx[k],tmp);/*Q(16+15-15=16) */
|
||||
pd_fx[k] = extract_h(L_shl(L_tmp,10)); /*16+10-16 =Q10 */
|
||||
|
||||
L_tmp2 = L_add(0,Ep_fx[k]);/*Q0 */
|
||||
L_tmp = L_max(1, L_tmp2);
|
||||
exp = norm_l(L_tmp);
|
||||
tmp = extract_h(L_shl(L_tmp, exp));
|
||||
|
||||
L_tmp3 = L_add(0,(Word32)band_width[k]);
|
||||
exp2 = norm_l(L_tmp3);
|
||||
tmp2 = extract_h(L_shl(L_tmp3, exp2));
|
||||
|
||||
exp2 = sub(exp, exp2); /* Denormalize and substract */
|
||||
|
||||
tmp3 = sub(tmp2, tmp);
|
||||
if (tmp3 > 0)
|
||||
{
|
||||
tmp2 = shr(tmp2, 1);
|
||||
}
|
||||
if (tmp3 > 0)
|
||||
{
|
||||
exp2 = add(exp2, 1);
|
||||
}
|
||||
tmp = div_s(tmp2, tmp);
|
||||
L_tmp = L_deposit_h(tmp);
|
||||
L_tmp = Isqrt_lc(L_tmp, &exp2);
|
||||
env_fx[k] = L_tmp;
|
||||
move32();/*Q(31-exp2) move32(); */
|
||||
Q_env_fx[k] = sub(31,exp2);
|
||||
move16();
|
||||
tmp = sub(17,Q_env_fx[k]);
|
||||
env_fx2[k] = extract_h(L_shl(env_fx[k],tmp));/*Q1 */
|
||||
peak_fx[k] = 0;
|
||||
move16();
|
||||
count[k] = 0;
|
||||
move16();
|
||||
|
||||
IF(npulses[k] != 0)
|
||||
{
|
||||
FOR (i = band_start[k]; i <= band_end[k]; i++)
|
||||
{
|
||||
L_tmp =L_mult0(y2hat_fx[i],y2hat_fx[i]); /*0 */
|
||||
Ep_fx[k] =L_sub(Ep_fx[k],L_tmp);
|
||||
move32();/*0 */
|
||||
IF(sub(abs_s(y2hat_fx[i]),peak_fx[k]) > 0)
|
||||
{
|
||||
peak_fx[k] = abs_s(y2hat_fx[i]);
|
||||
move16();/*0 */
|
||||
}
|
||||
|
||||
IF(y2hat_fx[i] != 0)
|
||||
{
|
||||
count[k] = add(count[k],1);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
max_pos_pulse = k;
|
||||
L_tmp2 = L_add(0,Ep_fx[k]);
|
||||
L_tmp = L_max(1, L_tmp2);
|
||||
exp = norm_l(L_tmp);
|
||||
tmp = extract_h(L_shl(L_tmp, exp));
|
||||
|
||||
L_tmp3 = (Word32)band_width[k];
|
||||
exp2 = norm_l(L_tmp3);
|
||||
tmp2 = extract_h(L_shl(L_tmp3, exp2));
|
||||
|
||||
exp2 = sub(exp, exp2); /* Denormalize and substract */
|
||||
|
||||
tmp3 = sub(tmp2, tmp);
|
||||
if (tmp3 > 0)
|
||||
{
|
||||
tmp2 = shr(tmp2, 1);
|
||||
}
|
||||
if (tmp3 > 0)
|
||||
{
|
||||
exp2 = add(exp2, 1);
|
||||
}
|
||||
tmp = div_s(tmp2, tmp);
|
||||
L_tmp = L_deposit_h(tmp);
|
||||
L_tmp = Isqrt_lc(L_tmp, &exp2);
|
||||
Ep_fx[k] = L_tmp;
|
||||
move32();/*Q(31-exp2) */
|
||||
Q_Ep_fx[k] = sub(31,exp2);
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Ep_fx[k] = env_fx[k];
|
||||
move32();/*Q(Q_env_fx[k]) */
|
||||
Q_Ep_fx[k] = Q_env_fx[k];
|
||||
move16();/*31-exp2 */
|
||||
}
|
||||
}
|
||||
|
||||
FOR(k = ni_start_band; k < ni_end_band; k++)
|
||||
{
|
||||
/* calculate the noise gain */
|
||||
satur =0;
|
||||
move16();
|
||||
if(sub(pd_fx[k],819)>= 0)
|
||||
{
|
||||
satur =1;
|
||||
move16();
|
||||
}
|
||||
|
||||
test();
|
||||
IF (satur == 0 && Ep_fx[k] > 0)
|
||||
{
|
||||
IF(npulses[k] != 0)
|
||||
{
|
||||
IF( sub(bwidth,SWB) ==0)
|
||||
{
|
||||
IF(sub(hqswb_clas,HQ_TRANSIENT) !=0 )
|
||||
{
|
||||
IF(peak_fx[k]!=0)
|
||||
{
|
||||
Q_speech = norm_s(peak_fx[k]);
|
||||
tmp = shl(peak_fx[k],Q_speech);/*Q(Q_speech) */
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-Q_speech) */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp = 0x7fff;
|
||||
move16();
|
||||
Q_speech = 0;
|
||||
move16();
|
||||
}
|
||||
L_tmp2x = Mult_32_16(Ep_fx[k],tmp);/* Q(Q_Ep_fx[k]+29-Q_speech-15 = Q_Ep_fx[k]-Q_speech+14) */
|
||||
tmp = sub(Q_Ep_fx[k],Q_speech);
|
||||
tmpx = add(tmp,1);
|
||||
tmp2 = extract_l(L_shr(L_tmp2x,s_min(tmpx, 31)));/*Q13 Ep[k]/peak[k] */
|
||||
|
||||
IF(sub(hqswb_clas,HQ_HARMONIC) == 0 )
|
||||
{
|
||||
tmp = sub(1536,pd_fx[k]); /*Q10 */
|
||||
tmp3 = shl(tmp,4); /*Q14 */
|
||||
L_tmp = Mult_32_16(env_fx[k],tmp3);/*Q(Q_env_fx[k]+14-15 = Q_env_fx[k]-1) */
|
||||
L_tmp = Mult_32_16(L_tmp,6144);/*Q(Q_env_fx[k]-1+10-15 = Q_env_fx[k]-6) */
|
||||
|
||||
IF(peak_fx[k]!=0)
|
||||
{
|
||||
Q_speech = norm_s(peak_fx[k]);
|
||||
tmp = shl(peak_fx[k],Q_speech);/*Q(Q_speech) */
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-Q_speech) */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp = 0x7fff;
|
||||
move16();
|
||||
Q_speech = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
L_tmp2 = Mult_32_16(Ep_fx[k],tmp);/* Q(Q_Ep_fx[k]+29-Q_speech-15=Q_Ep_fx[k]-Q_speech+14) */
|
||||
L_tmp3 = Mult_32_16(L_tmp,tmp);/* Q(Q_env_fx[k]-6+29-Q_speech-15=Q_env_fx[k]-Q_speech+8) */
|
||||
L_tmp = Mult_32_32(L_tmp2,L_tmp3); /*Q(Q_Ep_fx[k]-Q_speech+14+Q_env_fx[k]-Q_speech+8-31=Q_Ep_fx[k]+Q_env_fx[k]-2*Q_speech-9) */
|
||||
|
||||
tmp = add(Q_Ep_fx[k],Q_env_fx[k]);
|
||||
tmp = sub(tmp,Q_speech);
|
||||
tmp = sub(tmp,Q_speech);
|
||||
tmp = sub(37,tmp);
|
||||
tmp1= extract_h(L_shl(L_tmp,tmp));/*Q12 //6.0f*(1.5f - pd[k])*env[k]*Ep[k]/(peak[k]*peak[k]) */
|
||||
|
||||
fac_fx = tmp1;
|
||||
move16();/*Q12 */
|
||||
if(sub(k,sb) > 0)
|
||||
{
|
||||
fac_fx =mult(24576,tmp2);/*//Q(14+13-15=12) */
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
IF(sub(k,sb) <= 0)
|
||||
{
|
||||
tmp = sub(1536,pd_fx[k]); /*Q10 */
|
||||
tmp3 = shl(tmp,4); /*Q14 */
|
||||
L_tmp = Mult_32_16(L_tmp2x,tmp3);/*Q(Q_Ep_fx[k]-Q_speech+14+14-15 = Q_Ep_fx[k]-Q_speech+13) */
|
||||
L_tmp = Mult_32_16(L_tmp,20480);/*Q(Q_Ep_fx[k]-Q_speech+13+12-15 = Q_Ep_fx[k]-Q_speech+10) */
|
||||
fac_fx= extract_h(L_shl(L_tmp,sub(add(18,Q_speech),Q_Ep_fx[k])));/*Q_Ep_fx[k]-Q_speech+10 +18+Q_speech-Q_Ep_fx[k] -16 =12 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
fac_fx =shl(mult(32767,tmp2),1);/*//Q(13+13-15+1=12) */
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
fac_fx = 4505;
|
||||
move16();/*Q12 */
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp = sub(1536,pd_fx[k]); /*Q10 */
|
||||
tmp2 = s_min(1024,tmp); /*q10 */
|
||||
tmp2 = shl(tmp2,4); /*Q14 */
|
||||
L_tmp = Mult_32_16(env_fx[k],tmp2);/*Q(Q_env_fx[k]+14-15 = Q_env_fx[k]-1) */
|
||||
L_tmp = Mult_32_16(L_tmp,20480);/*Q(Q_env_fx[k]-1+10-15 = Q_env_fx[k]-6) */
|
||||
|
||||
IF(peak_fx[k]!=0)
|
||||
{
|
||||
Q_speech = norm_s(peak_fx[k]);
|
||||
tmp = shl(peak_fx[k],Q_speech);/*Q(Q_speech) */
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-Q_speech) */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp = 0x7fff;
|
||||
move16();
|
||||
Q_speech = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
L_tmp2 = Mult_32_16(Ep_fx[k],tmp);/* Q(Q_Ep_fx[k]+29-Q_speech-15=Q_Ep_fx[k]-Q_speech+14) */
|
||||
L_tmp3 = Mult_32_16(L_tmp,tmp);/* Q(Q_env_fx[k]-6+29-Q_speech-15=Q_env_fx[k]-Q_speech+8) */
|
||||
L_tmp = Mult_32_32(L_tmp2,L_tmp3); /*Q(Q_Ep_fx[k]-Q_speech+14+Q_env_fx[k]-Q_speech+8-31=Q_Ep_fx[k]+Q_env_fx[k]-2*Q_speech-9) */
|
||||
|
||||
tmp = add(Q_Ep_fx[k],Q_env_fx[k]);
|
||||
tmp = sub(tmp,Q_speech);
|
||||
tmp = sub(tmp,Q_speech);
|
||||
tmp = sub(37,tmp);
|
||||
|
||||
fac_fx = extract_h(L_shl(L_tmp,tmp));/*Q12 */
|
||||
|
||||
test();
|
||||
IF(sub(k,1) > 0 && sub(k,sub(ni_end_band,1)) < 0)
|
||||
{
|
||||
IF(env_fx2[k]!=0)
|
||||
{
|
||||
Q_speech = norm_s(env_fx2[k]);
|
||||
tmp = shl(env_fx2[k],Q_speech);/*Q(Q_speech+1) */
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-Q_speech-1=28-Q_speech) */
|
||||
Q_speech = sub(28,Q_speech);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp =0x7fff;
|
||||
move16();
|
||||
Q_speech = 0;
|
||||
move16();
|
||||
}
|
||||
tmp1 = mult(env_fx2[add(k,1)],16384);/*Q(1+15-15=1) Q1 */
|
||||
tmp2 = sub(env_fx2[k],tmp1);
|
||||
tmp1 = mult(env_fx2[k],16384);/*Q(1+15-15=1) Q1 */
|
||||
tmp3 = sub(tmp1,env_fx2[sub(k,1)]);
|
||||
tmp1 = mult(peak_fx[k],16384);/*Q(0+15-15=0) Q0 */
|
||||
tmp4 = sub(tmp1,shr(env_fx2[k],1));
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF(count[add(k,1)] == 0 && tmp2 > 0 && tmp3 < 0)
|
||||
{
|
||||
L_tmp = L_mult(env_fx2[add(k,1)],tmp);/* Q(1+Q_speech+1 = Q_speech+2) */
|
||||
L_tmp = Mult_32_16(L_tmp,24576); /*Q(Q_speech+2+14-15=Q_speech+1) */
|
||||
fac_fx = extract_h(L_shl(L_tmp,sub(27,Q_speech)));/*Q12 */
|
||||
}
|
||||
ELSE IF(count[sub(k,1)] == 0 && tmp4 > 0)
|
||||
{
|
||||
L_tmp = L_mult(env_fx2[sub(k,1)],tmp); /* Q(1+Q_speech+1 = Q_speech+2) */
|
||||
fac_fx = extract_h(L_shl(L_tmp,sub(26,Q_speech)));/*Q12 */
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
||||
IF(sub(k,sub(ni_end_band,p2a_bands)) >= 0 && sub(bwidth, WB) == 0)
|
||||
{
|
||||
L_tmp = Mult_32_16(enerH_fx, bw_low);
|
||||
L_tmp2= Mult_32_16(enerL_fx, bw_high);
|
||||
L_tmp = L_sub(L_tmp,L_tmp2);
|
||||
tmp1 = mult(peak_fx[k],16384);/*Q(0+15-15=0) Q0 */
|
||||
tmp4 = sub(tmp1,shr(env_fx2[k],1));
|
||||
test();
|
||||
IF(L_tmp > 0 && tmp4 < 0)
|
||||
{
|
||||
IF(peak_fx[k]!=0)
|
||||
{
|
||||
Q_speech = norm_s(peak_fx[k]);
|
||||
tmp = shl(peak_fx[k],Q_speech);/*Q(Q_speech) */
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-Q_speech) */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp = 0x7fff;
|
||||
move16();
|
||||
Q_speech = 0;
|
||||
move16();
|
||||
}
|
||||
L_tmp2 = Mult_32_16(Ep_fx[k],tmp);/* Q(Q_Ep_fx[k]+29-Q_speech-15 = Q_Ep_fx[k]-Q_speech+14) */
|
||||
tmp = sub(Q_Ep_fx[k],Q_speech);
|
||||
tmp = add(tmp,1);
|
||||
tmp = extract_l(L_shr(L_tmp2,tmp));/*Q13 */
|
||||
tmp = sub(16384,tmp);/*Q13 */
|
||||
fac_fx = extract_h(L_shl(L_mult(fac_fx,tmp),2));/*Q12*/
|
||||
}
|
||||
|
||||
IF(p2a_flags[k] == 0)
|
||||
{
|
||||
L_tmp2 = Mult_32_16(Ep_fx[k],fac_fx);/*Q(Q_Ep_fx[k]+12-15 = Q_Ep_fx[k]-3) */
|
||||
Q_speech = norm_l(L_tmp2);
|
||||
tmp = extract_h(L_shl(L_tmp2,Q_speech));/*Q(Q_Ep_fx[k]-3+Q_speech-16 = Q_Ep_fx[k]+Q_speech-19) */
|
||||
IF(tmp != 0)
|
||||
{
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-Q_Ep_fx[k]-Q_speech+19 = 48-Q_Ep_fx[k]-Q_speech) */
|
||||
L_tmp2 = Mult_32_16(env_fx[k],tmp);/*Q(Q_env_fx[k]+48-Q_Ep_fx[k]-Q_speech-15 = Q_env_fx[k]-Q_Ep_fx[k]-Q_speech+33) */
|
||||
L_tmp2 = Mult_32_16(L_tmp2,20480);/*Q(Q_env_fx[k]-Q_Ep_fx[k]-Q_speech+33+14-15 = Q_env_fx[k]-Q_Ep_fx[k]-Q_speech+32) */
|
||||
tmp = sub(Q_env_fx[k],Q_Ep_fx[k]);
|
||||
tmp = sub(tmp,Q_speech);
|
||||
tmp = add(tmp,25);
|
||||
L_tmp = L_shr(L_tmp2,tmp);/*Q7 */
|
||||
tmp = extract_l(L_min(L_tmp,192));/* */
|
||||
fac_fx = extract_h(L_shl(L_mult(fac_fx,tmp),8));/*Q12 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp = 0x7fff;/*Q0 */
|
||||
L_tmp2 = Mult_32_16(env_fx[k],tmp);/*Q(Q_env_fx[k]+0-15 = Q_env_fx[k]-15) */
|
||||
L_tmp2 = Mult_32_16(L_tmp2,20480);/*Q(Q_env_fx[k]-15+14-15 = Q_env_fx[k]-16) */
|
||||
tmp = sub(Q_env_fx[k],23);
|
||||
L_tmp = L_shr(L_tmp2,tmp);/*Q7 */
|
||||
tmp = extract_l((L_min(L_tmp,192)));/* */
|
||||
fac_fx = extract_h(L_shl(L_mult(fac_fx,tmp),8));/*Q12 */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
fac_fx = 4505;
|
||||
move16();
|
||||
test();
|
||||
if( sub(hqswb_clas,HQ_HARMONIC) == 0 && sub(bwidth,SWB) == 0 )
|
||||
{
|
||||
fac_fx = 3277;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
L_tmp = Mult_32_16(Ep_fx[k],fac_fx);/*Q(Q_Ep_fx[k]+12-15 = Q_Ep_fx[k]-3) */
|
||||
ni_gain_fx[k] = L_shr(L_tmp,sub(Q_Ep_fx[k],20));
|
||||
move32();/*Q17 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
ni_gain_fx[k] = L_deposit_l(0);
|
||||
}
|
||||
|
||||
/* smooth the noise gain between the current frame and the previous frame */
|
||||
pos = s_max(max_pos_pulse, *last_max_pos_pulse);
|
||||
move16();
|
||||
if( sub(bwidth,SWB) == 0 )
|
||||
{
|
||||
pos = sub(ni_end_band,1);
|
||||
move16();
|
||||
}
|
||||
|
||||
IF(sub(k,pos) <=0 )
|
||||
{
|
||||
test();
|
||||
IF(k > 0 && add(sub(k,ni_end_band),1) < 0)
|
||||
{
|
||||
tmp1 = mult(last_env_fx[k],16384);/*Q(1+15-15=1) Q1 */
|
||||
tmp2 = sub(env_fx2[k],tmp1);/*>0 */
|
||||
tmp1 = mult(env_fx2[k],16384);/*Q(1+15-15=1) Q1 */
|
||||
tmp3 = sub(tmp1,last_env_fx[k]);/*<0 */
|
||||
L_tmp = L_add((Word32)env_fx2[k],(Word32)env_fx2[sub(k,1)]);
|
||||
L_tmp = L_add(L_tmp,(Word32)env_fx2[add(k,1)]);/*Q1 */
|
||||
L_tmp1 = L_add((Word32)last_env_fx[k],(Word32)last_env_fx[sub(k,1)]);
|
||||
L_tmp1 = L_add(L_tmp1,(Word32)last_env_fx[add(k,1)]);/*Q1 */
|
||||
L_tmp2 = Mult_32_16(L_tmp1,16384);/*Q(1+15-15) Q1 */
|
||||
L_tmp2 = L_sub(L_tmp,L_tmp2);/*>0 */
|
||||
L_tmp3 = Mult_32_16(L_tmp,16384);/*Q(1+15-15) Q1 */
|
||||
L_tmp3 = L_sub(L_tmp3,L_tmp1);/*<0 */
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF( (tmp2 > 0 && tmp3 < 0) ||(L_tmp2 > 0 && L_tmp3 < 0))
|
||||
{
|
||||
IF( L_sub(ni_gain_fx[k],last_ni_gain_fx[k]) > 0 )
|
||||
{
|
||||
L_tmp = Mult_32_16(ni_gain_fx[k],6554);/*Q(17+15-15 = 17) */
|
||||
L_tmp1 = Mult_32_16(last_ni_gain_fx[k],26214);/*Q17 */
|
||||
ni_gain_fx[k] = L_add(L_tmp,L_tmp1);
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_tmp = Mult_32_16(ni_gain_fx[k],19661);/*Q(17+15-15 = 17) */
|
||||
L_tmp1 = Mult_32_16(last_ni_gain_fx[k],13107);/*Q17 */
|
||||
ni_gain_fx[k] = L_add(L_tmp,L_tmp1);
|
||||
move32();
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE IF (add(sub(k,ni_end_band),1) == 0)
|
||||
{
|
||||
tmp1 = mult(last_env_fx[k],16384);/*Q(1+15-15=1) Q1 */
|
||||
tmp2 = sub(env_fx2[k],tmp1);/*>0 */
|
||||
tmp1 = mult(env_fx2[k],16384);/*Q(1+15-15=1) Q1 */
|
||||
tmp3 = sub(tmp1,last_env_fx[k]);/*<0 */
|
||||
L_tmp = L_add((Word32)env_fx2[k],(Word32)env_fx2[sub(k,1)]);/*Q1 */
|
||||
L_tmp1 = L_add((Word32)last_env_fx[k],(Word32)last_env_fx[sub(k,1)]);/*Q1 */
|
||||
L_tmp2 = Mult_32_16(L_tmp1,16384);/*Q(1+15-15) Q1 */
|
||||
L_tmp2 = L_sub(L_tmp,L_tmp2);/*>0 */
|
||||
L_tmp3 = Mult_32_16(L_tmp,16384);/*Q(1+15-15) Q1 */
|
||||
L_tmp3 = L_sub(L_tmp3,L_tmp1);/*<0 */
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF( (tmp2 > 0 && tmp3 < 0) ||(L_tmp2 > 0 && L_tmp3 < 0))
|
||||
{
|
||||
IF( L_sub(ni_gain_fx[k],last_ni_gain_fx[k]) > 0 )
|
||||
{
|
||||
L_tmp = Mult_32_16(ni_gain_fx[k],6554);/*Q(17+15-15 = 17) */
|
||||
L_tmp1 = Mult_32_16(last_ni_gain_fx[k],26214);/*Q17 */
|
||||
ni_gain_fx[k] = L_add(L_tmp,L_tmp1);
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_tmp = Mult_32_16(ni_gain_fx[k],19661);/*Q(17+15-15 = 17) */
|
||||
L_tmp1 = Mult_32_16(last_ni_gain_fx[k],13107);/*Q17 */
|
||||
ni_gain_fx[k] = L_add(L_tmp,L_tmp1);
|
||||
move32();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* inject noise into the non-decoded coeffs */
|
||||
test();
|
||||
test();
|
||||
IF(add(sub(k,ni_end_band),p2a_bands) >=0 && p2a_flags[k] == 0 && sub(bwidth,SWB) !=0 )
|
||||
{
|
||||
FOR (i = band_start[k]; i <= band_end[k]; i++)
|
||||
{
|
||||
IF (L_y2[i] != 0)
|
||||
{
|
||||
L_y2[i] = Mult_32_16(L_y2[i],26215);
|
||||
move32();/*Q(12+15-15=12) */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF(sub(k,max_pos_pulse) == 0 && add(sub(k,bands),p2a_bands)< 0 && sub(satur,1) != 0 && sub(bwidth,SWB) !=0)
|
||||
{
|
||||
j = 0;
|
||||
Q_speech = norm_l(ni_gain_fx[k]);
|
||||
tmp = extract_h(L_shl(ni_gain_fx[k],Q_speech));/*Q(Q_speech+1) */
|
||||
IF(tmp != 0)
|
||||
{
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-Q_speech-1 = 28-Q_speech) */
|
||||
L_tmp = Mult_32_16(Ep_fx[k],tmp); /*Q(Q_Ep_fx[k]+28-Q_speech-15 = Q_Ep_fx[k]+13-Q_speech) */
|
||||
tmp = sub(Q_Ep_fx[k],Q_speech);
|
||||
tmp = sub(15,tmp);
|
||||
tmp = extract_h(L_shl(L_tmp,tmp));/*Q12 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp = 0x7fff;/*Q0 */
|
||||
L_tmp = Mult_32_16(Ep_fx[k],tmp); /*Q(Q_Ep_fx[k]+0-15 = Q_Ep_fx[k]-15) */
|
||||
tmp = sub(43,Q_Ep_fx[k]);
|
||||
tmp = extract_h(L_shl(L_tmp,tmp));/*Q12 */
|
||||
}
|
||||
fac_fx = s_max(tmp,4096);/*Q12 */
|
||||
|
||||
FOR (i = band_start[k]; i <= band_end[k]; i++)
|
||||
{
|
||||
IF (L_y2[i] == 0)
|
||||
{
|
||||
rand_fx = Random(&ni_seed); /*Q15 */
|
||||
IF(band_width[k] != 0)
|
||||
{
|
||||
Q_speech = norm_s(band_width[k]);
|
||||
tmp = shl(band_width[k],Q_speech);/*Q(Q_speech) */
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-Q_speech) */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp = 0x7fff;
|
||||
Q_speech = 0;
|
||||
}
|
||||
tmp1 = sub(fac_fx,4096);/*Q12 */
|
||||
L_tmp = L_mult(tmp1,j);/*Q13 */
|
||||
L_tmp = Mult_32_16(L_tmp,tmp);/*Q(13+29-Q_speech-15 = 27-Q_speech) */
|
||||
tmp = extract_h(L_shl(L_tmp,add(1,Q_speech)));/*Q12 */
|
||||
tmp = sub(fac_fx,tmp);/*Q12 */
|
||||
L_tmp = Mult_32_16(ni_gain_fx[k],tmp);/*Q(17+12-15=14) */
|
||||
L_y2[i] = L_add(L_y2[i],L_shr(Mult_32_16(L_tmp,rand_fx),2));
|
||||
move32();/*Q12 */
|
||||
}
|
||||
j=add(j,1);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
FOR (i = band_start[k]; i <= band_end[k]; i++)
|
||||
{
|
||||
IF (L_y2[i] == 0)
|
||||
{
|
||||
rand_fx = Random(&ni_seed); /*Q15 */
|
||||
L_tmp = Mult_32_16(ni_gain_fx[k],rand_fx);/*Q(17+15-15=17) */
|
||||
L_y2[i] = L_add(L_y2[i],L_shr(L_tmp,5));
|
||||
move32();/*Q12 */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Copy(env_fx2,last_env_fx,ni_end_band);
|
||||
Copy32(ni_gain_fx,last_ni_gain_fx,ni_end_band);
|
||||
*last_max_pos_pulse = max_pos_pulse;
|
||||
move16();
|
||||
return;
|
||||
}
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* hq_bit_allocation_fx()
|
||||
*
|
||||
* Assign bits for HQ fine structure coding with PVQ
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void hq_bit_allocation_fx(
|
||||
const Word32 core_brate, /* i : Core bit-rate Q0 */
|
||||
const Word16 length, /* i : Frame length Q0 */
|
||||
const Word16 hqswb_clas, /* i : HQ class Q0 */
|
||||
Word16 *num_bits, /* i/o: Remaining bit budget Q0 */
|
||||
const Word16 *normqlg2, /* i : Quantized norms Q0 */
|
||||
const Word16 nb_sfm, /* i : Number sub bands to be encoded Q0 */
|
||||
const Word16 *sfmsize, /* i : Sub band bandwidths Q0 */
|
||||
Word16 *noise_level, /* o : HVQ noise level */
|
||||
Word16 *R, /* o : Bit allocation per sub band Q0 */
|
||||
Word16 *Rsubband, /* o : Fractional bit allocation Q3 */
|
||||
Word16 *sum, /* o : Sum of allocated shape bits Q0 */
|
||||
Word16 *core_sfm, /* o : Last coded band in core Q0 */
|
||||
const Word16 num_env_bands /* i : Number sub bands to be encoded for HQ_GEN Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word16 idx[NB_SFM];
|
||||
Word16 wnorm[NB_SFM];
|
||||
Word16 avrg_wnorm;
|
||||
Word16 tmp, tmp2;
|
||||
Word16 E_low;
|
||||
Word16 E_hb_mean;
|
||||
Word16 E_max;
|
||||
Word16 i_max;
|
||||
/* Temp */
|
||||
|
||||
Word16 sfm_limit = nb_sfm;
|
||||
move16();
|
||||
|
||||
set16_fx( R, 0, NB_SFM);
|
||||
FOR( i = 0; i < nb_sfm; i++ )
|
||||
{
|
||||
idx[i] = i;
|
||||
move16();
|
||||
}
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
if( sub(hqswb_clas, HQ_TRANSIENT) != 0 && sub(hqswb_clas, HQ_HVQ) != 0 && !(sub(length, L_FRAME16k) == 0 && L_sub(core_brate, HQ_32k) == 0))
|
||||
{
|
||||
/* 'nf_idx' 2-bits index written later */
|
||||
*num_bits = sub(*num_bits, 2);
|
||||
}
|
||||
|
||||
test();
|
||||
IF ( sub(hqswb_clas, HQ_GEN_SWB) == 0 || sub(hqswb_clas, HQ_GEN_FB) == 0 )
|
||||
{
|
||||
IF ( L_sub(core_brate, HQ_32k) == 0 )
|
||||
{
|
||||
*num_bits = sub(*num_bits, HQ_GENERIC_SWB_NBITS2 );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
*num_bits = sub(*num_bits, HQ_GENERIC_SWB_NBITS );
|
||||
}
|
||||
|
||||
if ( sub(hqswb_clas, HQ_GEN_FB) == 0 )
|
||||
{
|
||||
*num_bits = sub(*num_bits, HQ_GENERIC_FB_NBITS );
|
||||
}
|
||||
}
|
||||
|
||||
IF( ( sub(length, L_FRAME48k) == 0 ) && (sub(hqswb_clas, HQ_HARMONIC) != 0) && (sub(hqswb_clas, HQ_HVQ) != 0))
|
||||
{
|
||||
tmp = 0;
|
||||
move16();
|
||||
if( sub(hqswb_clas,HQ_TRANSIENT) == 0 )
|
||||
{
|
||||
tmp = 1;
|
||||
move16();
|
||||
}
|
||||
map_quant_weight_fx( normqlg2, wnorm, tmp );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Copy( normqlg2, wnorm, nb_sfm );
|
||||
}
|
||||
|
||||
IF( sub(hqswb_clas, HQ_HARMONIC) == 0 )
|
||||
{
|
||||
/* classification and limit bandwidth for bit allocation */
|
||||
sfm_limit = sub(sfm_limit, 2);
|
||||
limit_band_noise_level_calc_fx( wnorm, &sfm_limit, core_brate, noise_level );
|
||||
|
||||
/* Detect important band in high frequency region */
|
||||
E_low = sum16_fx(wnorm, SFM_G1);
|
||||
i_max = 0;
|
||||
move16();
|
||||
E_max = MIN16B;
|
||||
move16();
|
||||
E_hb_mean = 0;
|
||||
move16();
|
||||
FOR( i = SFM_G1; i < nb_sfm; i++)
|
||||
{
|
||||
E_hb_mean = add(E_hb_mean, wnorm[i]);
|
||||
IF( sub(wnorm[i], E_max) > 0)
|
||||
{
|
||||
E_max = wnorm[i];
|
||||
move16();
|
||||
i_max = i;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
E_hb_mean = shr(E_hb_mean, 4); /* Truncated division by SFM_G1 */
|
||||
set16_fx( wnorm + sfm_limit, -20, sub(nb_sfm, sfm_limit) );
|
||||
IF (L_msu0(L_deposit_l(E_low), E_max, 15) <= 0)
|
||||
{
|
||||
IF (L_msu(L_deposit_h(E_hb_mean), E_max, 21955) <= 0) /* 21955 = 0.67 (Q15) */
|
||||
{
|
||||
if (sub(i_max, sfm_limit) >= 0)
|
||||
{
|
||||
wnorm[i_max] = E_max;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF( sub(hqswb_clas, HQ_HVQ) == 0 )
|
||||
{
|
||||
*sum = 0;
|
||||
move16();
|
||||
}
|
||||
ELSE IF ( sub(hqswb_clas, HQ_GEN_SWB) == 0 || (sub(hqswb_clas, HQ_TRANSIENT) == 0 && sub(length, L_FRAME32k) == 0 && L_sub(core_brate, HQ_32k) <= 0) )
|
||||
{
|
||||
*sum = BitAllocF_fx( wnorm, core_brate, *num_bits, nb_sfm, R, Rsubband, hqswb_clas, num_env_bands );
|
||||
}
|
||||
ELSE IF( sub(length, L_FRAME16k) == 0 && L_sub(core_brate, HQ_32k) == 0 )
|
||||
{
|
||||
IF( sub(hqswb_clas, HQ_TRANSIENT) != 0 )
|
||||
{
|
||||
avrg_wnorm = wnorm[10];
|
||||
move16();
|
||||
FOR( i=11; i<18; i++ )
|
||||
{
|
||||
avrg_wnorm = add(avrg_wnorm, wnorm[i]);
|
||||
}
|
||||
|
||||
avrg_wnorm = shr(avrg_wnorm, 3);
|
||||
FOR( i=0; i<4; i++ )
|
||||
{
|
||||
if( sub(wnorm[i], avrg_wnorm) < 0 )
|
||||
{
|
||||
wnorm[i] = avrg_wnorm;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
/* Estimate number of bits per band */
|
||||
*sum = BitAllocWB_fx( wnorm, *num_bits, nb_sfm, R, Rsubband );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
reordvct_fx(wnorm, nb_sfm, idx);
|
||||
bitalloc_fx( wnorm, idx, *num_bits, nb_sfm, QBIT_MAX2, R, sfmsize, hqswb_clas );
|
||||
bitallocsum_fx( R, nb_sfm, sum, Rsubband, *num_bits, length, sfmsize );
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
reordvct_fx(wnorm, nb_sfm, idx);
|
||||
|
||||
/* enlarge the wnorm value so that more bits can be allocated to (sfm_limit/2 ~ sfm_limit) range */
|
||||
IF( sub(hqswb_clas, HQ_HARMONIC) == 0 )
|
||||
{
|
||||
tmp = shr(sfm_limit,1);
|
||||
tmp2 = sub(tmp,1);
|
||||
FOR( i=tmp; i<sfm_limit; i++ )
|
||||
{
|
||||
wnorm[i] = wnorm[tmp2];
|
||||
move16();
|
||||
}
|
||||
}
|
||||
bitalloc_fx( wnorm, idx, *num_bits, nb_sfm, QBIT_MAX2, R, sfmsize, hqswb_clas );
|
||||
bitallocsum_fx( R, nb_sfm, sum, Rsubband, *num_bits, length, sfmsize );
|
||||
}
|
||||
|
||||
/* Find last coded core band */
|
||||
*core_sfm = sub(nb_sfm, 1);
|
||||
test();
|
||||
test();
|
||||
IF( hqswb_clas == HQ_NORMAL || sub(hqswb_clas, HQ_HARMONIC) == 0 )
|
||||
{
|
||||
*core_sfm = find_last_band_fx(R, nb_sfm );
|
||||
}
|
||||
ELSE IF ( sub(hqswb_clas, HQ_GEN_SWB) == 0 || sub(hqswb_clas, HQ_GEN_FB) == 0 )
|
||||
{
|
||||
*core_sfm = find_last_band_fx( R, nb_sfm );
|
||||
IF ( sub(*core_sfm ,num_env_bands) <0 )
|
||||
{
|
||||
*core_sfm = sub(num_env_bands,1);
|
||||
}
|
||||
}
|
||||
|
||||
*num_bits = sub(*num_bits, *sum);
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+279
@@ -0,0 +1,279 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "options.h"
|
||||
#include "cnst_fx.h" /* Audio core constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* hq_configure()
|
||||
*
|
||||
* Configuration routine for HQ mode
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void hq_configure_fx(
|
||||
const Word16 length, /* i : Frame length Q0 */
|
||||
const Word16 hqswb_clas, /* i : HQ SWB class Q0 */
|
||||
const Word32 core_brate, /* i : Codec bitrate Q0 */
|
||||
Word16 *num_sfm, /* o : Total number of subbands Q0 */
|
||||
Word16 *nb_sfm, /* o : Total number of coded bands Q0 */
|
||||
Word16 *start_norm, /* o : First norm to be SDE encoded Q0 */
|
||||
Word16 *num_env_bands, /* o : Number coded envelope bands Q0 */
|
||||
Word16 *numnrmibits, /* o : Number of bits in fall-back norm encoding Q0 */
|
||||
Word16 *hq_generic_offset, /* o : Freq offset for HQ GENERIC Q0 */
|
||||
Word16 const **sfmsize, /* o : Subband bandwidths Q0 */
|
||||
Word16 const **sfm_start, /* o : Subband start coefficients Q0 */
|
||||
Word16 const **sfm_end /* o : Subband end coefficients Q0 */
|
||||
)
|
||||
{
|
||||
*start_norm = 0;
|
||||
move16();
|
||||
|
||||
IF ( sub(length, L_FRAME48k) == 0 )
|
||||
{
|
||||
IF ( sub(hqswb_clas, HQ_GEN_FB) == 0 )
|
||||
{
|
||||
*num_sfm = NB_SFM;
|
||||
move16();
|
||||
*sfmsize = band_len_HQ;
|
||||
move16();
|
||||
*sfm_start = band_start_HQ;
|
||||
move16();
|
||||
*sfm_end = band_end_HQ;
|
||||
move16();
|
||||
|
||||
test();
|
||||
IF ( L_sub(core_brate, HQ_32k) == 0 )
|
||||
{
|
||||
*hq_generic_offset = HQ_GENERIC_FOFFSET_32K;
|
||||
move16();
|
||||
}
|
||||
ELSE IF ( L_sub(core_brate, HQ_16k40) == 0 || L_sub(core_brate, HQ_24k40) == 0 )
|
||||
{
|
||||
*hq_generic_offset = HQ_GENERIC_FOFFSET_24K4;
|
||||
move16();
|
||||
}
|
||||
|
||||
/* setting start frequency of FD BWE */
|
||||
test();
|
||||
IF ( L_sub(core_brate, HQ_32k) == 0 )
|
||||
{
|
||||
*num_env_bands = SFM_N_STA_10k;
|
||||
move16();
|
||||
}
|
||||
ELSE IF ( L_sub(core_brate, HQ_16k40) == 0 || L_sub(core_brate, HQ_24k40) == 0 )
|
||||
{
|
||||
*num_env_bands = SFM_N_STA_8k;
|
||||
move16();
|
||||
}
|
||||
*nb_sfm = *num_sfm;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
IF(sub(hqswb_clas, HQ_HARMONIC) == 0)
|
||||
{
|
||||
*num_sfm = SFM_N_HARM_FB;
|
||||
move16();
|
||||
*nb_sfm = SFM_N_HARM_FB;
|
||||
move16();
|
||||
*num_env_bands = SFM_N_HARM_FB;
|
||||
move16();
|
||||
|
||||
*sfmsize = band_len_harm;
|
||||
move16();
|
||||
*sfm_start = band_start_harm;
|
||||
move16();
|
||||
*sfm_end = band_end_harm;
|
||||
move16();
|
||||
}
|
||||
ELSE IF ( sub(hqswb_clas, HQ_HVQ) == 0 )
|
||||
{
|
||||
IF ( L_sub(core_brate, HQ_24k40) == 0 )
|
||||
{
|
||||
*num_sfm = SFM_N_HARM_FB;
|
||||
move16();
|
||||
*nb_sfm = HVQ_THRES_SFM_24k;
|
||||
move16();
|
||||
*num_env_bands = sub(*num_sfm, *nb_sfm);
|
||||
|
||||
*sfmsize = band_len_harm;
|
||||
move16();
|
||||
*sfm_start = band_start_harm;
|
||||
move16();
|
||||
*sfm_end = band_end_harm;
|
||||
move16();
|
||||
*start_norm = HVQ_THRES_SFM_24k;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
*num_sfm = SFM_N_HARM_FB;
|
||||
move16();
|
||||
*nb_sfm = HVQ_THRES_SFM_32k;
|
||||
move16();
|
||||
*num_env_bands = sub(*num_sfm, *nb_sfm);
|
||||
|
||||
*sfmsize = band_len_harm;
|
||||
move16();
|
||||
*sfm_start = band_start_harm;
|
||||
move16();
|
||||
*start_norm = HVQ_THRES_SFM_32k;
|
||||
move16();
|
||||
*sfm_end = band_end_harm;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
*num_sfm = NB_SFM;
|
||||
move16();
|
||||
*nb_sfm = *num_sfm;
|
||||
move16();
|
||||
*num_env_bands = NB_SFM;
|
||||
move16();
|
||||
|
||||
*sfmsize = band_len_HQ;
|
||||
move16();
|
||||
*sfm_start = band_start_HQ;
|
||||
move16();
|
||||
*sfm_end = band_end_HQ;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE IF( sub(length, L_FRAME32k) == 0 )
|
||||
{
|
||||
IF ( sub(hqswb_clas, HQ_HARMONIC) == 0 )
|
||||
{
|
||||
*num_sfm = SFM_N_HARM;
|
||||
move16();
|
||||
*nb_sfm = SFM_N_HARM;
|
||||
move16();
|
||||
*num_env_bands = SFM_N_HARM;
|
||||
move16();
|
||||
|
||||
*sfmsize = band_len_harm;
|
||||
move16();
|
||||
*sfm_start = band_start_harm;
|
||||
move16();
|
||||
*sfm_end = band_end_harm;
|
||||
move16();
|
||||
}
|
||||
ELSE IF ( sub(hqswb_clas, HQ_HVQ) == 0 )
|
||||
{
|
||||
IF ( L_sub(core_brate, HQ_24k40) == 0 )
|
||||
{
|
||||
*num_sfm = SFM_N_HARM;
|
||||
move16();
|
||||
*nb_sfm = HVQ_THRES_SFM_24k;
|
||||
move16();
|
||||
*num_env_bands = sub(*num_sfm, *nb_sfm);
|
||||
|
||||
*sfmsize = band_len_harm;
|
||||
move16();
|
||||
*sfm_start = band_start_harm;
|
||||
move16();
|
||||
*sfm_end = band_end_harm;
|
||||
move16();
|
||||
*start_norm = HVQ_THRES_SFM_24k;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
*num_sfm = SFM_N_HARM;
|
||||
move16();
|
||||
*nb_sfm = HVQ_THRES_SFM_32k;
|
||||
move16();
|
||||
*num_env_bands = sub(*num_sfm, *nb_sfm);
|
||||
|
||||
*sfmsize = band_len_harm;
|
||||
move16();
|
||||
*sfm_start = band_start_harm;
|
||||
move16();
|
||||
*start_norm = HVQ_THRES_SFM_32k;
|
||||
move16();
|
||||
*sfm_end = band_end_harm;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE IF ( sub(hqswb_clas, HQ_GEN_SWB) == 0 )
|
||||
{
|
||||
*num_sfm = SFM_N_SWB;
|
||||
move16();
|
||||
*sfmsize = band_len_HQ;
|
||||
move16();
|
||||
*sfm_start = band_start_HQ;
|
||||
move16();
|
||||
*sfm_end = band_end_HQ;
|
||||
move16();
|
||||
|
||||
IF ( L_sub(core_brate, HQ_32k) == 0 )
|
||||
{
|
||||
*hq_generic_offset = HQ_GENERIC_FOFFSET_32K;
|
||||
move16();
|
||||
}
|
||||
ELSE if ( L_sub(core_brate, HQ_24k40) == 0 )
|
||||
{
|
||||
*hq_generic_offset = HQ_GENERIC_FOFFSET_24K4;
|
||||
move16();
|
||||
}
|
||||
|
||||
/* setting start frequency of HQ Generic */
|
||||
IF ( L_sub(core_brate, HQ_32k) == 0 )
|
||||
{
|
||||
*num_env_bands = SFM_N_STA_10k;
|
||||
move16();
|
||||
}
|
||||
ELSE if( L_sub(core_brate, HQ_24k40) == 0 )
|
||||
{
|
||||
*num_env_bands = SFM_N_STA_8k;
|
||||
move16();
|
||||
}
|
||||
|
||||
*nb_sfm = *num_sfm;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* HQ_NORMAL and HQ_TRANSIENT */
|
||||
*num_sfm = SFM_N_SWB;
|
||||
move16();
|
||||
*nb_sfm = *num_sfm;
|
||||
move16();
|
||||
*num_env_bands = SFM_N_SWB;
|
||||
move16();
|
||||
|
||||
*sfmsize = band_len_HQ;
|
||||
move16();
|
||||
*sfm_start = band_start_HQ;
|
||||
move16();
|
||||
*sfm_end = band_end_HQ;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
*num_sfm = SFM_N_WB;
|
||||
move16();
|
||||
*nb_sfm = *num_sfm;
|
||||
move16();
|
||||
*num_env_bands = SFM_N_WB;
|
||||
move16();
|
||||
|
||||
*sfmsize = band_len_wb;
|
||||
move16();
|
||||
*sfm_start = band_start_wb;
|
||||
move16();
|
||||
*sfm_end = band_end_wb;
|
||||
move16();
|
||||
}
|
||||
|
||||
*numnrmibits = extract_l(L_mult0(sub(*num_env_bands, 1), NORMI_BITS));
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+2329
File diff suppressed because it is too large
Load Diff
+189
@@ -0,0 +1,189 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "stl.h" /* required by wmc_tool */
|
||||
|
||||
#include "rom_com_fx.h"
|
||||
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Function hvq_pvq_bitalloc */
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
/* */
|
||||
/* Calculate the number of PVQ bands to code and allocate bits based on */
|
||||
/* the number of available bits. */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
Word16 hvq_pvq_bitalloc_fx(
|
||||
Word16 num_bits, /* i/o: Number of available bits (including gain bits) */
|
||||
const Word32 brate, /* i : bitrate */
|
||||
const Word16 bwidth_fx, /* i : Encoded bandwidth */
|
||||
const Word16 *ynrm, /* i : Envelope coefficients */
|
||||
const Word32 manE_peak, /* i : Peak energy mantissa */
|
||||
const Word16 expE_peak, /* i : Peak energy exponent */
|
||||
Word16 *Rk, /* o : bit allocation for concatenated vector */
|
||||
Word16 *R, /* i/o: Global bit allocation */
|
||||
Word16 *sel_bands, /* o : Selected bands for encoding */
|
||||
Word16 *n_sel_bands /* o : No. of selected bands for encoding */
|
||||
)
|
||||
{
|
||||
Word16 num_bands, band_max_bits;
|
||||
Word16 one_over_band_max_bits;
|
||||
Word16 k;
|
||||
Word16 reciprocal, envSum, expo, align, m, n, indx;
|
||||
Word16 k_max;
|
||||
Word16 k_start;
|
||||
Word32 E_max, E_max5;
|
||||
Word32 tmp, acc;
|
||||
Word32 env_mean;
|
||||
UWord16 lsb;
|
||||
Word16 num_sfm;
|
||||
|
||||
IF (sub(bwidth_fx, FB) == 0)
|
||||
{
|
||||
num_sfm = SFM_N_HARM_FB;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
num_sfm = SFM_N_HARM;
|
||||
}
|
||||
|
||||
IF ( L_sub(brate, HQ_24k40) == 0 )
|
||||
{
|
||||
band_max_bits = HVQ_BAND_MAX_BITS_24k;
|
||||
move16();
|
||||
one_over_band_max_bits = ONE_OVER_HVQ_BAND_MAX_BITS_24k_FX;
|
||||
move16();
|
||||
k_start = HVQ_THRES_SFM_24k;
|
||||
move16();
|
||||
IF (sub(bwidth_fx, FB) == 0)
|
||||
{
|
||||
reciprocal = 2731; /* Q15, 1/(SFM_N_HARM_FB + 1 - k_start) */ move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
reciprocal = 3277; /* Q15, 1/(SFM_N_HARM + 1 - k_start) */ move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
band_max_bits = HVQ_BAND_MAX_BITS_32k;
|
||||
move16();
|
||||
one_over_band_max_bits = ONE_OVER_HVQ_BAND_MAX_BITS_32k_FX;
|
||||
move16();
|
||||
k_start = HVQ_THRES_SFM_32k;
|
||||
move16();
|
||||
IF (sub(bwidth_fx, FB) == 0)
|
||||
{
|
||||
reciprocal = 3641; /* Q15, 1/(SFM_N_HARM_FB + 1 - k_start) */ move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
reciprocal = 4681; /* Q15, 1/(SFM_N_HARM + 1 - k_start) */ move16();
|
||||
}
|
||||
}
|
||||
|
||||
num_bands = mult( num_bits, one_over_band_max_bits ); /* Q0 */
|
||||
num_bits = sub( num_bits, i_mult(num_bands, band_max_bits) ); /* Q0 */
|
||||
|
||||
IF ( sub(num_bits, HVQ_NEW_BAND_BIT_THR) >= 0 )
|
||||
{
|
||||
num_bands = add(num_bands, 1);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
num_bits = add(num_bits, band_max_bits);
|
||||
}
|
||||
|
||||
/* safety check in case of bit errors */
|
||||
if (sub(num_bands, 1) < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
*n_sel_bands = 0;
|
||||
move16();
|
||||
envSum = 0;
|
||||
move16();
|
||||
E_max = L_deposit_l(0);
|
||||
k_max = k_start;
|
||||
move16();
|
||||
FOR ( k = k_start; k < num_sfm; k++ )
|
||||
{
|
||||
indx = ynrm[k];
|
||||
move16();
|
||||
tmp = L_add(0,dicn_fx[indx]); /* Q14 */
|
||||
envSum = add(envSum, indx); /* Since the size of dicn_fx = 40, ynrm[k] must be less than 41. 16 bits are enough for envSum.*/
|
||||
IF (L_sub(tmp, E_max) > 0)
|
||||
{
|
||||
E_max = L_add(0,tmp);
|
||||
k_max = k;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
env_mean = L_mult(envSum, reciprocal); /* env_mean in Q16 */
|
||||
IF (L_sub(L_sub(env_mean, L_deposit_h(ynrm[k_max])), 0x30000L) > 0) /* condition: env_mean - ynrm[k_max] > 3 */
|
||||
{
|
||||
expo = norm_l(E_max);
|
||||
E_max = L_shl(E_max, expo);
|
||||
Mpy_32_16_ss(E_max, 0x7a12, &E_max5, &lsb); /* NB: 5.0e5 = 0x7a12(Q15) x 2^19. */
|
||||
/* True floating point value of E_max*5e5 = E_max5 x 2^(19 - expo - 14).
|
||||
* In this context, the 32-bit E_max5 is in Q0, and
|
||||
* -14 is due to Emax in Q14.
|
||||
* True floating point value of E_peak = manE_peak x 2^(31 - expE_peak - 2*12). See peak_vq_enc_fx().
|
||||
*/
|
||||
|
||||
/* Align the Q-points of the floating point Emax*5e5 and E_peak. */
|
||||
align = sub(expo, expE_peak);
|
||||
align = add(align, (19 - 14) - (31 - 2*12));
|
||||
IF (align < 0)
|
||||
{
|
||||
acc = L_sub(E_max5, L_shl(manE_peak, align));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
acc = L_sub(L_shr(E_max5, align), manE_peak);
|
||||
}
|
||||
|
||||
IF (acc > 0) /* condition: E_max*5.e5 > E_peak */
|
||||
{
|
||||
IF ( sub(band_len_harm[k_max], 96) == 0 )
|
||||
{
|
||||
n = 61;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
QuantaPerDsDirac_fx(band_len_harm[k_max], 1, hBitsN, &n);
|
||||
}
|
||||
m = shl(sub(num_bits, HVQ_PVQ_GAIN_BITS), 3);
|
||||
IF (sub(m, n) >= 0)
|
||||
{
|
||||
IF (sub(num_bands, 1) > 0) /* condition: num_bands > 1 */
|
||||
{
|
||||
sel_bands[*n_sel_bands] = k_max;
|
||||
move16();
|
||||
*n_sel_bands = add(*n_sel_bands, 1);
|
||||
R[k_max] = 1; /* Mark that the band has been encoded for fill_spectrum */ move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate bits */
|
||||
tmp = sub(num_bands,1);
|
||||
FOR (k = 0; k < tmp; k++)
|
||||
{
|
||||
Rk[k] = shl(sub(band_max_bits, HVQ_PVQ_GAIN_BITS), 3);
|
||||
move16();
|
||||
}
|
||||
/* NB: When it exits the above loop, k = num_bands - 1. */
|
||||
Rk[k] = shl(sub(num_bits, HVQ_PVQ_GAIN_BITS), 3);
|
||||
move16();
|
||||
|
||||
return num_bands;
|
||||
}
|
||||
|
||||
Executable
+901
@@ -0,0 +1,901 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#include "options.h"
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
/**********************************************************************/ /*
|
||||
returns an int val, multiplied with transFac
|
||||
**************************************************************************/
|
||||
static Word16 IGF_ApplyTransFac( /**< out: Q0 | multiplication factor */
|
||||
const Word16 val, /**< in: Q15 | input value for multiplication, Q15 */
|
||||
const Word16 transFac /**< in: Q14 | multiplicator for variable val, Q14: 1.25f=0x5000, 1.0f=0x4000, 0.5f=0x2000 */
|
||||
)
|
||||
{
|
||||
Word16 ret;
|
||||
|
||||
if(sub(transFac, 0x4000) == 0)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
ret = shl(val, 1);
|
||||
ret = mac_r(0x00000000, ret, transFac);
|
||||
ret = add(ret, s_and(ret, 1));
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**********************************************************************/ /*
|
||||
maps a given bitrate to the IGF_BITRATE index
|
||||
**************************************************************************/
|
||||
static Word16 IGF_MapBitRateToIndex( /**< out: Q0 | return bit rate index */
|
||||
Word32 bitRate, /**< in: | bitrate */
|
||||
Word16 mode /**< in: | bandwidth mode */
|
||||
, Word16 rf_mode /**< in: | flag to signal the RF mode */
|
||||
)
|
||||
{
|
||||
Word16 bitRateIndex;
|
||||
|
||||
|
||||
bitRateIndex = IGF_BITRATE_UNKNOWN;
|
||||
move16();
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case IGF_MODE_WB:
|
||||
switch (bitRate)
|
||||
{
|
||||
case 13200:
|
||||
if (sub(rf_mode,1) == 0)
|
||||
{
|
||||
bitRateIndex = IGF_BITRATE_RF_WB_13200;
|
||||
}
|
||||
break;
|
||||
case 9600:
|
||||
bitRateIndex = IGF_BITRATE_WB_9600;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
break;
|
||||
case IGF_MODE_SWB:
|
||||
switch (bitRate)
|
||||
{
|
||||
case 9600:
|
||||
bitRateIndex = IGF_BITRATE_SWB_9600;
|
||||
break;
|
||||
case 13200:
|
||||
bitRateIndex = IGF_BITRATE_SWB_13200;
|
||||
if (sub(rf_mode,1) == 0)
|
||||
{
|
||||
bitRateIndex = IGF_BITRATE_RF_SWB_13200;
|
||||
}
|
||||
break;
|
||||
case 16400:
|
||||
bitRateIndex = IGF_BITRATE_SWB_16400;
|
||||
break;
|
||||
case 24400:
|
||||
bitRateIndex = IGF_BITRATE_SWB_24400;
|
||||
break;
|
||||
case 32000:
|
||||
bitRateIndex = IGF_BITRATE_SWB_32000;
|
||||
break;
|
||||
case 48000:
|
||||
bitRateIndex = IGF_BITRATE_SWB_48000;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
break;
|
||||
case IGF_MODE_FB:
|
||||
switch (bitRate)
|
||||
{
|
||||
case 16400:
|
||||
bitRateIndex = IGF_BITRATE_FB_16400;
|
||||
break;
|
||||
case 24400:
|
||||
bitRateIndex = IGF_BITRATE_FB_24400;
|
||||
break;
|
||||
case 32000:
|
||||
bitRateIndex = IGF_BITRATE_FB_32000;
|
||||
break;
|
||||
case 48000:
|
||||
bitRateIndex = IGF_BITRATE_FB_48000;
|
||||
break;
|
||||
case 96000:
|
||||
bitRateIndex = IGF_BITRATE_FB_96000;
|
||||
break;
|
||||
case 128000:
|
||||
bitRateIndex = IGF_BITRATE_FB_128000;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return bitRateIndex;
|
||||
}
|
||||
|
||||
/**********************************************************************/ /*
|
||||
IGF grid setup
|
||||
**************************************************************************/
|
||||
static void IGF_gridSetUp(H_IGF_GRID hGrid, /**< out: | IGF grid handle */
|
||||
Word16 bitRateIndex, /**< in: Q0 | IGF bitrate index */
|
||||
Word32 sampleRate, /**< in: | sample rate */
|
||||
Word16 frameLength, /**< in: | frame length */
|
||||
Word16 transFac, /**< in: | transFac */
|
||||
Word16 igfMinFq /**< in: | IGF minimum frequency indicating lower start frequency for copy up */
|
||||
)
|
||||
{
|
||||
Word16 t;
|
||||
Word16 sfb;
|
||||
const Word16 *swb_offset;
|
||||
Word16 swb_offset_len;
|
||||
Word16 bandwidth;
|
||||
Word16 wrp_sfb;
|
||||
Word16 tmp1;
|
||||
Word16 tmp2;
|
||||
Word32 L_tmp1;
|
||||
Word32 L_tmp2;
|
||||
|
||||
swb_offset = NULL;
|
||||
move16();
|
||||
swb_offset_len = 0;
|
||||
move16();
|
||||
|
||||
SWITCH (bitRateIndex)
|
||||
{
|
||||
case IGF_BITRATE_WB_9600:
|
||||
case IGF_BITRATE_SWB_9600:
|
||||
case IGF_BITRATE_RF_WB_13200:
|
||||
case IGF_BITRATE_RF_SWB_13200:
|
||||
case IGF_BITRATE_SWB_13200:
|
||||
case IGF_BITRATE_SWB_16400:
|
||||
case IGF_BITRATE_SWB_24400:
|
||||
case IGF_BITRATE_SWB_32000:
|
||||
case IGF_BITRATE_SWB_48000:
|
||||
swb_offset = &swb_offset_LB_new[bitRateIndex][1];
|
||||
swb_offset_len = swb_offset_LB_new[bitRateIndex][0];
|
||||
move16();
|
||||
Copy(&igf_whitening_TH[bitRateIndex][0][0], &hGrid->whiteningThreshold[0][0], IGF_MAX_TILES * 2);
|
||||
BREAK;
|
||||
case IGF_BITRATE_FB_16400:
|
||||
case IGF_BITRATE_FB_24400:
|
||||
case IGF_BITRATE_FB_32000:
|
||||
swb_offset = &swb_offset_LB_new[bitRateIndex][1];
|
||||
swb_offset_len = swb_offset_LB_new[bitRateIndex][0];
|
||||
move16();
|
||||
Copy(&igf_whitening_TH[bitRateIndex][0][0], &hGrid->whiteningThreshold[0][0], IGF_MAX_TILES * 2);
|
||||
BREAK;
|
||||
case IGF_BITRATE_FB_48000:
|
||||
case IGF_BITRATE_FB_96000:
|
||||
case IGF_BITRATE_FB_128000:
|
||||
swb_offset = &swb_offset_LB_new[bitRateIndex][1];
|
||||
swb_offset_len = swb_offset_LB_new[bitRateIndex][0];
|
||||
move16();
|
||||
Copy(&igf_whitening_TH[bitRateIndex][0][0], &hGrid->whiteningThreshold[0][0], IGF_MAX_TILES * 2);
|
||||
BREAK;
|
||||
case IGF_BITRATE_UNKNOWN:
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
FOR(sfb = 0; sfb < swb_offset_len; sfb++)
|
||||
{
|
||||
hGrid->swb_offset[sfb] = IGF_ApplyTransFac(swb_offset[sfb], transFac);
|
||||
move16();
|
||||
}
|
||||
|
||||
hGrid->infoIsRefined = 0;
|
||||
move16();
|
||||
frameLength = IGF_ApplyTransFac(frameLength, transFac);
|
||||
tmp2 = norm_s(frameLength);
|
||||
bandwidth = shl(frameLength,tmp2);
|
||||
hGrid->swb_offset_len = extract_l(L_shr(sampleRate, 2));
|
||||
tmp1 = sub(norm_s(hGrid->swb_offset_len), 1);
|
||||
hGrid->swb_offset_len = shl(hGrid->swb_offset_len, tmp1);
|
||||
bandwidth = div_s(hGrid->swb_offset_len, bandwidth);
|
||||
tmp2 = sub(add(tmp2, 1), tmp1);
|
||||
bandwidth = shr(bandwidth, sub(15, tmp2));
|
||||
|
||||
|
||||
hGrid->swb_offset_len = swb_offset_len;
|
||||
move16();
|
||||
hGrid->startSfb = 0;
|
||||
move16();
|
||||
hGrid->stopSfb = sub(hGrid->swb_offset_len, 1);
|
||||
hGrid->startLine = hGrid->swb_offset[ hGrid->startSfb ];
|
||||
move16();
|
||||
hGrid->stopLine = hGrid->swb_offset[ hGrid->stopSfb ];
|
||||
move16();
|
||||
hGrid->startFrequency = imult1616(bandwidth, hGrid->startLine);
|
||||
hGrid->stopFrequency = imult1616(bandwidth, hGrid->stopLine);
|
||||
|
||||
L_tmp1 = L_mult0(igfMinFq, frameLength);
|
||||
tmp1 = sub(norm_l(L_tmp1), 1);
|
||||
L_tmp1 = L_shl(L_tmp1, tmp1);
|
||||
|
||||
tmp2 = norm_l(sampleRate);
|
||||
L_tmp2 = L_shl(sampleRate, tmp2);
|
||||
tmp1 = add(WORD16_BITS-1, sub(tmp1, add(tmp2, 1))); /* takes into account sampleRate >> 1 */
|
||||
|
||||
hGrid->minSrcSubband = div_s(extract_h(L_tmp1), extract_h(L_tmp2));
|
||||
hGrid->minSrcSubband = shr(hGrid->minSrcSubband, tmp1);
|
||||
|
||||
|
||||
hGrid->minSrcSubband = add(hGrid->minSrcSubband, s_and(hGrid->minSrcSubband, 1));
|
||||
hGrid->minSrcFrequency = imult1616(bandwidth, hGrid->minSrcSubband);
|
||||
hGrid->infoGranuleLen = frameLength;
|
||||
move16();
|
||||
hGrid->infoTransFac = transFac;
|
||||
move16();
|
||||
|
||||
hGrid->sfbWrap[0] = 0;
|
||||
move16();
|
||||
hGrid->tile[0] = hGrid->startLine;
|
||||
move16();
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
SWITCH (bitRateIndex)
|
||||
{
|
||||
/* SWB 13200 */
|
||||
case IGF_BITRATE_WB_9600:
|
||||
hGrid->nTiles = 2;
|
||||
move16();
|
||||
wrp_sfb = 2;
|
||||
move16();
|
||||
|
||||
/*1st*/
|
||||
hGrid->sfbWrap[0+1] = wrp_sfb;
|
||||
move16();
|
||||
hGrid->sbWrap[0] = hGrid->minSrcSubband;
|
||||
move16();
|
||||
hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb];
|
||||
move16();
|
||||
|
||||
/*2nd*/
|
||||
hGrid->sfbWrap[1+1] = hGrid->stopSfb;
|
||||
move16();
|
||||
hGrid->sbWrap[1] = hGrid->minSrcSubband;
|
||||
move16();
|
||||
hGrid->tile[1+1] = hGrid->swb_offset[hGrid->stopSfb];
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case IGF_BITRATE_RF_WB_13200:
|
||||
hGrid->nTiles = 2;
|
||||
wrp_sfb = 2;
|
||||
|
||||
/*1st*/
|
||||
hGrid->sfbWrap[0+1] = wrp_sfb;
|
||||
hGrid->sbWrap[0] = hGrid->minSrcSubband;
|
||||
hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb];
|
||||
|
||||
/*2nd*/
|
||||
hGrid->sfbWrap[1+1] = hGrid->stopSfb;
|
||||
hGrid->sbWrap[1] = hGrid->minSrcSubband;
|
||||
hGrid->tile[1+1] = hGrid->swb_offset[hGrid->stopSfb];
|
||||
|
||||
BREAK;
|
||||
case IGF_BITRATE_SWB_9600:
|
||||
hGrid->nTiles = 3;
|
||||
wrp_sfb = 1;
|
||||
|
||||
/*1st*/
|
||||
hGrid->sfbWrap[0+1] = wrp_sfb;
|
||||
hGrid->sbWrap[0] = hGrid->minSrcSubband;
|
||||
hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb];
|
||||
|
||||
/*2nd*/
|
||||
wrp_sfb = 2;
|
||||
hGrid->sfbWrap[1+1] = wrp_sfb;
|
||||
hGrid->sbWrap[1] = hGrid->minSrcSubband + IGF_ApplyTransFac(32, transFac);
|
||||
hGrid->tile[1+1] = hGrid->swb_offset[wrp_sfb];
|
||||
|
||||
/*3rd*/
|
||||
hGrid->sfbWrap[2+1] = hGrid->stopSfb;
|
||||
hGrid->sbWrap[2] = hGrid->minSrcSubband + IGF_ApplyTransFac(46, transFac);
|
||||
hGrid->tile[2+1] = hGrid->swb_offset[hGrid->stopSfb];
|
||||
|
||||
BREAK;
|
||||
case IGF_BITRATE_RF_SWB_13200:
|
||||
hGrid->nTiles = 3;
|
||||
wrp_sfb = 1;
|
||||
|
||||
/*1st*/
|
||||
hGrid->sfbWrap[0+1] = wrp_sfb;
|
||||
hGrid->sbWrap[0] = hGrid->minSrcSubband;
|
||||
hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb];
|
||||
|
||||
/*2nd*/
|
||||
wrp_sfb = 2;
|
||||
hGrid->sfbWrap[1+1] = wrp_sfb;
|
||||
hGrid->sbWrap[1] = hGrid->minSrcSubband + IGF_ApplyTransFac(32, transFac);
|
||||
hGrid->tile[1+1] = hGrid->swb_offset[wrp_sfb];
|
||||
|
||||
/*3rd*/
|
||||
hGrid->sfbWrap[2+1] = hGrid->stopSfb;
|
||||
hGrid->sbWrap[2] = hGrid->minSrcSubband + IGF_ApplyTransFac(46, transFac);
|
||||
hGrid->tile[2+1] = hGrid->swb_offset[hGrid->stopSfb];
|
||||
|
||||
BREAK;
|
||||
|
||||
case IGF_BITRATE_SWB_13200:
|
||||
hGrid->nTiles = 2;
|
||||
move16();
|
||||
wrp_sfb = 4;
|
||||
move16();
|
||||
|
||||
/*1st*/
|
||||
hGrid->sfbWrap[0+1] = wrp_sfb;
|
||||
move16();
|
||||
hGrid->sbWrap[0] = hGrid->minSrcSubband;
|
||||
move16();
|
||||
hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb];
|
||||
move16();
|
||||
|
||||
/*2nd*/
|
||||
hGrid->sfbWrap[1+1] = hGrid->stopSfb;
|
||||
move16();
|
||||
hGrid->sbWrap[1] = add(hGrid->minSrcSubband, IGF_ApplyTransFac(32, transFac));
|
||||
move16();
|
||||
hGrid->tile[1+1] = hGrid->swb_offset[hGrid->stopSfb];
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case IGF_BITRATE_SWB_16400:
|
||||
hGrid->nTiles = 3;
|
||||
move16();
|
||||
wrp_sfb = 4;
|
||||
move16();
|
||||
|
||||
/*1st*/
|
||||
hGrid->sfbWrap[0+1] = wrp_sfb;
|
||||
move16();
|
||||
hGrid->sbWrap[0] = hGrid->minSrcSubband;
|
||||
move16();
|
||||
hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb];
|
||||
move16();
|
||||
|
||||
/*2nd*/
|
||||
hGrid->sfbWrap[1+1] = 6;
|
||||
move16();
|
||||
hGrid->sbWrap[1] = add(hGrid->minSrcSubband, IGF_ApplyTransFac(48, transFac));
|
||||
move16();
|
||||
hGrid->tile[1+1] = hGrid->swb_offset[6];
|
||||
move16();
|
||||
|
||||
/*3nd*/
|
||||
hGrid->sfbWrap[2+1] = hGrid->stopSfb;
|
||||
move16();
|
||||
hGrid->sbWrap[2] = add(hGrid->minSrcSubband, IGF_ApplyTransFac(64, transFac));
|
||||
move16();
|
||||
hGrid->tile[2+1] = hGrid->swb_offset[hGrid->stopSfb];
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case IGF_BITRATE_SWB_24400:
|
||||
case IGF_BITRATE_SWB_32000:
|
||||
hGrid->nTiles = 3;
|
||||
move16();
|
||||
wrp_sfb = 4;
|
||||
move16();
|
||||
|
||||
/*1st*/
|
||||
hGrid->sfbWrap[0+1] = wrp_sfb;
|
||||
move16();
|
||||
hGrid->sbWrap[0] = hGrid->minSrcSubband;
|
||||
move16();
|
||||
hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb];
|
||||
move16();
|
||||
|
||||
/*2nd*/
|
||||
hGrid->sfbWrap[1+1] = 7;
|
||||
move16();
|
||||
hGrid->sbWrap[1] = add(hGrid->minSrcSubband, IGF_ApplyTransFac(32, transFac));
|
||||
move16();
|
||||
hGrid->tile[1+1] = hGrid->swb_offset[7];
|
||||
move16();
|
||||
|
||||
/*3nd*/
|
||||
hGrid->sfbWrap[2+1] = hGrid->stopSfb;
|
||||
move16();
|
||||
hGrid->sbWrap[2] = add(hGrid->minSrcSubband, IGF_ApplyTransFac(64, transFac));
|
||||
move16();
|
||||
hGrid->tile[2+1] = hGrid->swb_offset[hGrid->stopSfb];
|
||||
move16();
|
||||
BREAK;
|
||||
case IGF_BITRATE_SWB_48000:
|
||||
hGrid->nTiles = 1;
|
||||
move16();
|
||||
wrp_sfb = hGrid->stopSfb;
|
||||
move16();
|
||||
|
||||
/*1st*/
|
||||
hGrid->sfbWrap[0+1] = hGrid->stopSfb;
|
||||
move16();
|
||||
hGrid->sbWrap[0] = sub(shl(hGrid->startLine, 1), hGrid->stopLine);
|
||||
move16();
|
||||
hGrid->tile[0+1] = hGrid->swb_offset[hGrid->stopSfb];
|
||||
move16();
|
||||
|
||||
BREAK;
|
||||
case IGF_BITRATE_FB_16400:
|
||||
hGrid->nTiles = 3;
|
||||
move16();
|
||||
wrp_sfb = 4;
|
||||
move16();
|
||||
|
||||
/*1st*/
|
||||
hGrid->sfbWrap[0+1] = wrp_sfb;
|
||||
move16();
|
||||
hGrid->sbWrap[0] = hGrid->minSrcSubband;
|
||||
move16();
|
||||
hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb];
|
||||
move16();
|
||||
wrp_sfb = 7;
|
||||
move16();
|
||||
|
||||
/*2nd*/
|
||||
hGrid->sfbWrap[1+1] = wrp_sfb;
|
||||
move16();
|
||||
hGrid->sbWrap[1] = hGrid->minSrcSubband;
|
||||
move16();
|
||||
hGrid->tile[1+1] = hGrid->swb_offset[wrp_sfb];
|
||||
move16();
|
||||
|
||||
/*3nd*/
|
||||
hGrid->sfbWrap[2+1] = hGrid->stopSfb;
|
||||
move16();
|
||||
hGrid->sbWrap[2] = hGrid->minSrcSubband;
|
||||
move16();
|
||||
hGrid->tile[2+1] = hGrid->swb_offset[hGrid->stopSfb];
|
||||
move16();
|
||||
|
||||
BREAK;
|
||||
|
||||
case IGF_BITRATE_FB_24400:
|
||||
case IGF_BITRATE_FB_32000:
|
||||
hGrid->nTiles = 4;
|
||||
move16();
|
||||
wrp_sfb = 4;
|
||||
move16();
|
||||
|
||||
/*1st*/
|
||||
hGrid->sfbWrap[0+1] = wrp_sfb;
|
||||
move16();
|
||||
hGrid->sbWrap[0] = hGrid->minSrcSubband;
|
||||
move16();
|
||||
hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb];
|
||||
move16();
|
||||
wrp_sfb = 6;
|
||||
move16();
|
||||
|
||||
/*2nd*/
|
||||
hGrid->sfbWrap[1+1] = wrp_sfb;
|
||||
move16();
|
||||
hGrid->sbWrap[1] = add(hGrid->minSrcSubband, IGF_ApplyTransFac(32, transFac));
|
||||
move16();
|
||||
hGrid->tile[1+1] = hGrid->swb_offset[wrp_sfb];
|
||||
move16();
|
||||
wrp_sfb = 9;
|
||||
move16();
|
||||
|
||||
/*3nd*/
|
||||
hGrid->sfbWrap[2+1] = wrp_sfb;
|
||||
move16();
|
||||
hGrid->sbWrap[2] = hGrid->minSrcSubband;
|
||||
move16();
|
||||
hGrid->tile[2+1] = hGrid->swb_offset[wrp_sfb];
|
||||
move16();
|
||||
|
||||
/*4nd*/
|
||||
hGrid->sfbWrap[3+1] = hGrid->stopSfb;
|
||||
move16();
|
||||
hGrid->sbWrap[3] = add(hGrid->minSrcSubband, sub(hGrid->swb_offset[9], hGrid->swb_offset[8]));
|
||||
move16();
|
||||
hGrid->tile[3+1] = hGrid->swb_offset[hGrid->stopSfb];
|
||||
move16();
|
||||
BREAK;
|
||||
case IGF_BITRATE_FB_48000:
|
||||
case IGF_BITRATE_FB_96000:
|
||||
case IGF_BITRATE_FB_128000:
|
||||
hGrid->nTiles = 1;
|
||||
move16();
|
||||
|
||||
/*1st*/
|
||||
hGrid->sfbWrap[0+1] = hGrid->stopSfb;
|
||||
move16();
|
||||
hGrid->sbWrap[0] = sub(shl(hGrid->startLine, 1), hGrid->stopLine);
|
||||
move16();
|
||||
hGrid->tile[0+1] = hGrid->swb_offset[hGrid->stopSfb];
|
||||
move16();
|
||||
|
||||
BREAK;
|
||||
default:
|
||||
assert(0);
|
||||
}/*switch*/
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/* adapt level envelope: */
|
||||
SWITCH (bitRateIndex)
|
||||
{
|
||||
case IGF_BITRATE_RF_WB_13200:
|
||||
case IGF_BITRATE_WB_9600:
|
||||
hGrid->gFactor = 13107/*0.80f Q14*/;
|
||||
move16();
|
||||
hGrid->fFactor = 11469/*0.70f Q14*/;
|
||||
move16();
|
||||
hGrid->lFactor = 9830/*0.60f Q14*/;
|
||||
move16();
|
||||
BREAK;
|
||||
case IGF_BITRATE_SWB_13200:
|
||||
case IGF_BITRATE_FB_16400:
|
||||
case IGF_BITRATE_SWB_16400:
|
||||
hGrid->gFactor = 15237/*0.93f Q14*/;
|
||||
move16();
|
||||
hGrid->fFactor = 3277/*0.20f Q14*/;
|
||||
move16();
|
||||
hGrid->lFactor = 13926/*0.85f Q14*/;
|
||||
move16();
|
||||
BREAK;
|
||||
case IGF_BITRATE_FB_24400:
|
||||
case IGF_BITRATE_SWB_24400:
|
||||
case IGF_BITRATE_FB_32000:
|
||||
case IGF_BITRATE_SWB_32000:
|
||||
hGrid->gFactor = 15811/*0.965f Q14*/;
|
||||
move16();
|
||||
hGrid->fFactor = 3277/*0.20f Q14*/;
|
||||
move16();
|
||||
hGrid->lFactor = 13926/*0.85f Q14*/;
|
||||
move16();
|
||||
BREAK;
|
||||
case IGF_BITRATE_FB_48000:
|
||||
case IGF_BITRATE_SWB_48000:
|
||||
hGrid->gFactor = 16384/*1.00f Q14*/;
|
||||
move16();
|
||||
hGrid->fFactor = 3277/*0.20f Q14*/;
|
||||
move16();
|
||||
hGrid->lFactor = 16384/*1.00f Q14*/;
|
||||
move16();
|
||||
BREAK;
|
||||
case IGF_BITRATE_SWB_9600:
|
||||
case IGF_BITRATE_RF_SWB_13200:
|
||||
default:
|
||||
hGrid->gFactor = 16384/*1.00f Q14*/;
|
||||
move16();
|
||||
hGrid->fFactor = 0/*0.00f Q14*/;
|
||||
move16();
|
||||
hGrid->lFactor = 16384/*1.00f Q14*/;
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (t = add(hGrid->nTiles, 1); t < IGF_MAX_TILES; t++)
|
||||
{
|
||||
hGrid->tile[t] = 0;
|
||||
move16();
|
||||
hGrid->sbWrap[t - 1] = 0;
|
||||
move16();
|
||||
hGrid->sfbWrap[t] = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**********************************************************************/ /*
|
||||
calculates energy per sfb via power spectrum
|
||||
**************************************************************************/
|
||||
void IGFCommonFuncsCalcSfbEnergyPowerSpec(const Word16 startSfb, /**< in: Q0 | start sfb index */
|
||||
const Word16 stopSfb, /**< in: Q0 | stop sfb index */
|
||||
const Word16 *swb_offset, /**< in: Q0 | IGF swb offset table */
|
||||
Word32 *pPowerSpectrum, /**< in: Q31 | power spectrum */
|
||||
Word16 *pPowerSpectrum_exp, /**< in: | Exponent of PowerSpectrum */
|
||||
Word32 *sfbEnergy, /**< out:Q31 | SFB energies , will be initialized inside this function */
|
||||
Word16 *sfbEnergy_exp /**< out: | Exponent of PowerSpectrum */
|
||||
)
|
||||
{
|
||||
Word16/*Q0*/ sfb;
|
||||
Word16/*Q0*/ line;
|
||||
Word32 L_c;
|
||||
|
||||
|
||||
FOR (sfb = startSfb; sfb < stopSfb; sfb++)
|
||||
{
|
||||
sfbEnergy[sfb] = L_deposit_l(0);
|
||||
}
|
||||
IF (NULL == pPowerSpectrum)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FOR (sfb = startSfb; sfb < stopSfb; sfb++)
|
||||
{
|
||||
L_c = L_deposit_l(0);
|
||||
FOR (line = swb_offset[sfb]; line < swb_offset[sfb+1]; line++)
|
||||
{
|
||||
Carry = 0;
|
||||
sfbEnergy[sfb] = L_add_c(sfbEnergy[sfb], pPowerSpectrum[line]);
|
||||
move32();
|
||||
Overflow = 0;
|
||||
L_c = L_macNs(L_c,0,0);
|
||||
}
|
||||
sfbEnergy[sfb] = norm_llQ31(L_c,sfbEnergy[sfb],&(sfbEnergy_exp[sfb]));
|
||||
move32();
|
||||
sfbEnergy_exp[sfb] = add(sfbEnergy_exp[sfb],*pPowerSpectrum_exp);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************/ /*
|
||||
calculate the MDCT square spectrum in the IGF range
|
||||
**************************************************************************/
|
||||
void IGFCommonFuncsMDCTSquareSpec(const Word16 sqrtBgn, /**< in: Q0 | start MDCT subband index */
|
||||
const Word16 sqrtEnd, /**< in: Q0 | stop MDCT subband index */
|
||||
const Word32 *mdctSpec, /**< in: Q31 | MDCT spectrum to square */
|
||||
const Word16 mdctSpec_e, /**< in: | exponent of mdctSpectrum */
|
||||
Word32 *mdctSquareSpec, /**< out:Q31 | MDCT square spectrum */
|
||||
Word16 *mdctSquareSpec_e, /**< out: | exponent of mdctSquareSpec */
|
||||
Word16 indexOffset /**< in: Q0 | index offset */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word16 j;
|
||||
Word16 s1;
|
||||
Word16 tmp;
|
||||
|
||||
|
||||
/* get headroom, only in IGF range */
|
||||
s1 = getScaleFactor32(mdctSpec + sqrtBgn, sub(sqrtEnd, sqrtBgn));
|
||||
|
||||
/* set new exponent */
|
||||
*mdctSquareSpec_e = add(shl(sub(mdctSpec_e, s1), 1), 1);
|
||||
move16();
|
||||
|
||||
/* MDCT square spectrum: MDCT^2 */
|
||||
j = add(sqrtBgn, indexOffset); /* handle indexOffset with care, otherwise memory overruns may occur! */
|
||||
|
||||
|
||||
FOR (i = sqrtBgn; i < sqrtEnd; i++)
|
||||
{
|
||||
tmp = round_fx(L_shl(mdctSpec[i], s1));
|
||||
mdctSquareSpec[j++] = L_mult0(tmp, tmp);
|
||||
move32();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**********************************************************************/ /*
|
||||
write bits to stream
|
||||
**************************************************************************/
|
||||
void IGFCommonFuncsWriteSerialBit(void *st, /**< in: | encoder/decoder state structure */
|
||||
Word16 *pBitOffset, /**< out: Q0 | bit offset */
|
||||
Word16 bit /**< in: Q0 | value of bit */
|
||||
)
|
||||
{
|
||||
|
||||
IF (st)
|
||||
{
|
||||
push_next_indice_fx((Encoder_State_fx*)st, bit, 1);
|
||||
}
|
||||
*pBitOffset = add(*pBitOffset, 1);
|
||||
move16();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**********************************************************************/ /*
|
||||
changes the IGF configuration
|
||||
**************************************************************************/
|
||||
Word16 IGFCommonFuncsIGFConfiguration( /**< out: | error value: 0 -> error, 1 -> ok */
|
||||
Word32 bitRate, /**< in: Q0 | bitrate in bs e.g. 9600 for 9.6kbs */
|
||||
Word16 mode, /**< in: Q0 | bandwidth mode */
|
||||
H_IGF_INFO hIGFInfo /**< out: | IGF info handle */
|
||||
,Word16 rf_mode /**< in: flag to signal the RF mode */
|
||||
)
|
||||
{
|
||||
H_IGF_GRID hGrid;
|
||||
Word16 retValue;
|
||||
Word32 sampleRate;
|
||||
Word16 frameLength;
|
||||
Word16 igfMinFq;
|
||||
Word16 maxHopsize;
|
||||
|
||||
retValue = 0; /* bitrate index is unknown -> error! */ move16();
|
||||
|
||||
/* interface call for reading in settings */
|
||||
hIGFInfo->bitRateIndex = IGF_MapBitRateToIndex(bitRate, mode
|
||||
,rf_mode
|
||||
);
|
||||
|
||||
IF (sub(hIGFInfo->bitRateIndex, IGF_BITRATE_UNKNOWN) != 0)
|
||||
{
|
||||
retValue = 1; /* no error */ move16();
|
||||
|
||||
/* mapping to local values */
|
||||
sampleRate = igfMode[hIGFInfo->bitRateIndex].sampleRate;
|
||||
move32();
|
||||
frameLength = igfMode[hIGFInfo->bitRateIndex].frameLength;
|
||||
move16();
|
||||
igfMinFq = igfMode[hIGFInfo->bitRateIndex].igfMinFq;
|
||||
move16();
|
||||
maxHopsize = igfMode[hIGFInfo->bitRateIndex].maxHopsize;
|
||||
move16();
|
||||
|
||||
/* basic information */
|
||||
hIGFInfo->sampleRate = sampleRate;
|
||||
move32();
|
||||
hIGFInfo->frameLength = frameLength;
|
||||
move16();
|
||||
hIGFInfo->maxHopsize = maxHopsize;
|
||||
move16();
|
||||
hIGFInfo->nfSeed = 0;
|
||||
move16();
|
||||
|
||||
/* set up regular IGF grid for TCX 20 (transfac = 1.f) */
|
||||
hGrid = &hIGFInfo->grid[IGF_GRID_LB_NORM];
|
||||
IGF_gridSetUp(hGrid,
|
||||
hIGFInfo->bitRateIndex,
|
||||
sampleRate,
|
||||
frameLength,
|
||||
16384/*1 Q14*/,
|
||||
igfMinFq);
|
||||
|
||||
/* set up IGF grid for CELP->TCX 20 transitions (transfac = 1.25) */
|
||||
hGrid = &hIGFInfo->grid[IGF_GRID_LB_TRAN];
|
||||
IGF_gridSetUp(hGrid,
|
||||
hIGFInfo->bitRateIndex,
|
||||
sampleRate,
|
||||
frameLength,
|
||||
20480/*1.25 Q14*/,
|
||||
igfMinFq);
|
||||
/* set up IGF grid for TCX 10 (transfac = 0.5) */
|
||||
hGrid = &hIGFInfo->grid[IGF_GRID_LB_SHORT];
|
||||
IGF_gridSetUp(hGrid,
|
||||
hIGFInfo->bitRateIndex,
|
||||
sampleRate,
|
||||
frameLength,
|
||||
8192/*0.50f Q14*/,
|
||||
igfMinFq);
|
||||
}
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
/**********************************************************************/ /*
|
||||
selects cumulative frequency tables and offsets for the IGF SCF arithmetic coder
|
||||
**************************************************************************/
|
||||
Word16 IGFCommonFuncsIGFGetCFTables( /**< out: | error value: 0 -> error, 1 -> ok */
|
||||
Word32 bitRate, /**< in: Q0 | bitrate in bs e.g. 9600 for 9.6kbs */
|
||||
Word16 mode, /**< in: Q0 | bandwidth mode */
|
||||
Word16 rf_mode, /**< in: | flag to signal the RF mode */
|
||||
const Word16 **cf_se00, /**< out: | CF table for t == 0 and f == 0 */
|
||||
const Word16 **cf_se01, /**< out: | CF table for t == 0 and f == 1 */
|
||||
Word16 *cf_off_se01, /**< out: | offset for CF table above */
|
||||
const Word16 **cf_se02, /**< out: | CF tables for t == 0 and f >= 2 */
|
||||
const Word16 **cf_off_se02, /**< out: | offsets for CF tables above */
|
||||
const Word16 **cf_se10, /**< out: | CF table for t == 1 and f == 0 */
|
||||
Word16 *cf_off_se10, /**< out: | offset for CF table above */
|
||||
const Word16 **cf_se11, /**< out: | CF tables for t == 1 and f >= 1 */
|
||||
const Word16 **cf_off_se11 /**< out: | offsets for CF tables above */
|
||||
)
|
||||
{
|
||||
Word16 retValue;
|
||||
Word16 bitRateIndex;
|
||||
|
||||
|
||||
retValue = 0; /* bitrate index is unknown -> error! */ move16();
|
||||
bitRateIndex = IGF_MapBitRateToIndex(bitRate, mode
|
||||
,rf_mode
|
||||
);
|
||||
|
||||
|
||||
IF (sub(bitRateIndex, IGF_BITRATE_UNKNOWN) != 0)
|
||||
{
|
||||
retValue = 1; /* no error */ move16();
|
||||
SWITCH(bitRateIndex)
|
||||
{
|
||||
case IGF_BITRATE_WB_9600:
|
||||
case IGF_BITRATE_RF_WB_13200:
|
||||
case IGF_BITRATE_SWB_9600:
|
||||
case IGF_BITRATE_SWB_13200:
|
||||
case IGF_BITRATE_RF_SWB_13200:
|
||||
case IGF_BITRATE_SWB_16400:
|
||||
case IGF_BITRATE_SWB_24400:
|
||||
case IGF_BITRATE_SWB_32000:
|
||||
case IGF_BITRATE_SWB_48000:
|
||||
*cf_se00 = cf_se00_tab;
|
||||
*cf_se01 = cf_se01_tab[bitRateIndex];
|
||||
*cf_off_se01 = cf_off_se01_tab[bitRateIndex];
|
||||
*cf_se02 = &cf_se02_tab[bitRateIndex][0][0];
|
||||
move16();
|
||||
*cf_off_se02 = &cf_off_se02_tab[bitRateIndex][0];
|
||||
move16();
|
||||
*cf_se10 = &cf_se10_tab[0];
|
||||
move16();
|
||||
*cf_off_se10 = cf_off_se10_tab;
|
||||
*cf_se11 = &cf_se11_tab[0][0][0];
|
||||
move16();
|
||||
*cf_off_se11 = &cf_off_se11_tab[0][0];
|
||||
move16();
|
||||
BREAK;
|
||||
case IGF_BITRATE_FB_16400:
|
||||
case IGF_BITRATE_FB_24400:
|
||||
case IGF_BITRATE_FB_32000:
|
||||
bitRateIndex = add(sub(bitRateIndex, IGF_BITRATE_FB_16400), IGF_BITRATE_SWB_16400);
|
||||
*cf_se00 = cf_se00_tab;
|
||||
*cf_se01 = cf_se01_tab[bitRateIndex];
|
||||
*cf_off_se01 = cf_off_se01_tab[bitRateIndex];
|
||||
*cf_se02 = &cf_se02_tab[bitRateIndex][0][0];
|
||||
move16();
|
||||
*cf_off_se02 = &cf_off_se02_tab[bitRateIndex][0];
|
||||
move16();
|
||||
*cf_se10 = &cf_se10_tab[0];
|
||||
move16();
|
||||
*cf_off_se10 = cf_off_se10_tab;
|
||||
*cf_se11 = &cf_se11_tab[0][0][0];
|
||||
move16();
|
||||
*cf_off_se11 = &cf_off_se11_tab[0][0];
|
||||
move16();
|
||||
BREAK;
|
||||
case IGF_BITRATE_FB_48000:
|
||||
bitRateIndex = add(sub(bitRateIndex, IGF_BITRATE_FB_48000), IGF_BITRATE_SWB_48000);
|
||||
*cf_se00 = cf_se00_tab;
|
||||
*cf_se01 = cf_se01_tab[bitRateIndex];
|
||||
*cf_off_se01 = cf_off_se01_tab[bitRateIndex];
|
||||
*cf_se02 = &cf_se02_tab[bitRateIndex][0][0];
|
||||
move16();
|
||||
*cf_off_se02 = &cf_off_se02_tab[bitRateIndex][0];
|
||||
move16();
|
||||
*cf_se10 = &cf_se10_tab[0];
|
||||
move16();
|
||||
*cf_off_se10 = cf_off_se10_tab;
|
||||
*cf_se11 = &cf_se11_tab[0][0][0];
|
||||
move16();
|
||||
*cf_off_se11 = &cf_off_se11_tab[0][0];
|
||||
move16();
|
||||
BREAK;
|
||||
case IGF_BITRATE_FB_96000:
|
||||
case IGF_BITRATE_FB_128000:
|
||||
bitRateIndex = IGF_BITRATE_SWB_48000;
|
||||
move16();
|
||||
*cf_se00 = cf_se00_tab;
|
||||
*cf_se01 = cf_se01_tab[bitRateIndex];
|
||||
*cf_off_se01 = cf_off_se01_tab[bitRateIndex];
|
||||
*cf_se02 = &cf_se02_tab[bitRateIndex][0][0];
|
||||
move16();
|
||||
*cf_off_se02 = &cf_off_se02_tab[bitRateIndex][0];
|
||||
move16();
|
||||
*cf_se10 = &cf_se10_tab[0];
|
||||
move16();
|
||||
*cf_off_se10 = cf_off_se10_tab;
|
||||
*cf_se11 = &cf_se11_tab[0][0][0];
|
||||
move16();
|
||||
*cf_off_se11 = &cf_off_se11_tab[0][0];
|
||||
move16();
|
||||
BREAK;
|
||||
case IGF_BITRATE_UNKNOWN:
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
Executable
+1187
File diff suppressed because it is too large
Load Diff
Executable
+173
@@ -0,0 +1,173 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*========================================================================*/
|
||||
/* FUNCTION : int_lsp4_fx() */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* PURPOSE : Interpolate LSPs find the A[z] parameters for all subframes */
|
||||
/* by interpolating between old end-frame LSPs, current */
|
||||
/* mid-frame LSPs and current end-frame LSPs */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16) L_frame : length of the frame */
|
||||
/* _ (Word16) m : order of LP filter */
|
||||
/* _ (Word16) clas : signal frame class */
|
||||
/* _ (Word16[]) lsp_old : LSPs from past frame Q15 */
|
||||
/* _ (Word16[]) lsp_mid : LSPs from mid-frame Q15 */
|
||||
/* _ (Word16[]) lsp_new : LSPs from present frame Q15 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*) Aq : LP coefficients in both subframes Q12 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*========================================================================*/
|
||||
void int_lsp4_fx(
|
||||
const Word16 L_frame, /* i : length of the frame */
|
||||
const Word16 lsp_old[], /* i : LSPs from past frame Q15*/
|
||||
const Word16 lsp_mid[], /* i : LSPs from mid-frame Q15*/
|
||||
const Word16 lsp_new[], /* i : LSPs from present frame Q15*/
|
||||
Word16 *Aq, /* o : LP coefficients in both subframes Q12*/
|
||||
const Word16 m, /* i : order of LP filter */
|
||||
Word16 relax_prev_lsf_interp /* i : relax prev frame lsf interp after erasure */
|
||||
)
|
||||
{
|
||||
Word16 lsp[M16k];
|
||||
Word16 i,j, k;
|
||||
Word32 L_tmp;
|
||||
const Word16 *pt_int_coeffs;
|
||||
|
||||
IF( sub(L_frame,L_FRAME) == 0)
|
||||
{
|
||||
IF ( sub(relax_prev_lsf_interp,1) == 0)
|
||||
{
|
||||
pt_int_coeffs = interpol_frac_mid_relaxprev_12k8_fx;
|
||||
}
|
||||
ELSE IF ( sub(relax_prev_lsf_interp,2) == 0 )
|
||||
{
|
||||
pt_int_coeffs = interpol_frac_mid_FEC_fx;
|
||||
}
|
||||
ELSE IF ( sub(relax_prev_lsf_interp,-1) == 0 )
|
||||
{
|
||||
pt_int_coeffs = interpol_frac_mid_relaxprev_pred_12k8_fx;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
pt_int_coeffs = interpol_frac_mid_fx;
|
||||
}
|
||||
}
|
||||
ELSE /* L_frame == L_FRAME16k */
|
||||
{
|
||||
IF ( sub(relax_prev_lsf_interp,1) == 0 )
|
||||
{
|
||||
pt_int_coeffs = interpol_frac_mid_relaxprev_16k_fx;
|
||||
}
|
||||
ELSE IF ( sub(relax_prev_lsf_interp,2) == 0 )
|
||||
{
|
||||
pt_int_coeffs = interpol_frac_mid_16k_FEC_fx;
|
||||
}
|
||||
ELSE IF ( sub(relax_prev_lsf_interp,-1) == 0 )
|
||||
{
|
||||
pt_int_coeffs = interpol_frac_mid_relaxprev_pred_16k_fx;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
pt_int_coeffs = interpol_frac_mid_16k_fx;
|
||||
}
|
||||
}
|
||||
k = sub(shr(L_frame,6),1);
|
||||
FOR( j=0; j<k; j++ )
|
||||
{
|
||||
FOR( i=0; i<m; i++ )
|
||||
{
|
||||
L_tmp = L_mult(lsp_old[i], *pt_int_coeffs); /*Q31 */
|
||||
L_tmp = L_mac(L_tmp, lsp_mid[i], *(pt_int_coeffs+1)); /*Q31 */
|
||||
lsp[i] = mac_r(L_tmp, lsp_new[i], *(pt_int_coeffs+2));
|
||||
move16();
|
||||
}
|
||||
pt_int_coeffs += 3;
|
||||
move16();
|
||||
|
||||
E_LPC_f_lsp_a_conversion( lsp, Aq, m );
|
||||
Aq += (m+1);
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Last subframe */
|
||||
E_LPC_f_lsp_a_conversion( lsp_new, Aq, m );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* int_lsp_fx()
|
||||
*
|
||||
* Find the interpolated LSP parameters for all subframes
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
void int_lsp_fx(
|
||||
const Word16 L_frame, /* i : length of the frame */
|
||||
const Word16 lsp_old[], /* i : LSPs from past frame */
|
||||
const Word16 lsp_new[], /* i : LSPs from present frame */
|
||||
Word16 *Aq, /* o : LP coefficients in both subframes */
|
||||
const Word16 m, /* i : order of LP filter */
|
||||
const Word16 *int_coeffs, /* i : interpolation coefficients */
|
||||
const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */
|
||||
)
|
||||
{
|
||||
Word16 lsp[M], fnew, fold;
|
||||
Word16 i, k;
|
||||
const Word16 *pt_int_coeffs=NULL;
|
||||
Word32 L_tmp;
|
||||
Word16 tmp;
|
||||
|
||||
tmp = shr(L_frame,6); /*L_frame/L_SUBFR */
|
||||
|
||||
IF( sub(L_frame,L_FRAME) == 0 )
|
||||
{
|
||||
pt_int_coeffs = int_coeffs;
|
||||
move16();
|
||||
}
|
||||
ELSE /* L_frame == L_FRAME16k */
|
||||
{
|
||||
pt_int_coeffs = interpol_frac_16k_fx;
|
||||
}
|
||||
FOR( k=0; k<tmp; k++ )
|
||||
{
|
||||
fnew = pt_int_coeffs[k];
|
||||
move16();
|
||||
fold = sub(32767, fnew); /* 1.0 - fac_new */
|
||||
if (fold != 0)
|
||||
fold = add(fold, 1);
|
||||
FOR (i = 0; i < m; i++)
|
||||
{
|
||||
L_tmp = L_mult(lsp_old[i], fold);
|
||||
L_tmp = L_mac(L_tmp, lsp_new[i], fnew);
|
||||
if (fold == 0)
|
||||
L_tmp = L_mac(L_tmp, lsp_new[i], 1); /* 'fnew' should have been 32768 */
|
||||
lsp[i] = round_fx(L_tmp);
|
||||
}
|
||||
IF ( Opt_AMR_WB )
|
||||
{
|
||||
E_LPC_f_isp_a_conversion( lsp, Aq, m );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
E_LPC_f_lsp_a_conversion(lsp, Aq, m);
|
||||
}
|
||||
Aq +=(m+1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* interleave_spectrum_fx()
|
||||
*
|
||||
* Interleave the spectrum
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void interleave_spectrum_fx(
|
||||
Word32 *coefs, /* i/o: input and output coefficients Q12 */
|
||||
const Word16 length /* i : length of spectrum Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i, j, k;
|
||||
Word32 *p1, *p2, *p3, *p4;
|
||||
Word32 *p_out;
|
||||
Word32 coefs_out[L_FRAME48k];
|
||||
Word16 sublen[3] = {240, 160, 80};
|
||||
Word16 grps;
|
||||
const Word16 *bw;
|
||||
const Word16 *cnt;
|
||||
|
||||
/* Common inits */
|
||||
p1 = coefs;
|
||||
p_out = coefs_out;
|
||||
|
||||
IF ( sub(length, L_FRAME48k) == 0 )
|
||||
{
|
||||
bw = intl_bw_48;
|
||||
cnt = intl_cnt_48;
|
||||
grps = N_INTL_GRP_48;
|
||||
move16();
|
||||
p2 = p1 + sublen[0];
|
||||
p3 = p2 + sublen[0];
|
||||
p4 = p3 + sublen[0];
|
||||
}
|
||||
ELSE IF( sub(length, L_FRAME32k) == 0 )
|
||||
{
|
||||
bw = intl_bw_32;
|
||||
cnt = intl_cnt_32;
|
||||
grps = N_INTL_GRP_32;
|
||||
move16();
|
||||
p2 = p1 + sublen[1];
|
||||
p3 = p2 + sublen[1];
|
||||
p4 = p3 + sublen[1];
|
||||
}
|
||||
ELSE /* length == L_FRAME16k */
|
||||
{
|
||||
bw = intl_bw_16;
|
||||
cnt = intl_cnt_16;
|
||||
grps = N_INTL_GRP_16;
|
||||
move16();
|
||||
p2 = p1 + sublen[2];
|
||||
p3 = p2 + sublen[2];
|
||||
p4 = p3 + sublen[2];
|
||||
}
|
||||
|
||||
FOR (i = 0; i < grps; i++)
|
||||
{
|
||||
FOR (j = 0; j < cnt[i]; j++)
|
||||
{
|
||||
FOR (k = 0; k < bw[i]; k++)
|
||||
{
|
||||
*p_out++ = *p1++;
|
||||
move32();
|
||||
}
|
||||
FOR (k = 0; k < bw[i]; k++)
|
||||
{
|
||||
*p_out++ = *p2++;
|
||||
move32();
|
||||
}
|
||||
FOR (k = 0; k < bw[i]; k++)
|
||||
{
|
||||
*p_out++ = *p3++;
|
||||
move32();
|
||||
}
|
||||
FOR (k = 0; k < bw[i]; k++)
|
||||
{
|
||||
*p_out++ = *p4++;
|
||||
move32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* For FB the interleaved spectrum is 800 samples */
|
||||
Copy32(coefs_out, coefs, (Word16)(p_out - coefs_out));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* de_interleave_spectrum_fx()
|
||||
*
|
||||
* Deinterleave the spectrum
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void de_interleave_spectrum_fx(
|
||||
Word32 *coefs, /* i/o: input and output coefficients Q12 */
|
||||
const Word16 length /* i : length of spectrum Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i, j, k;
|
||||
Word32 *p1, *p2, *p3, *p4;
|
||||
Word32 *p_in;
|
||||
Word32 coefs_out[L_FRAME48k];
|
||||
Word16 sublen[] = {80, 160, 240, 320, 480, 720};
|
||||
Word16 grps;
|
||||
const Word16 *bw;
|
||||
const Word16 *cnt;
|
||||
|
||||
/* common for all groups */
|
||||
p1 = coefs_out;
|
||||
|
||||
IF ( sub(length, L_FRAME48k) == 0 )
|
||||
{
|
||||
bw = intl_bw_48;
|
||||
cnt = intl_cnt_48;
|
||||
grps = N_INTL_GRP_48;
|
||||
move16();
|
||||
|
||||
p2 = coefs_out + sublen[2]; /* 240, length/4 */
|
||||
p3 = coefs_out + sublen[4]; /* 480, 2*length/4 */
|
||||
p4 = coefs_out + sublen[5]; /* 720, 3*length/4 */
|
||||
}
|
||||
ELSE IF( sub(length, L_FRAME32k) == 0 )
|
||||
{
|
||||
bw = intl_bw_32;
|
||||
cnt = intl_cnt_32;
|
||||
grps = N_INTL_GRP_32;
|
||||
move16();
|
||||
|
||||
p2 = coefs_out + sublen[1]; /* 160 */
|
||||
p3 = coefs_out + sublen[3]; /* 320 */
|
||||
p4 = coefs_out + sublen[4]; /* 480 */
|
||||
}
|
||||
ELSE /* length == L_FRAME16k */
|
||||
{
|
||||
bw = intl_bw_16;
|
||||
cnt = intl_cnt_16;
|
||||
grps = N_INTL_GRP_16;
|
||||
move16();
|
||||
|
||||
p2 = coefs_out + sublen[0]; /* 80 */
|
||||
p3 = coefs_out + sublen[1]; /* 160 */
|
||||
p4 = coefs_out + sublen[2]; /* 240 */
|
||||
}
|
||||
|
||||
set32_fx(coefs_out, 0, L_FRAME48k);
|
||||
p_in = coefs;
|
||||
|
||||
FOR (i = 0; i < grps; i++)
|
||||
{
|
||||
FOR (j = 0; j < cnt[i]; j++)
|
||||
{
|
||||
FOR (k = 0; k < bw[i]; k++)
|
||||
{
|
||||
*p1++ = *p_in++;
|
||||
move32();
|
||||
}
|
||||
FOR (k = 0; k < bw[i]; k++)
|
||||
{
|
||||
*p2++ = *p_in++;
|
||||
move32();
|
||||
}
|
||||
FOR (k = 0; k < bw[i]; k++)
|
||||
{
|
||||
*p3++ = *p_in++;
|
||||
move32();
|
||||
}
|
||||
FOR (k = 0; k < bw[i]; k++)
|
||||
{
|
||||
*p4++ = *p_in++;
|
||||
move32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Copy32(coefs_out, coefs, length);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Executable
+80
@@ -0,0 +1,80 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* tables definition */
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
Word32 Interpol_lc_fx( /* o : interpolated value Qx+16 */
|
||||
const Word16 *x, /* i : input vector Q0 */
|
||||
const Word16 *win, /* i : interpolation window Q14 */
|
||||
const Word16 frac, /* i : fraction (0..up_samp) Q0 */
|
||||
const Word16 up_samp, /* i : upsampling factor Q0 */
|
||||
const Word16 nb_coef /* i : number of coefficients Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
const Word16 *c1, *c2, *x2;
|
||||
Word32 L_sum;
|
||||
|
||||
x2 = &x[1];
|
||||
c1 = &win[frac];
|
||||
c2 = &win[sub(up_samp,frac)];
|
||||
L_sum = L_mult0(*x--, *c1);
|
||||
L_sum = L_mac0(L_sum, *x2++, *c2);
|
||||
FOR (i=1; i<nb_coef; i++)
|
||||
{
|
||||
c2 += up_samp; /* move16() not needed, since the coefficient can be rearrange in bit exact way */
|
||||
c1 += up_samp;
|
||||
/* Using L_mac0 limits the risk of saturation during the loop, saturation may occures after the loop */
|
||||
if (*c1)
|
||||
{
|
||||
L_sum = L_mac0(L_sum, *x, *c1);
|
||||
}
|
||||
--x;
|
||||
if (*c2)
|
||||
{
|
||||
L_sum = L_mac0(L_sum, *x2, *c2);
|
||||
}
|
||||
++x2;
|
||||
}
|
||||
L_sum = L_shl(L_sum,1);
|
||||
|
||||
return L_sum;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* Interpol_4()
|
||||
*
|
||||
* For interpolating the normalized correlation with 1/4 resolution.
|
||||
*--------------------------------------------------------------------------*/
|
||||
Word16 Interpol_4( /* o : interpolated value */
|
||||
Word16 * x, /* i : input vector */
|
||||
Word16 frac /* i : fraction (-4..+3) */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 L_sum;
|
||||
|
||||
x = x - L_INTERPOL1 + 1;
|
||||
|
||||
L_sum = L_mult(x[0], (inter4_1_fx+UP_SAMP-1)[-frac]);
|
||||
FOR (i = 1; i < 2 * L_INTERPOL1; i++)
|
||||
{
|
||||
/*
|
||||
* Here, additions with UP_SAMP are not counted
|
||||
* because, the window could easily be modified
|
||||
* so that the values needed are contiguous.
|
||||
*/
|
||||
frac -= UP_SAMP;
|
||||
L_sum = L_mac(L_sum, x[i], (inter4_1_fx+UP_SAMP-1)[-frac]);
|
||||
}
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
/* Here, saturation might occur by intention */
|
||||
L_sum = L_shl(L_sum,1);
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
return round_fx(L_sum);
|
||||
}
|
||||
+329
@@ -0,0 +1,329 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
void E_LPC_isf_isp_conversion(const Word16 isf[], Word16 isp[], const Word16 m);
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* isf_dec_amr_wb()
|
||||
*
|
||||
* Decoding of ISF parameters in AMR-WB IO mode
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
void isf_dec_amr_wb_fx(
|
||||
Decoder_State_fx *st, /* i/o: State structure */
|
||||
Word16 *Aq, /* o : quantized A(z) for 4 subframes */
|
||||
Word16 *isf_new, /* o : de-quantized ISF vector */
|
||||
Word16 *isp_new /* o : de-quantized ISP vector */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word16 indice[7];
|
||||
Word32 L_tmp;
|
||||
|
||||
set16_fx( indice, -1, 7 );
|
||||
|
||||
/*---------------------------------*
|
||||
* ISF de-quantization of SID frames
|
||||
*---------------------------------*/
|
||||
|
||||
IF ( L_sub(st->core_brate_fx,SID_1k75) == 0 )
|
||||
{
|
||||
|
||||
indice[0] = (Word16)get_next_indice_fx( st, 6 );
|
||||
move16();
|
||||
indice[1] = (Word16)get_next_indice_fx( st, 6 );
|
||||
move16();
|
||||
indice[2] = (Word16)get_next_indice_fx( st, 6 );
|
||||
move16();
|
||||
indice[3] = (Word16)get_next_indice_fx( st, 5 );
|
||||
move16();
|
||||
indice[4] = (Word16)get_next_indice_fx( st, 5 );
|
||||
move16();
|
||||
|
||||
disf_ns_28b_fx( indice, isf_new );
|
||||
|
||||
reorder_isf_fx( isf_new, ISF_GAP_FX, M, Fs_2);
|
||||
|
||||
E_LPC_isf_isp_conversion( isf_new, isp_new, M);
|
||||
/* return if SID frame (conversion to A(z) done in the calling function) */
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* ISF de-quantization of all other frames
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
IF( L_sub(st->core_brate_fx,ACELP_6k60) == 0 )
|
||||
{
|
||||
indice[0] = (Word16)get_next_indice_fx( st, 8 );
|
||||
move16();
|
||||
indice[1] = (Word16)get_next_indice_fx( st, 8 );
|
||||
move16();
|
||||
indice[2] = (Word16)get_next_indice_fx( st, 7 );
|
||||
move16();
|
||||
indice[3] = (Word16)get_next_indice_fx( st, 7 );
|
||||
move16();
|
||||
indice[4] = (Word16)get_next_indice_fx( st, 6 );
|
||||
move16();
|
||||
|
||||
disf_2s_36b_fx( indice, isf_new, st->mem_AR_fx, st->mem_MA_fx, 1 );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
indice[0] = (Word16)get_next_indice_fx( st, 8 );
|
||||
move16();
|
||||
indice[1] = (Word16)get_next_indice_fx( st, 8 );
|
||||
move16();
|
||||
indice[2] = (Word16)get_next_indice_fx( st, 6 );
|
||||
move16();
|
||||
indice[3] = (Word16)get_next_indice_fx( st, 7 );
|
||||
move16();
|
||||
indice[4] = (Word16)get_next_indice_fx( st, 7 );
|
||||
move16();
|
||||
indice[5] = (Word16)get_next_indice_fx( st, 5 );
|
||||
move16();
|
||||
indice[6] = (Word16)get_next_indice_fx( st, 5 );
|
||||
move16();
|
||||
|
||||
disf_2s_46b_fx( indice, isf_new, st->mem_AR_fx, st->mem_MA_fx,1 );
|
||||
}
|
||||
reorder_isf_fx( isf_new, ISF_GAP_FX, M, Fs_2 );
|
||||
/* convert quantized ISFs to ISPs */
|
||||
E_LPC_isf_isp_conversion( isf_new, isp_new, M);
|
||||
|
||||
/*-------------------------------------------------------------------------------------*
|
||||
* FEC - update adaptive mean ISF vector
|
||||
*-------------------------------------------------------------------------------------*/
|
||||
|
||||
FOR ( i=0; i<M; i++ )
|
||||
{
|
||||
/*st->lsf_adaptive_mean[i] = (st->lsfoldbfi1[i] + st->lsfoldbfi0[i] + isf_new[i]) / 3;*/
|
||||
L_tmp = L_mult(st->lsfoldbfi1_fx[i], 10923);
|
||||
L_tmp = L_mac(L_tmp, st->lsfoldbfi0_fx[i], 10923);
|
||||
st->lsf_adaptive_mean_fx[i] = round_fx(L_mac(L_tmp, isf_new[i], 10923));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------*
|
||||
* ISP interpolation
|
||||
* A(z) calculation
|
||||
*-------------------------------------------------------------------------------------*/
|
||||
|
||||
if(st->rate_switching_reset)
|
||||
{
|
||||
/*extrapolation instead of interpolation*/
|
||||
Copy(isp_new, st->lsp_old_fx, M);
|
||||
Copy(isf_new, st->lsf_old_fx, M);
|
||||
}
|
||||
|
||||
/* ISP interpolation and A(z) calculation */
|
||||
int_lsp_fx( L_FRAME, st->lsp_old_fx, isp_new, Aq, M, interpol_isp_amr_wb_fx, 1 );
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Check ISF stability : distance between old ISF and current ISF
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
st->stab_fac_fx = lsf_stab_fx( isf_new, st->lsf_old_fx, 1, st->L_frame_fx );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* disf_ns_28b()
|
||||
*
|
||||
* ISF de-quantizer for SID_1k75 frames (only for AMR-WB IO mode)
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void disf_ns_28b_fx(
|
||||
Word16 *indice, /* i : quantized indices (use indice[0] = -1 in the decoder) */
|
||||
Word16 *isf_q /* o : ISF in the frequency domain (0..6400) */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
|
||||
FOR (i = 0; i < 2; i++)
|
||||
{
|
||||
isf_q[i] = dico1_ns_28b_fx[indice[0]*2+i];
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 0; i < 3; i++)
|
||||
{
|
||||
isf_q[i+2] = dico2_ns_28b_fx[indice[1]*3+i];
|
||||
move16();
|
||||
isf_q[i+5] = dico3_ns_28b_fx[indice[2]*3+i];
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 0; i < 4; i++)
|
||||
{
|
||||
isf_q[i+8] = dico4_ns_28b_fx[indice[3]*4+i];
|
||||
move16();
|
||||
isf_q[i+12] = dico5_ns_28b_fx[indice[4]*4+i];
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i=0; i<M; i++)
|
||||
{
|
||||
isf_q[i] = add(isf_q[i] , mean_isf_noise_amr_wb_fx[i]);
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* disf_2s_46b()
|
||||
*
|
||||
* ISF de-quantizer for 46b. codebooks (only for AMR-WB IO mode)
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void disf_2s_46b_fx(
|
||||
Word16 *indice, /* i : quantized indices (use indice[0] = -1 in the decoder) */
|
||||
Word16 *isf_q, /* o : quantized ISFs in the cosine domain */
|
||||
Word16 *mem_AR, /* o : quantizer memory for AR model */
|
||||
Word16 *mem_MA, /* i/o: quantizer memory for MA model */
|
||||
const Word16 enc_dec /* i : encoder (0), decoder (1) G722.2 FER */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
|
||||
IF (enc_dec != 0) /* Redirection for G722.2 compatibility */
|
||||
{
|
||||
i = 0;
|
||||
move16();
|
||||
WHILE (sub(Indirect_dico1[i], indice[0]) != 0)
|
||||
{
|
||||
i = add(i, 1);
|
||||
}
|
||||
indice[0] = i;
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 0; i < 9; i++)
|
||||
{
|
||||
isf_q[i] = dico1_isf_fx[indice[0]*9+i];
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 0; i < 7; i++)
|
||||
{
|
||||
isf_q[i+9] = dico2_isf_fx[indice[1]*7+i];
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 0; i < 3; i++)
|
||||
{
|
||||
isf_q[i] = add(isf_q[i],dico21_isf_46b_fx[indice[2]*3+i]);
|
||||
move16();
|
||||
isf_q[i+3] = add(isf_q[i+3], dico22_isf_46b_fx[indice[3]*3+i]);
|
||||
move16();
|
||||
isf_q[i+6] = add(isf_q[i+6], dico23_isf_46b_fx[indice[4]*3+i]);
|
||||
move16();
|
||||
isf_q[i+9] = add(isf_q[i+9], dico24_isf_46b_fx[indice[5]*3+i]);
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 0; i < 4; i++)
|
||||
{
|
||||
isf_q[i+12] = add(isf_q[i+12], dico25_isf_46b_fx[indice[6]*4+i]);
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 0; i < M; i++)
|
||||
{
|
||||
mem_AR[i] = add(isf_q[i], mult_r(MU_MA_FX, mem_MA[i]));
|
||||
move16(); /* Update with quantized ISF vector for AR model */
|
||||
mem_MA[i] = isf_q[i];
|
||||
move16(); /* Update with quantized prediction error for MA model */
|
||||
isf_q[i] = add(mem_AR[i], mean_isf_amr_wb_fx[i]);
|
||||
move16(); /* Quantized ISFs */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* disf_2s_36b()
|
||||
*
|
||||
* ISF de-quantizer for 36b. codebooks (only for AMR-WB IO mode)
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void disf_2s_36b_fx(
|
||||
Word16 *indice, /* i : quantized indices (use indice[0] = -1 in the decoder) */
|
||||
Word16 *isf_q, /* o : quantized ISFs in the cosine domain */
|
||||
Word16 *mem_AR, /* i/o: quantizer memory for AR model */
|
||||
Word16 *mem_MA, /* i/o: quantizer memory for MA model */
|
||||
const Word16 enc_dec /* i : encoder (0), decoder (1) G722.2 FER */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
const Word16 *pt_dico1;
|
||||
|
||||
IF (enc_dec != 0) /* Redirection for G722.2 interoperability */
|
||||
{
|
||||
i = 0;
|
||||
move16();
|
||||
WHILE (sub(Indirect_dico1[i], indice[0]) != 0)
|
||||
{
|
||||
i = add(i,1);
|
||||
}
|
||||
indice[0] = i;
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
pt_dico1 = dico1_isf_fx; /* Pointer of the 1st stage, 1st plit */
|
||||
|
||||
FOR (i = 0; i < 9; i++)
|
||||
{
|
||||
isf_q[i] = pt_dico1[indice[0]*9+i];
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 0; i < 7; i++)
|
||||
{
|
||||
isf_q[i+9] = dico2_isf_fx[indice[1]*7+i];
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 0; i < 5; i++)
|
||||
{
|
||||
isf_q[i] = add(isf_q[i], dico21_isf_36b_fx[indice[2]*5+i]);
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 0; i < 4; i++)
|
||||
{
|
||||
isf_q[i+5] = add(isf_q[i+5], dico22_isf_36b_fx[indice[3]*4+i]);
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 0; i < 7; i++)
|
||||
{
|
||||
isf_q[i+9] = add(isf_q[i+9], dico23_isf_36b_fx[indice[4]*7+i]);
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 0; i < M; i++)
|
||||
{
|
||||
mem_AR[i] = add(isf_q[i], mult_r(MU_MA_FX, mem_MA[i]));
|
||||
move16(); /* Update with quantized ISF vector for AR model */
|
||||
mem_MA[i] = isf_q[i];
|
||||
move16(); /* Update with quantized prediction error for MA model */
|
||||
isf_q[i] = mem_AR[i] + mean_isf_amr_wb_fx[i];
|
||||
move16(); /* Quantized ISFs */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+130
@@ -0,0 +1,130 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "prot_fx.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "stl.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
#define kLagWinThGain1 19661 /* 0.6f in Q15 */
|
||||
#define kLagWinThGain2 9830 /* 0.3f in Q15 */
|
||||
|
||||
/*-------------------------------------------------------------*
|
||||
* procedure lag_wind: *
|
||||
* ~~~~~~~~~ *
|
||||
* lag windowing of the autocorrelations *
|
||||
*-------------------------------------------------------------*/
|
||||
|
||||
void lag_wind(
|
||||
Word16 r_h[], /* in/out: autocorrelations */
|
||||
Word16 r_l[], /* in/out: autocorrelations */
|
||||
Word16 m, /* input : order of LP filter */
|
||||
Word32 sr, /* input : sampling rate */
|
||||
Word16 strength /* input : LAGW_WEAK, LAGW_MEDIUM, or LAGW_STRONG */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 tmp;
|
||||
const Word16 *wnd_h, *wnd_l;
|
||||
|
||||
|
||||
assert(0 <= strength && strength <= NUM_LAGW_STRENGTHS);
|
||||
SWITCH (sr)
|
||||
{
|
||||
case 8000:
|
||||
assert(m <= 16);
|
||||
assert(strength == LAGW_STRONG);
|
||||
wnd_h = lag_window_8k[0];
|
||||
wnd_l = lag_window_8k[1];
|
||||
BREAK;
|
||||
case 12800:
|
||||
assert(m <= 16);
|
||||
wnd_h = lag_window_12k8[strength][0];
|
||||
wnd_l = lag_window_12k8[strength][1];
|
||||
BREAK;
|
||||
case 16000:
|
||||
assert(m <= 16);
|
||||
wnd_h = lag_window_16k[strength][0];
|
||||
wnd_l = lag_window_16k[strength][1];
|
||||
BREAK;
|
||||
case 24000:
|
||||
case 25600:
|
||||
assert(m <= 16);
|
||||
wnd_h = lag_window_25k6[strength][0];
|
||||
wnd_l = lag_window_25k6[strength][1];
|
||||
BREAK;
|
||||
case 32000:
|
||||
assert(m <= 16);
|
||||
wnd_h = lag_window_32k[strength][0];
|
||||
wnd_l = lag_window_32k[strength][1];
|
||||
BREAK;
|
||||
case 48000:
|
||||
assert(m <= 16);
|
||||
assert(strength == LAGW_STRONG);
|
||||
wnd_h = lag_window_48k[0];
|
||||
wnd_l = lag_window_48k[1];
|
||||
BREAK;
|
||||
default:
|
||||
assert(!"Lag window not implemented for this sampling rate");
|
||||
return;
|
||||
}
|
||||
|
||||
FOR (i = 1; i <= m; i++)
|
||||
{
|
||||
tmp = Mpy_32(r_h[i], r_l[i], wnd_h[i-1], wnd_l[i-1]);
|
||||
L_Extract(tmp, &r_h[i], &r_l[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void adapt_lag_wind(
|
||||
Word16 r_h[], /* in/out: autocorrelations */
|
||||
Word16 r_l[], /* in/out: autocorrelations */
|
||||
Word16 m, /* input : order of LP filter */
|
||||
const Word16 Top, /* input : open loop pitch lag */
|
||||
const Word16 Tnc, /* input : open loop pitch gain */
|
||||
Word32 sr /* input : sampling rate */
|
||||
)
|
||||
{
|
||||
Word16 strength, pitch_lag;
|
||||
Word16 pitch_gain;
|
||||
|
||||
pitch_lag = Top;
|
||||
move16();
|
||||
pitch_gain = Tnc;
|
||||
move16();
|
||||
|
||||
IF (sub(pitch_lag, 80) < 0)
|
||||
{
|
||||
strength = LAGW_STRONG;
|
||||
move16();
|
||||
if (sub(pitch_gain, kLagWinThGain1) <= 0)
|
||||
{
|
||||
strength = LAGW_MEDIUM;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE IF (sub(pitch_lag, 160) < 0)
|
||||
{
|
||||
strength = LAGW_MEDIUM;
|
||||
move16();
|
||||
if (sub(pitch_gain, kLagWinThGain2) <= 0)
|
||||
{
|
||||
strength = LAGW_WEAK;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
strength = LAGW_WEAK;
|
||||
move16();
|
||||
}
|
||||
|
||||
lag_wind(r_h, r_l, m, sr, strength);
|
||||
}
|
||||
Executable
+179
@@ -0,0 +1,179 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "basop_util.h"
|
||||
#include "prot_fx.h"
|
||||
#include <assert.h>
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
|
||||
#define shift_e (16-1)
|
||||
#define pos_e (16-1)
|
||||
|
||||
static void lerp_proc(Word16 *f, Word16 *f_out, Word16 bufferNewSize, Word16 bufferOldSize);
|
||||
|
||||
|
||||
void lerp(Word16 *f, Word16 *f_out, Word16 bufferNewSize, Word16 bufferOldSize)
|
||||
{
|
||||
Word16 tmp1, tmp2, tmpexp;
|
||||
BASOP_Util_Divide_MantExp(bufferNewSize, 0, bufferOldSize, 0, &tmp1, &tmpexp);
|
||||
tmp1 = shr(tmp1,3); /*Q12*/
|
||||
tmp1 = shl(tmp1,tmpexp);
|
||||
|
||||
BASOP_Util_Divide_MantExp(bufferOldSize, 0, bufferNewSize, 0, &tmp2, &tmpexp);
|
||||
tmp2 = shr(tmp2,3); /*Q12*/
|
||||
tmp2 = shl(tmp2,tmpexp);
|
||||
test();
|
||||
test();
|
||||
IF(sub(tmp1,16224 /*3,9609375 in Q12*/) > 0)
|
||||
{
|
||||
Word16 tmpNewSize = shl(bufferOldSize,1);
|
||||
WHILE(sub(bufferNewSize, bufferOldSize) > 0)
|
||||
{
|
||||
BASOP_Util_Divide_MantExp(bufferNewSize, 0, bufferOldSize, 0, &tmp1, &tmpexp);
|
||||
tmp1 = shr(tmp1,3); /*Q12*/
|
||||
tmp1 = shl(tmp1,tmpexp);
|
||||
test();
|
||||
IF(sub(tmp1,16224 /*3,9609375 in Q12*/) <= 0)
|
||||
{
|
||||
tmpNewSize = bufferNewSize;
|
||||
}
|
||||
|
||||
lerp_proc(f, f_out, tmpNewSize, bufferOldSize);
|
||||
|
||||
f = f_out;
|
||||
bufferOldSize = tmpNewSize;
|
||||
tmpNewSize = shl(tmpNewSize,1);
|
||||
}
|
||||
}
|
||||
ELSE IF(sub(tmp2,16224 /*3,9609375 in Q12*/) > 0)
|
||||
{
|
||||
Word16 tmpNewSize = shr(bufferOldSize,1);
|
||||
WHILE(sub(bufferNewSize, bufferOldSize) < 0)
|
||||
{
|
||||
BASOP_Util_Divide_MantExp(bufferOldSize, 0, bufferNewSize, 0, &tmp2, &tmpexp);
|
||||
tmp2 = shr(tmp2,3); /*Q12*/
|
||||
tmp2 = shl(tmp2,tmpexp);
|
||||
test();
|
||||
IF(sub(tmp2,16224 /*3,9609375 in Q12*/) <= 0)
|
||||
{
|
||||
tmpNewSize = bufferNewSize;
|
||||
}
|
||||
|
||||
lerp_proc(f, f_out, tmpNewSize, bufferOldSize);
|
||||
|
||||
f = f_out;
|
||||
bufferOldSize = tmpNewSize;
|
||||
tmpNewSize = shr(tmpNewSize,1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lerp_proc(f, f_out, bufferNewSize, bufferOldSize);
|
||||
}
|
||||
}
|
||||
|
||||
void lerp_proc(Word16 *f, Word16 *f_out, Word16 bufferNewSize, Word16 bufferOldSize)
|
||||
{
|
||||
|
||||
Word16 i, idx, n;
|
||||
Word16 diff;
|
||||
Word32 pos, shift;
|
||||
Word16 buf[2*L_FRAME_MAX];
|
||||
Word16 *ptr;
|
||||
|
||||
|
||||
ptr = f_out;
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
if ( ((f <= f_out) && (f + bufferOldSize >= f_out)) || ((f_out <= f) && (f_out + bufferNewSize >= f)) )
|
||||
{
|
||||
ptr = buf;
|
||||
move16();
|
||||
}
|
||||
|
||||
IF( sub(bufferNewSize, bufferOldSize) == 0 )
|
||||
{
|
||||
Copy(f, f_out, bufferNewSize);
|
||||
return;
|
||||
}
|
||||
|
||||
shift = L_shl(L_deposit_l(div_s( bufferOldSize, shl(bufferNewSize, 4))), 4-shift_e+16);
|
||||
|
||||
pos = L_sub(L_shr(shift, 1), 32768l/*1.0f Q15*/);
|
||||
|
||||
/* Adjust interpolation shift to avoid accessing beyond end of input buffer. */
|
||||
if ( L_sub(shift, 19661l/*0.3f Q16*/) < 0)
|
||||
{
|
||||
pos = L_sub(pos, 8520l/*0.13f Q16*/);
|
||||
}
|
||||
|
||||
assert(pos_e == shift_e);
|
||||
|
||||
/* first point of interpolation */
|
||||
IF (pos<0)
|
||||
{
|
||||
|
||||
diff = shr(extract_l(pos), 1);
|
||||
/*buf[0]=f[0]+pos*(f[1]-f[0]);*/
|
||||
move16();
|
||||
*ptr++ = add(f[0], msu_r(L_mult(diff, f[1]),diff, f[0]));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
|
||||
idx=extract_h(pos);
|
||||
|
||||
diff = lshr(extract_l(pos), 1);
|
||||
|
||||
move16();
|
||||
*ptr++ = add(f[idx], msu_r(L_mult(diff, f[idx+1]), diff, f[idx]));
|
||||
}
|
||||
|
||||
pos = L_add(pos, shift);
|
||||
idx = s_max(0, extract_h(pos));
|
||||
|
||||
n = sub(bufferNewSize, 1);
|
||||
FOR ( i=1; i<n; i++ )
|
||||
{
|
||||
diff = lshr(extract_l(pos), 1);
|
||||
if (pos < 0)
|
||||
{
|
||||
diff = sub(16384/*0.5f Q15*/, diff);
|
||||
}
|
||||
move16();
|
||||
*ptr++ = add(f[idx], msu_r(L_mult(diff, f[idx+1]), diff, f[idx]));
|
||||
|
||||
|
||||
|
||||
pos = L_add(pos, shift);
|
||||
idx = extract_h(pos);
|
||||
}
|
||||
|
||||
/* last point */
|
||||
|
||||
if ( L_sub(pos, L_deposit_h(sub(bufferOldSize,1))) > 0 )
|
||||
{
|
||||
idx = sub(bufferOldSize,2);
|
||||
}
|
||||
assert(idx <= 2*L_FRAME_MAX);
|
||||
|
||||
/* diff = t - point;*/
|
||||
diff = lshr(extract_l(L_shr(L_sub(pos, L_deposit_h(idx)), 1)), 1);
|
||||
|
||||
move16();
|
||||
*ptr++ = add(f[idx], shl(msu_r(L_mult(diff, f[idx+1]), diff, f[idx]), 1));
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF ( ((f <= f_out) && (f + bufferOldSize >= f_out)) || ((f_out <= f) && (f_out + bufferNewSize >= f)) )
|
||||
{
|
||||
Copy( buf, f_out, bufferNewSize );
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+259
@@ -0,0 +1,259 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
#include "rom_basop_util.h"
|
||||
|
||||
|
||||
/*-------------------------------------------------*
|
||||
* Local constants
|
||||
*-------------------------------------------------*/
|
||||
|
||||
#define LIMIT_PIT_REL_LOWER 2 /* delta interval to extend pitch coding in relative Q */
|
||||
#define LIMIT_PIT_REL_UPPER 0
|
||||
|
||||
/*-------------------------------------------------*
|
||||
* limit_T0()
|
||||
*
|
||||
* Close-loop pitch lag search limitation
|
||||
*-------------------------------------------------*/
|
||||
|
||||
|
||||
void limit_T0_fx(
|
||||
const Word16 L_frame, /* i : length of the frame */
|
||||
const Word16 delta, /* i : Half the close-loop searched interval */
|
||||
const Word16 pit_flag, /* i : selecting absolute(0) or delta(1) pitch quantization */
|
||||
const Word16 limit_flag, /* i : flag for Q limits (0=restrained, 1=extended) */
|
||||
const Word16 T0, /* i : rough pitch estimate around which the search is done */
|
||||
const Word16 T0_frac, /* i : pitch estimate fractional part */
|
||||
Word16 *T0_min, /* o : lower pitch limit */
|
||||
Word16 *T0_max /* o : higher pitch limit */
|
||||
)
|
||||
{
|
||||
|
||||
Word16 delta2,T1;
|
||||
Word16 pit_min, pit_max;
|
||||
|
||||
IF( limit_flag == 0 ) /* restrained Q limits */
|
||||
{
|
||||
/* set limits */
|
||||
IF( sub(L_frame,L_FRAME) == 0)
|
||||
{
|
||||
pit_max = PIT_MAX;
|
||||
move16();
|
||||
pit_min = PIT_MIN;
|
||||
move16();
|
||||
}
|
||||
ELSE /* L_frame == L_FRAME16k */
|
||||
{
|
||||
pit_max = PIT16k_MAX;
|
||||
move16();
|
||||
pit_min = PIT16k_MIN;
|
||||
move16();
|
||||
}
|
||||
|
||||
delta2 = sub(shl(delta,1),1);
|
||||
T1 = T0;
|
||||
move16();
|
||||
|
||||
if( sub(T0_frac,2) >= 0 )
|
||||
{
|
||||
T1 = add(T1,1);
|
||||
}
|
||||
|
||||
*T0_min = sub(T1,delta);
|
||||
move16();
|
||||
|
||||
*T0_min = s_max(*T0_min,pit_min);
|
||||
|
||||
*T0_max = add(*T0_min,delta2);
|
||||
move16();
|
||||
|
||||
IF( sub(*T0_max,pit_max) > 0)
|
||||
{
|
||||
*T0_max = pit_max;
|
||||
move16();
|
||||
*T0_min = sub(*T0_max,delta2);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE /* extended Q limits */
|
||||
{
|
||||
/* set limits */
|
||||
IF( sub(L_frame, L_FRAME) == 0)
|
||||
{
|
||||
pit_max = PIT_MAX;
|
||||
move16();
|
||||
pit_min = PIT_MIN_EXTEND;
|
||||
move16();
|
||||
if( sub(limit_flag, 2) == 0 )
|
||||
{
|
||||
pit_min = PIT_MIN_DOUBLEEXTEND;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE /* L_frame == L_FRAME16k */
|
||||
{
|
||||
pit_max = PIT16k_MAX;
|
||||
move16();
|
||||
pit_min = PIT16k_MIN_EXTEND;
|
||||
move16();
|
||||
}
|
||||
|
||||
delta2 = sub(shl(delta,1),1) ;
|
||||
move16();
|
||||
T1 = T0;
|
||||
move16();
|
||||
if( sub(T0_frac,2) >= 0 )
|
||||
{
|
||||
T1 = add(T1,1);
|
||||
}
|
||||
*T0_min = sub(T1, delta);
|
||||
move16();
|
||||
IF( pit_flag == 0 )
|
||||
{
|
||||
/* subframes with absolute search: keep Q range */
|
||||
*T0_min = s_max(*T0_min,pit_min);
|
||||
|
||||
*T0_max = add(*T0_min, delta2);
|
||||
move16();
|
||||
IF( sub(*T0_max,pit_max) > 0)
|
||||
{
|
||||
*T0_max = pit_max;
|
||||
move16();
|
||||
*T0_min = sub(*T0_max, delta2);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* subframes with relative search: extend Q range */
|
||||
*T0_min = s_max(*T0_min,sub(pit_min, LIMIT_PIT_REL_LOWER));
|
||||
move16();
|
||||
|
||||
*T0_min = s_max(*T0_min,L_INTERPOL);
|
||||
*T0_max = *T0_min + delta2;
|
||||
move16();
|
||||
|
||||
IF( sub(*T0_max, add(pit_max, LIMIT_PIT_REL_UPPER)) > 0 )
|
||||
{
|
||||
*T0_max = add(pit_max, LIMIT_PIT_REL_UPPER);
|
||||
move16();
|
||||
*T0_min = sub(*T0_max, delta2);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#define inv_T0_res InvIntTable
|
||||
|
||||
/*-------------------------------------------------*
|
||||
* Routine limit_T0_voiced()
|
||||
*
|
||||
* Close-loop pitch lag search limitation
|
||||
*-------------------------------------------------*/
|
||||
void limit_T0_voiced(
|
||||
const Word16 nbits,
|
||||
const Word16 res,
|
||||
const Word16 T0, /* i : rough pitch estimate around which the search is done */
|
||||
const Word16 T0_frac, /* i : pitch estimate fractional part */
|
||||
const Word16 T0_res, /* i : pitch resolution */
|
||||
Word16 *T0_min, /* o : lower pitch limit */
|
||||
Word16 *T0_min_frac, /* o : lower pitch limit */
|
||||
Word16 *T0_max, /* o : higher pitch limit */
|
||||
Word16 *T0_max_frac, /* o : higher pitch limit */
|
||||
const Word16 pit_min, /* i : Minimum pitch lag */
|
||||
const Word16 pit_max /* i : Maximum pitch lag */
|
||||
)
|
||||
{
|
||||
Word16 T1, temp1, temp2, res2;
|
||||
|
||||
|
||||
assert(res > 1 && res<=6);
|
||||
|
||||
res2 = res;
|
||||
move16();
|
||||
if(sub(res,6) == 0)
|
||||
{
|
||||
res2 = shr(res2,1);
|
||||
}
|
||||
|
||||
/* Mid-point */
|
||||
T1 = T0;
|
||||
test();
|
||||
if( sub(T0_res,1) > 0 && sub(T0_frac,(shr(T0_res,1))) >= 0 )
|
||||
{
|
||||
T1 = add(T1,1);
|
||||
}
|
||||
|
||||
/* Lower-bound */
|
||||
temp1 = sub(i_mult(T1,res),shl(1,sub(nbits,1)));
|
||||
|
||||
temp2 = mult(temp1,inv_T0_res[res2]);
|
||||
if(sub(res,6) == 0)
|
||||
{
|
||||
temp2 = shr(temp2,1);
|
||||
}
|
||||
|
||||
*T0_min = temp2;
|
||||
move16();
|
||||
|
||||
*T0_min_frac = sub(temp1,i_mult(temp2,res));
|
||||
move16();
|
||||
|
||||
IF ( sub(*T0_min,pit_min) < 0)
|
||||
{
|
||||
*T0_min = pit_min;
|
||||
move16();
|
||||
*T0_min_frac = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Higher-bound */
|
||||
temp1 = add(i_mult(*T0_min,res),add(*T0_min_frac,sub(shl(1,nbits),1)));
|
||||
|
||||
temp2 = mult(temp1,inv_T0_res[res2]);
|
||||
if(sub(res,6) == 0)
|
||||
{
|
||||
temp2 = shr(temp2,1);
|
||||
}
|
||||
|
||||
*T0_max = temp2;
|
||||
move16();
|
||||
|
||||
*T0_max_frac = sub(temp1,i_mult(temp2,res));
|
||||
move16();
|
||||
|
||||
IF ( sub(*T0_max,pit_max) > 0)
|
||||
{
|
||||
*T0_max = pit_max;
|
||||
move16();
|
||||
|
||||
*T0_max_frac = sub(res,1);
|
||||
move16();
|
||||
|
||||
temp1 = add(i_mult(*T0_max,res),sub(*T0_max_frac,sub(shl(1,nbits),1)));
|
||||
|
||||
temp2 = mult(temp1,inv_T0_res[res2]);
|
||||
if(sub(res,6) == 0)
|
||||
{
|
||||
temp2 = shr(temp2,1);
|
||||
}
|
||||
move16();
|
||||
*T0_min = temp2;
|
||||
|
||||
*T0_min_frac = sub(temp1, i_mult(temp2,res));
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+195
@@ -0,0 +1,195 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
|
||||
/* Local constants */
|
||||
#define THREN2POW 1518500250L
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* logqnorm_fx
|
||||
*
|
||||
* Log quantization for norms of sub-vectors
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void logqnorm_fx(
|
||||
const Word32 *L_x, /* i : coefficient vector Qx */
|
||||
const Word16 qx, /* i : Q value of input */
|
||||
Word16 *k, /* o : index Q0 */
|
||||
const Word16 L, /* i : codebook length Q0 */
|
||||
const Word16 N, /* i : sub-vector size Q0 */
|
||||
const Word16 hvq_flag /* i : HVQ flag Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i, m;
|
||||
Word16 coefs_shift, power_shift, temp_shift;
|
||||
Word32 L_temp, L_temp1, L_temp2;
|
||||
Word16 coefs16[MAX_SFM_LEN_FX];
|
||||
UWord16 lsb;
|
||||
|
||||
Word16 offset = add(3,shl(qx,1)); /* 3 + 2*qx */
|
||||
|
||||
lsb = 0U; /* to avoid compilation warnings */
|
||||
|
||||
L_temp1 = L_deposit_l(1);
|
||||
FOR (i=0; i<N; i++)
|
||||
{
|
||||
L_temp2 = L_abs(L_x[i]);
|
||||
L_temp1 = L_max(L_temp1, L_temp2);
|
||||
}
|
||||
coefs_shift = sub(norm_l(L_temp1), sqac_headroom_fx[N]);
|
||||
L_temp = L_deposit_l(0);
|
||||
|
||||
FOR (i=0; i<N; i++)
|
||||
{
|
||||
coefs16[i] = extract_h(L_shl(L_x[i], coefs_shift));
|
||||
L_temp = L_mac0(L_temp, coefs16[i], coefs16[i]);
|
||||
}
|
||||
|
||||
if( sub(N, 1) > 0 )
|
||||
{
|
||||
Mpy_32_16_ss(L_temp, inv_tbl_fx[N], &L_temp, &lsb);
|
||||
}
|
||||
power_shift = shl(sub(coefs_shift, 16), 1);
|
||||
|
||||
temp_shift = norm_l(L_temp);
|
||||
m = add(temp_shift, power_shift);
|
||||
|
||||
L_temp1 = L_add(L_shl(L_temp, temp_shift), lshr(lsb, sub(16, temp_shift)));
|
||||
|
||||
m = add(offset, m);
|
||||
test();
|
||||
IF( m < 5 && hvq_flag )
|
||||
{
|
||||
m = shl(m, 1);
|
||||
IF( L_sub(L_temp1, 1276901417L /* 2^0.25 Q30 */) < 0 )
|
||||
{
|
||||
m = add(m, 2);
|
||||
}
|
||||
ELSE if( L_sub(L_temp1, 1805811301L /* 2^0.75 Q30 */) < 0 )
|
||||
{
|
||||
m = add(m, 1);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
if ( L_sub(L_temp1, THREN2POW /* 2^0.5 Q30 */) < 0 )
|
||||
{
|
||||
m = add(m, 1);
|
||||
}
|
||||
if ( hvq_flag )
|
||||
{
|
||||
m = add(m, 5); /* offset, 5 extra levels in HVQ codebook */
|
||||
}
|
||||
}
|
||||
*k = s_max(m, 0);
|
||||
i = sub(L, 1);
|
||||
*k = s_min(*k, i);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void logqnorm_2_fx(
|
||||
const Word32 *env_fl, /* o, Q10 : index */
|
||||
const Word16 L, /* i : codebook length */
|
||||
const Word16 n_env_band, /* i : sub-vector size */
|
||||
const Word16 nb_sfm, /* i : sub-vector size */
|
||||
Word16 *ynrm,
|
||||
Word16 *normqlg2,
|
||||
const Word32 *thren /* i, Q10 : quantization thresholds */
|
||||
)
|
||||
{
|
||||
Word16 i, j, j1, j2;
|
||||
Word32 temp, power;
|
||||
|
||||
FOR( i=n_env_band; i < nb_sfm; i++ )
|
||||
{
|
||||
temp = env_fl[ sub(i,n_env_band) ];
|
||||
IF ( L_sub(thren[0], temp) <= 0 )
|
||||
{
|
||||
*ynrm = 0;
|
||||
move16();
|
||||
}
|
||||
ELSE IF ( L_sub(thren[sub(L,2)], temp) > 0)
|
||||
{
|
||||
*ynrm = sub(L, 1);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
power = temp;
|
||||
move16();
|
||||
j1 = 0;
|
||||
move16();
|
||||
j2 = sub(L, 1);
|
||||
WHILE ( sub(sub(j2,j1),1) > 0 )
|
||||
{
|
||||
j = shr(add(j1 , j2), 1);
|
||||
IF ( L_sub(power,thren[j]) >= 0 )
|
||||
{
|
||||
j2 = j;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
j1 = j;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
*ynrm = j2;
|
||||
move16();
|
||||
}
|
||||
*normqlg2 = dicnlg2[*ynrm];
|
||||
move16();
|
||||
normqlg2++;
|
||||
ynrm++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* calc_norm_fx()
|
||||
*
|
||||
* Calculate the norms for the spectral envelope
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void calc_norm_fx(
|
||||
const Word32 *L_x, /* i : Input vector. Qx */
|
||||
const Word16 qx, /* i : Q value of input */
|
||||
Word16 *norm, /* o : Quantization indices for norms Q0 */
|
||||
Word16 *normlg, /* o : Quantized norms in log2 Q0 */
|
||||
const Word16 start_band, /* i : Indice of band to start coding Q0 */
|
||||
const Word16 num_bands, /* i : Number of bands Q0 */
|
||||
const Word16 *band_len, /* i : Length of bands Q0 */
|
||||
const Word16 *band_start /* i : Start of bands Q0 */
|
||||
)
|
||||
{
|
||||
Word16 nrm;
|
||||
Word16 band;
|
||||
Word16 tmp;
|
||||
|
||||
set16_fx(norm, 0, start_band);
|
||||
logqnorm_fx(&L_x[band_start[start_band]], qx, &nrm, 32, band_len[start_band], 0);
|
||||
norm[start_band] = nrm;
|
||||
move16();
|
||||
normlg[start_band] = dicnlg2[nrm];
|
||||
move16();
|
||||
|
||||
tmp = add(start_band, num_bands);
|
||||
FOR (band = add(start_band, 1); band < tmp; band++)
|
||||
{
|
||||
logqnorm_fx(&L_x[band_start[band]], qx, &nrm, 40, band_len[band], 0);
|
||||
|
||||
norm[band] = nrm;
|
||||
move16();
|
||||
normlg[band] = dicnlg2[nrm];
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
/**
|
||||
* \brief inplace long shift right: a[] = a[] >> bits
|
||||
* Logical shift right of UWord32 vector a[] by 'bits' positions.
|
||||
* BASOP cycles: FLC cycles
|
||||
* len = 1: 8 lena = 2: 24
|
||||
* len = 2: 13 lena = 4: 34
|
||||
* len = 3: 18 lena = 6: 44
|
||||
* len = 4: 23 lena = 8: 54
|
||||
* \param UWord32 a[]
|
||||
* Input: vector of the length len
|
||||
* \param Word16 bits
|
||||
* Input: number of bit positions to shift right in range 1..31
|
||||
* Note: 'bits' must not be 0, this would cause a shift-overflow
|
||||
* \param Word16 len
|
||||
* Input: length of vector a[] in units of 'UWord32'
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
|
||||
void longshr(UWord32 a[], Word16 bits, Word16 len)
|
||||
{
|
||||
Word16 fracb_u, k;
|
||||
|
||||
assert ((bits > 0) && (bits < 32));
|
||||
|
||||
fracb_u = sub(32,bits);
|
||||
len = sub(len,1);
|
||||
FOR (k=0; k < len; k++)
|
||||
{
|
||||
a[k] = L_or(L_lshr(a[k],bits),L_lshl(a[k+1],fracb_u));
|
||||
move32();
|
||||
}
|
||||
a[k] = L_lshr(a[k],bits);
|
||||
move32();
|
||||
|
||||
return;
|
||||
}
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* fine_gain_pred()
|
||||
*
|
||||
* Fine gain prediction
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void fine_gain_pred_fx(
|
||||
const Word16 *sfm_start, /* i : Sub band start indices */
|
||||
const Word16 *sfm_end, /* i : Sub band end indices */
|
||||
const Word16 *sfm_size, /* i : Sub band bandwidths */
|
||||
const Word16 *i_sort, /* i : Energy sorting indices */
|
||||
const Word16 *K, /* i : Number of pulses per band */
|
||||
const Word16 *maxpulse, /* i : Maximum pulse per band */
|
||||
const Word16 *R, /* i : Bits per sub band Q3 */
|
||||
const Word16 num_sfm, /* i : Number of sub bands */
|
||||
Word16 *xq, /* i/o: Quantized vector /quantized vector with finegain adj Q15*/
|
||||
Word16 *y, /* i/o: Quantized vector (int) */
|
||||
Word16 *fg_pred, /* o : Predicted fine gains Q12 */
|
||||
const Word16 core /* i : Core */
|
||||
)
|
||||
{
|
||||
Word16 i, band;
|
||||
Word16 gp;
|
||||
Word32 xx;
|
||||
Word16 accuracy;
|
||||
Word16 k, bw;
|
||||
|
||||
Word16 shift, bw_idx;
|
||||
Word16 tmp, exp, exp2;
|
||||
Word32 L_tmp;
|
||||
UWord16 lsb;
|
||||
|
||||
FOR( band = 0; band < num_sfm; band++)
|
||||
{
|
||||
k = K[i_sort[band]];
|
||||
move16();
|
||||
|
||||
IF( k > 0)
|
||||
{
|
||||
/* bw, bw_idx only used if k>0 */
|
||||
bw = sfm_size[i_sort[band]];
|
||||
move16(); /* allowed. 8, 16, 24,32,48,64,80,96 */
|
||||
bw_idx = band_len_idx[ shr(bw,3) ];
|
||||
move16(); /* bw_idx= 0: 7 */
|
||||
xx = L_deposit_l(0);
|
||||
shift = band_len_ener_shift[bw_idx];
|
||||
FOR(i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++)
|
||||
{
|
||||
/*xx += xq[i] * xq[i]; */
|
||||
tmp = shr(xq[i], shift); /*15-shift */
|
||||
xx = L_mac0(xx, tmp, tmp); /*30-2*shift */
|
||||
}
|
||||
|
||||
IF ( xx > 0)
|
||||
{
|
||||
/* Normalize synthesis to RMS=1.0 */
|
||||
/*gp = (float) sqrt(bw / xx); */
|
||||
exp = norm_l(xx);
|
||||
L_tmp = L_shl(xx, exp); /*2*(15-shift)+exp */
|
||||
exp = sub(31, add(exp, sub(30, shl(shift,1))));
|
||||
L_tmp = Isqrt_lc(L_tmp, &exp); /*31 - exp */
|
||||
Mpy_32_16_ss(L_tmp, fine_gain_pred_sqrt_bw[bw_idx], &L_tmp, &lsb); /*31-exp+11-15=27-exp */
|
||||
gp = round_fx(L_shl(L_tmp, add(1, exp))); /*27-exp+1+exp-16=12 */
|
||||
|
||||
test();
|
||||
test();
|
||||
IF (sub(core, HQ_CORE) == 0 && R != NULL && sub(R[i_sort[band]], 256) <= 0) /* 256 is 32 in Q3 */
|
||||
{
|
||||
/*accuracy = ((float)k/(float)bw)*maxpulse[i_sort[band]]; */
|
||||
L_tmp = L_mult(k, inv_tbl_fx[bw]); /*0+15+1 */
|
||||
exp2 = norm_l(L_tmp);
|
||||
tmp = round_fx(L_shl(L_tmp, exp2)); /*16+exp2-16 */
|
||||
L_tmp = L_mult0(maxpulse[i_sort[band]], tmp); /*0+exp2 */
|
||||
exp = norm_l(L_tmp);
|
||||
accuracy = round_fx(L_shl(L_tmp, exp)); /*exp2+exp-16=exp-16 */
|
||||
exp = add(exp, exp2);
|
||||
|
||||
/*gp *= 1.0f - 0.05f / accuracy; */
|
||||
tmp = div_s(13107, accuracy); /* 0.05 in Q18 */
|
||||
tmp = shr(tmp, sub(34, exp)); /*15+18-exp+16-15=34-exp */
|
||||
tmp = sub(32767, tmp);
|
||||
tmp = s_max(27554, tmp); /* Limit attenuation to norm quantizer error, 2^-0.25 in Q15 */
|
||||
gp = mult_r(tmp, gp); /*15+12+1-16=12 */
|
||||
}
|
||||
|
||||
fg_pred[band] = gp;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
fg_pred[band] = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
fg_pred[band] = 0;
|
||||
move16();
|
||||
FOR(i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++)
|
||||
{
|
||||
y[i] = 0;
|
||||
move16();
|
||||
xq[i] = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* get_max_pulses()
|
||||
*
|
||||
* Find the maximum pulse height (in unit pulses) in each band
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void get_max_pulses_fx(
|
||||
const Word16 *band_start, /* i : Sub band start indices */
|
||||
const Word16 *band_end, /* i : Sub band end indices */
|
||||
const Word16 *k_sort, /* i : Indices for sorting by energy */
|
||||
const Word16 *npulses, /* i : Pulses per sub band */
|
||||
const Word16 BANDS, /* i : Number of bands */
|
||||
Word16 *inp_vector, /* i/o: Encoded shape vectors (int)*/
|
||||
Word16 *maxpulse /* o : Maximum pulse height per band */
|
||||
)
|
||||
{
|
||||
Word16 i, k;
|
||||
Word16 npul;
|
||||
Word16 maxp;
|
||||
Word16 tmp;
|
||||
|
||||
FOR (k = 0; k < BANDS; k++)
|
||||
{
|
||||
npul = npulses[k_sort[k]];
|
||||
move16();
|
||||
maxp = 0;
|
||||
move16();
|
||||
IF (npul > 0)
|
||||
{
|
||||
FOR (i = band_start[k_sort[k]]; i < band_end[k_sort[k]]; i++)
|
||||
{
|
||||
tmp = abs_s(inp_vector[i]);
|
||||
if (sub(tmp, maxp) > 0)
|
||||
{
|
||||
maxp = tmp;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
maxpulse[k_sort[k]] = maxp;
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* fine_gain_dec()
|
||||
*
|
||||
* Fine gain decoder. Decodes fine gain adjustments and applies correction to
|
||||
* predicted fine gains
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void fine_gain_dec_fx
|
||||
(
|
||||
Decoder_State_fx *st,
|
||||
const Word16 *ord, /* i : Indices for energy order */
|
||||
const Word16 num_sfm, /* i : Number of bands */
|
||||
const Word16 *gain_bits, /* i : Gain adjustment bits per sub band */
|
||||
Word16 *fg_pred /* i/o: Predicted gains / Corrected gains */
|
||||
)
|
||||
{
|
||||
Word16 band;
|
||||
Word16 gbits;
|
||||
Word16 idx, tmp1, exp1;
|
||||
Word16 gain_dbq;
|
||||
Word32 L_tmp;
|
||||
|
||||
|
||||
FOR ( band = 0; band < num_sfm; band++)
|
||||
{
|
||||
gbits = gain_bits[ord[band]];
|
||||
IF (gbits > 0)
|
||||
{
|
||||
IF (fg_pred[band] != 0)
|
||||
{
|
||||
idx = get_next_indice_fx( st, gbits );
|
||||
gain_dbq = finegain_fx[gbits-1][idx];
|
||||
|
||||
/* Update predicted gain with quantized correction */
|
||||
L_tmp = L_mult0(gain_dbq, 21771); /* 21771=0.05*log2(10) */ /* 14+17=31 */
|
||||
L_tmp = L_shr(L_tmp, 15);
|
||||
tmp1 = L_Extract_lc(L_tmp, &exp1);
|
||||
tmp1 = abs_s(tmp1);
|
||||
tmp1 = extract_l(Pow2(14, tmp1));
|
||||
exp1 = sub(14, exp1);
|
||||
|
||||
L_tmp = L_mult0(fg_pred[band], tmp1); /*12+exp1 */
|
||||
fg_pred[band] = round_fx(L_shl(L_tmp, sub(16, exp1))); /*12+exp1+16-exp1-16=12 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Executable
+1007
File diff suppressed because it is too large
Load Diff
Executable
+301
@@ -0,0 +1,301 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "prot_fx.h"
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* routine: lsf_dec_bfi()
|
||||
*
|
||||
* Estimate the LSFs in case of FER
|
||||
* Bad frame, all active speech coders
|
||||
*---------------------------------------------------------------------*/
|
||||
void lsf_dec_bfi(
|
||||
const Word16 codec_mode, /* i: : codec mode: MODE1 | MODE2 */
|
||||
Word16*lsf, /*!< o : 14Q1*1.28 quantized ISFs */
|
||||
const Word16*lsfold, /*!< i : 14Q1*1.28 past quantized ISF */
|
||||
Word16*lsf_adaptive_mean, /*!< i : 14Q1*1.28 ISF adaptive mean, updated when BFI==0 */
|
||||
const Word16 lsfBase[], /* i : base for differential lsf coding */
|
||||
Word16*mem_MA, /*!< i/o: 14Q1*1.28 quantizer memory for MA model */
|
||||
Word16*mem_AR, /*!< i/o: 14Q1*1.28 quantizer memory for MA model */
|
||||
Word16 stab_fac, /*!< i : ISF stability factor (shifted right by 1) */
|
||||
const Word16 last_coder_type, /*!< i : coding type in last good received fr. */
|
||||
Word16 L_frame,
|
||||
const Word16 last_good, /*!< i : last good received frame */
|
||||
const Word16 nbLostCmpt, /*!< i : counter of consecutive bad frames */
|
||||
Word8 plcBackgroundNoiseUpdated,
|
||||
Word16 *lsf_q_cng, /* o : quantized ISFs for background noise (14Q1*1.28) */
|
||||
Word16 *lsf_cng,
|
||||
Word16 *old_lsf_q_cng, /* o : old quantized ISFs for background noise */
|
||||
const Word16 Last_GSC_pit_band_idx,
|
||||
const Word16 Opt_AMR_WB /* i : IO flag */
|
||||
, const Word8 tcxonly
|
||||
,const short MODE1_bwidth /* i: coded bandwidth */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word16 alpha;
|
||||
Word32 tmp;
|
||||
Word16 lsf_mean[M];
|
||||
const Word16* pt_meansForFading;
|
||||
const Word16* pt_meansForMemUpdate;
|
||||
Word16 beta;
|
||||
Word16 gap;
|
||||
|
||||
IF (sub(codec_mode,MODE1) == 0)
|
||||
{
|
||||
pt_meansForMemUpdate = lsf_mean;
|
||||
/* Update inital guess to something stable, with proper sampling frequency and format (ISF/LSF)*/
|
||||
IF ( Opt_AMR_WB)
|
||||
{
|
||||
pt_meansForFading = Mean_isf_wb;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* 12.8kHz ACELP sampling */
|
||||
IF( sub(L_frame,L_FRAME) == 0 )
|
||||
{
|
||||
pt_meansForFading = GEWB_Ave_fx;
|
||||
|
||||
if (sub(MODE1_bwidth,NB)==0)
|
||||
{
|
||||
pt_meansForFading = GENB_Ave_fx;
|
||||
}
|
||||
}
|
||||
/* 16kHz ACELP sampling */
|
||||
ELSE
|
||||
{
|
||||
pt_meansForFading = GEWB2_Ave_fx;
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
pt_meansForFading = pt_meansForMemUpdate = lsfBase;
|
||||
test();
|
||||
if (lsf_cng != NULL && plcBackgroundNoiseUpdated)
|
||||
{
|
||||
pt_meansForFading = lsf_cng;
|
||||
}
|
||||
}
|
||||
IF( sub(nbLostCmpt, 3) <= 0 )
|
||||
{
|
||||
test();
|
||||
test();
|
||||
IF( (sub(last_coder_type, UNVOICED) == 0) ) /* Clear unvoiced last good frame */
|
||||
{
|
||||
move16();
|
||||
alpha = _ALPHA_UU_FX;
|
||||
}
|
||||
ELSE IF( sub(last_coder_type,AUDIO) == 0 || sub(last_good,INACTIVE_CLAS) == 0 )
|
||||
{
|
||||
alpha = 32604/*0.995f Q15*/;
|
||||
move16();
|
||||
test();
|
||||
if( Last_GSC_pit_band_idx > 0 && sub(nbLostCmpt, 1) > 0 )
|
||||
{
|
||||
alpha = 26214/*0.8f Q15*/;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE IF( sub(last_good,UNVOICED_CLAS) == 0 )
|
||||
{
|
||||
IF( sub(nbLostCmpt,1) <= 0 )
|
||||
{
|
||||
/* If stable, do not flatten the spectrum in the 1st erased frame */
|
||||
alpha = add(mult(stab_fac, 32768 - _ALPHA_U_FX_X_2), _ALPHA_U_FX_X_2);
|
||||
}
|
||||
ELSE IF(sub(nbLostCmpt,2) == 0)
|
||||
{
|
||||
alpha = sub(_ALPHA_U_FX_X_2,shr(_ALPHA_U_FX,1)); /* 0.6 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
alpha = _ALPHA_U_FX;
|
||||
move16(); /* go rapidly to CNG spectrum */
|
||||
}
|
||||
}
|
||||
ELSE IF( sub(last_good ,UNVOICED_TRANSITION) == 0 )
|
||||
{
|
||||
alpha = _ALPHA_UT_FX;
|
||||
move16();
|
||||
}
|
||||
ELSE IF( (sub(last_good,VOICED_CLAS) == 0) || (sub(last_good,ONSET) == 0) )
|
||||
{
|
||||
/* clearly voiced - mild convergence to the CNG spectrum for the first 3 erased frames */
|
||||
move16();
|
||||
alpha = _ALPHA_V_FX;
|
||||
}
|
||||
ELSE IF( sub(last_good ,SIN_ONSET) == 0 )
|
||||
{
|
||||
alpha = _ALPHA_S_FX;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
alpha = _ALPHA_VT_FX; /* rapid convergence to the CNG spectrum (long erasure, ONSETS) */
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Word16 exp = 15;
|
||||
alpha = Inv16(nbLostCmpt, &exp); /*1.f/bfi_cnt;*/
|
||||
alpha = shl(alpha,exp);
|
||||
}
|
||||
IF(sub(codec_mode,MODE1) == 0)
|
||||
{
|
||||
beta = BETA_FEC_FX;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
beta = 8192/*0.25f Q15*/;
|
||||
move16();
|
||||
if (plcBackgroundNoiseUpdated)
|
||||
{
|
||||
beta = 0/*0.f Q15*/;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
FOR (i=0; i<M; i++)
|
||||
{
|
||||
|
||||
lsf_mean[i] = mac_r(L_mult(beta,pt_meansForFading[i]), sub(32767/*1.0F Q15*/,beta), lsf_adaptive_mean[i]);
|
||||
move16();
|
||||
|
||||
lsf[i] = mac_r(L_mult(alpha, lsfold[i]), sub(32767/*1.0F Q15*/, alpha), lsf_mean[i]);
|
||||
move16();
|
||||
|
||||
IF(lsf_q_cng!=NULL)
|
||||
{
|
||||
lsf_q_cng[i] = mac_r(L_mult(s_max(alpha,26214/*0.8f Q15*/),old_lsf_q_cng[i]), sub(32767/*1.0f Q15*/, s_max(alpha,26214/*0.8f Q15*/)), pt_meansForFading[i]);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
/* check LSF stability through LSF ordering */
|
||||
IF ( Opt_AMR_WB )
|
||||
{
|
||||
reorder_isf_fx( lsf, ISF_GAP_FX, M, Fs_2 );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
IF( sub(L_frame,L_FRAME) == 0 )
|
||||
{
|
||||
IF(sub(codec_mode, MODE1) == 0)
|
||||
{
|
||||
reorder_lsf_fx(lsf, MODE1_LSF_GAP_FX, M, INT_FS_FX); /*arg1&2: 14Q1*1.18*/
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
reorder_lsf_fx(lsf, LSF_GAP_FX, M, INT_FS_FX); /*arg1&2: 14Q1*1.18*/
|
||||
}
|
||||
|
||||
IF(lsf_q_cng!=NULL)
|
||||
{
|
||||
reorder_lsf_fx(lsf_q_cng, LSF_GAP_FX, M, INT_FS_FX);
|
||||
}
|
||||
}
|
||||
ELSE IF ( tcxonly != 0 )
|
||||
{
|
||||
IF ( sub(L_frame,320) == 0 )
|
||||
{
|
||||
gap = 143;
|
||||
}
|
||||
ELSE IF ( sub(L_frame,512) == 0 )
|
||||
{
|
||||
gap = 90;
|
||||
}
|
||||
ELSE IF ( sub(L_frame,640) == 0 )
|
||||
{
|
||||
gap = 72;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
gap = 48;
|
||||
}
|
||||
reorder_lsf_fx(lsf, gap, M, INT_FS_FX);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
reorder_lsf_fx(lsf, MODE1_LSF_GAP_FX, M, i_mult(L_frame, 50)); /*arg1&2: 14Q1*1.18*/
|
||||
IF(lsf_q_cng!=NULL)
|
||||
{
|
||||
reorder_lsf_fx(lsf_q_cng, LSF_GAP_FX, M, INT_FS_16k_FX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* update the AR memory to be used in the next frame */
|
||||
{
|
||||
Copy(lsf,mem_AR,M);
|
||||
}
|
||||
|
||||
/* update the MA memory to be used in the next frame */
|
||||
FOR(i=0; i<M; i++)
|
||||
{
|
||||
/*factor 0x4000 means 0.5. Together with /2 in mem_MA-assignment,
|
||||
this results in an attenuation of the MA Q memory */
|
||||
tmp = L_msu(L_mult(lsf[i],0x4000),pt_meansForMemUpdate[i],0x4000);
|
||||
/* Update with quantized prediction error for MA model */
|
||||
mem_MA[i] = msu_r(tmp, MU_MA_FX/2,mem_MA[i]);
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Word16 const * PlcGetLsfBase (Word16 const lpcQuantization,
|
||||
Word16 const narrowBand,
|
||||
Word32 const sr_core)
|
||||
{
|
||||
/* Not correct BW */
|
||||
IF (lpcQuantization==0)
|
||||
{
|
||||
/* high rates, return value is never used; the correct value changes
|
||||
dynamically and is not available during PLC; therefore, the setting
|
||||
is kept as before (without the define PLC_FIX_XSF_HANDLING); the
|
||||
correct value would be isf[m] as returned by lpc_unquantize()
|
||||
during normal decoding */
|
||||
IF(L_sub(sr_core,32000)==0)
|
||||
{
|
||||
return means_swb_cleanspeech_lsf32k0;
|
||||
}
|
||||
ELSE IF(L_sub(sr_core,25600)==0)
|
||||
{
|
||||
return means_swb_cleanspeech_lsf25k6;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
return means_wb_cleanspeech_lsf16k0;
|
||||
}
|
||||
}
|
||||
|
||||
/* lpcQuntization == 1 is left */
|
||||
|
||||
IF (L_sub(sr_core,16000)==0)
|
||||
{
|
||||
return GEWB2_Ave_fx;
|
||||
}
|
||||
|
||||
/* sr_core == 12.8k is left */
|
||||
|
||||
IF (narrowBand == 0)
|
||||
{
|
||||
return GEWB_Ave_fx;
|
||||
}
|
||||
|
||||
/* narrowBand == 1 is left */
|
||||
return GENB_Ave_fx;
|
||||
}
|
||||
|
||||
Executable
+159
@@ -0,0 +1,159 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "cnst_fx.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
#include "prot_fx.h"
|
||||
#include "options.h"
|
||||
|
||||
#define swap(x,y,type) {type u__p; u__p=x; x=y; y=u__p;}
|
||||
|
||||
extern const Word16 tbl_mid_gen_wb_5b_fx[];
|
||||
extern const Word16 tbl_mid_unv_wb_5b_fx[];
|
||||
|
||||
|
||||
|
||||
|
||||
void midlsf_dec(
|
||||
const Word16 qlsf0[], /* i: quantized lsf coefficients (3Q12) */
|
||||
const Word16 qlsf1[], /* i: quantized lsf coefficients (3Q12) */
|
||||
Word16 idx, /* i: codebook index */
|
||||
Word16 qlsf[], /* o: decoded lsf coefficients (3Q12) */
|
||||
Word16 coder_type,
|
||||
Word16 *mid_lsf_int,
|
||||
Word16 prev_bfi,
|
||||
Word16 safety_net)
|
||||
{
|
||||
const Word16 *ratio=NULL;
|
||||
Word16 j;
|
||||
Word32 L_tmp;
|
||||
Word16 bad_spacing = 0;
|
||||
|
||||
move16();
|
||||
/* Select codebook */
|
||||
IF ( sub(coder_type, UNVOICED) == 0 )
|
||||
{
|
||||
ratio = tbl_mid_unv_wb_5b_fx;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
ratio = tbl_mid_gen_wb_5b_fx;
|
||||
}
|
||||
FOR (j=0; j<M; j++)
|
||||
{
|
||||
L_tmp = L_mult(sub(0x2000, ratio[idx*M+j]), qlsf0[j]); /*Q(x2.56+13+1)->Q(x2.56+14)*/
|
||||
L_tmp = L_mac(L_tmp, ratio[idx*M+j], qlsf1[j]); /*Q(x2.56+14)*/
|
||||
qlsf[j] = round_fx(L_shl(L_tmp,2)); /*Q(x2.56)*/
|
||||
}
|
||||
|
||||
|
||||
IF(mid_lsf_int != NULL) /*at the decoder*/
|
||||
{
|
||||
/* check for incorrect LSF ordering */
|
||||
IF ( sub(*mid_lsf_int, 1) == 0 )
|
||||
{
|
||||
FOR (j=1; j<M; j++)
|
||||
{
|
||||
IF ( sub(qlsf[j] , qlsf[j-1]) < 0 )
|
||||
{
|
||||
bad_spacing = 1;
|
||||
move16();
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Redo mid-LSF interpolation with 0.4 in case of LSF instability */
|
||||
test();
|
||||
test();
|
||||
IF( prev_bfi || ( sub(*mid_lsf_int, 1) == 0 && bad_spacing ) )
|
||||
{
|
||||
FOR (j=0; j<M; j++)
|
||||
{
|
||||
/* redo mid-LSF interpolation with 0.4 */
|
||||
qlsf[j] = add(mult_r(13107, qlsf0[j]), mult_r(19661, qlsf1[j])); /* Q15 +x2.56 -Q15 13107 = 0.4(Q15), 19661 = 0.6 (Q15)*/ move16();
|
||||
|
||||
/* ensure correct ordering of LSF indices */
|
||||
test();
|
||||
test();
|
||||
IF ( j > 0 && sub(j, M) <0 && sub(qlsf[j], add( qlsf[j-1], LSF_GAP_MID_FX))<0 )
|
||||
{
|
||||
qlsf[j] = add(qlsf[j-1], LSF_GAP_MID_FX);
|
||||
move16();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* otherwise, use regular LSF spacing and ordering as in the encoder */
|
||||
FOR (j=0; j<M; j++)
|
||||
{
|
||||
test();
|
||||
test();
|
||||
IF ( j > 0 && sub(j, M) < 0 && sub(qlsf[j], add( qlsf[j-1],LSF_GAP_MID_FX))<0 )
|
||||
{
|
||||
qlsf[j] = add(qlsf[j-1], LSF_GAP_MID_FX);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( prev_bfi )
|
||||
{
|
||||
/* continue redoing mid-LSF interpolation with 0.4 in order not to propagate the error */
|
||||
*mid_lsf_int = 1;
|
||||
move16();
|
||||
}
|
||||
if ( safety_net )
|
||||
{
|
||||
/* safety-net encountered -> stop redoing mid-LSF interpolation with 0.4 */
|
||||
*mid_lsf_int = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* use regular LSF spacing */
|
||||
FOR (j=0; j<M; j++)
|
||||
{
|
||||
test();
|
||||
test();
|
||||
IF ( j > 0 && sub(j, M) <0 && sub(qlsf[j], add(qlsf[j-1], LSF_GAP_MID_FX))<0 )
|
||||
{
|
||||
qlsf[j] = add(qlsf[j-1], LSF_GAP_MID_FX);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Word16 lsf_ind_is_active(
|
||||
const Word16 lsf_q_ind[],
|
||||
const Word16 means[],
|
||||
Word16 narrowband,
|
||||
Word16 cdk
|
||||
)
|
||||
{
|
||||
Word16 lsf[2], min_distance;
|
||||
|
||||
lsf[0] = add(lsf_q_ind[0], means[0]);
|
||||
move16();
|
||||
lsf[1] = add(lsf_q_ind[1], means[1]);
|
||||
move16();
|
||||
|
||||
min_distance = lsf[0];
|
||||
move16();
|
||||
min_distance = s_min(min_distance, sub(lsf[1], lsf[0]));
|
||||
|
||||
assert(narrowband == 0 || narrowband == 1);
|
||||
assert(cdk == 0 || cdk == 1);
|
||||
|
||||
return sub(min_distance, min_distance_thr[narrowband][cdk]) < 0;
|
||||
}
|
||||
|
||||
Executable
+3420
File diff suppressed because it is too large
Load Diff
Executable
+858
@@ -0,0 +1,858 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
/* The conversion modes. */
|
||||
#define DOWNCONV 0
|
||||
#define UPCONV 1
|
||||
#define NC (M/2)
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Local functions
|
||||
*-------------------------------------------------------------------*/
|
||||
static void powerspect_fx(
|
||||
const Word16 x[], /* i: Q15 Grid points x[0:m-1] */
|
||||
Word16 N, /* i: Number of grid points */
|
||||
Word32 R[], /* i: Q20 Coefficients of R(x) in R[0:NC] */
|
||||
Word32 S[], /* i: Q20 Coefficients of S(x) in S[0:NC] */
|
||||
Word32 G[], /* o: Q15 Power spectrum G[0:N] */
|
||||
Word16 mode /* i: Flag for up or down conversion */
|
||||
);
|
||||
|
||||
static void spectautocorr_fx(
|
||||
const Word16 x[], /* i: Grid points x[0:m-1] */
|
||||
const Word16 N, /* i: Number of grid points */
|
||||
const Word32 G[], /* i: Power spectrum G[0:N-1] */
|
||||
Word16 rh[], /* o: Autocorrelation r[0:M] */
|
||||
Word16 rl[] /* o: Autocorrelation r[0:M] */
|
||||
);
|
||||
|
||||
static Word32 b_inv_sq(
|
||||
const Word32 in32, /* i : Input not normalized to inverse */
|
||||
const Word16 exp_in /* I : input current exponent */
|
||||
);
|
||||
|
||||
static Word32 inv_pow(
|
||||
const Word32 re,
|
||||
const Word32 se,
|
||||
const Word16 x
|
||||
|
||||
);
|
||||
|
||||
static void zeros2poly_fx( Word16 x[], Word32 R[], Word32 S[] );
|
||||
|
||||
static void polydecomp_fx(
|
||||
Word16 A[], /* i: Q12 linear prediction coefficients */
|
||||
Word32 P[], /* o: Q22 coefficients of R(x) */
|
||||
Word32 Q[] /* o: Q22 coefficients of S(x) */
|
||||
);
|
||||
|
||||
static void cheb2poly_fx(
|
||||
Word32 L_P[] /* i/o Q22: The coefficients of C(x) and P(x) */
|
||||
);
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* lsp_convert_poly()
|
||||
*
|
||||
* Converts the LP filter estimated at 16.0 kHz sampling rate down
|
||||
* 12.8 kHz frequency scale or alternatively from 12.8 kHz up to
|
||||
* 16.0 kHz. The former is called down conversation and latter up
|
||||
* conversion. The resulting LP filter is characterized with its
|
||||
* line spectrum pairs. The original Lp filter can be either in
|
||||
* its immittance, used for the AMR-WB IO mode, or line spectrum
|
||||
* pair representation.
|
||||
*
|
||||
* The conversion is based the autocorrelation computed from the
|
||||
* power spectrum of the LP filter that is truncated or extrapolated
|
||||
* to the desired frequency scale.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
Word16 lsp_convert_poly_fx(
|
||||
Word16 w[], /* i/o: LSP or ISP parameters */
|
||||
const Word16 L_frame, /* i : flag for up or down conversion */
|
||||
const Word16 Opt_AMRWB /* i : flag for the AMR-WB IO mode */
|
||||
)
|
||||
{
|
||||
const Word16 N50 = GRID50_POINTS;
|
||||
const Word16 N40 = GRID40_POINTS;
|
||||
Word16 flag;
|
||||
|
||||
Word32 G[GRID50_POINTS];
|
||||
Word16 i;
|
||||
Word16 A[M+1];
|
||||
Word32 R[NC+1], S[NC+1];
|
||||
Word32 epsP[M+1];
|
||||
Word16 rh[M+1], rl[M+1];
|
||||
Word16 oldA[M+3];
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Because AMR-WB IO mode uses immittance spectrum frequency representation
|
||||
* instead of line spectrum frequency representation, the input
|
||||
* parameters do not give the zeros of the polynomials R(x) and S(x).
|
||||
* Hence R(x) and S(x) are formed via the polynomial A(z) of the linear
|
||||
* prediction filter.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
IF( Opt_AMRWB )
|
||||
{
|
||||
E_LPC_f_isp_a_conversion( w, oldA, M );
|
||||
|
||||
polydecomp_fx( oldA, R, S );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Form the polynomials R(x) and S(x) from their zeros that are the
|
||||
* line spectrum pairs of A(z). The polynomial coefficients can be
|
||||
* scaled for convenience, because scaling will not affect the
|
||||
* resulting LP coefficients. Scaling by 128 gives the correct offset
|
||||
* to the power spectrum for n = 16.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
ELSE
|
||||
{
|
||||
E_LPC_f_lsp_a_conversion( w, oldA, M );
|
||||
|
||||
zeros2poly_fx(w, R, S);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Conversion from 16.0 kHz down to 12.8 kHz. The power spectrum
|
||||
* needs to be computed only up to 6.4 kHz, because the upper band
|
||||
* is omitted.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
IF (sub(L_frame,L_FRAME) == 0)
|
||||
{
|
||||
powerspect_fx(grid50_fx, N50, R, S, G, DOWNCONV);
|
||||
spectautocorr_fx(grid40_fx, N40, G, rh, rl);
|
||||
}
|
||||
/*---------------------------------------------------------------------*
|
||||
* Conversion from 12.8 kHz up to 16.0 kHz.
|
||||
* Compute the power spectrum of the LP filter, extrapolate the
|
||||
* power spectrum from 6.4 kHz to 8.0 kHz, and compute auto-
|
||||
* correlation on this power spectrum.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
ELSE
|
||||
{
|
||||
powerspect_fx(grid40_fx, N40, R, S, G, UPCONV);
|
||||
|
||||
FOR (i = N40; i < N50; i++)
|
||||
{
|
||||
G[i] = G[N40-1];
|
||||
move32();
|
||||
}
|
||||
|
||||
spectautocorr_fx(grid50_fx, N50, G, rh, rl);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Compute the linear prediction coefficients from the autocorrelation
|
||||
* and convert to line spectrum pairs.
|
||||
*---------------------------------------------------------------------*/
|
||||
flag=E_LPC_lev_dur(rh, rl, A, epsP, M, oldA);
|
||||
E_LPC_a_lsp_conversion(A, w, stable_LSP_fx, M );
|
||||
|
||||
|
||||
return(flag);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* powerspect()
|
||||
*
|
||||
* Computes the power spectrum G(w) = 1/|A(w)|^2 at N points on
|
||||
* the real axis x = cos w by utilizing the line spectrum frequency
|
||||
* decomposition
|
||||
*
|
||||
* A(z) = (P(z) + Q(z))/2,
|
||||
*
|
||||
* where assuming A(z) of an even degree n,
|
||||
*
|
||||
* P(z) = [A(z) + z^(n+1) A(1/z)]/(1/z + 1),
|
||||
* Q(z) = [A(z) - z^(n+1) A(1/z)]/(1/z - 1).
|
||||
*
|
||||
* The zeros of these polynomials give the line spectrum frequencies
|
||||
* of A(z). It can be shown that for an even n,
|
||||
*
|
||||
* |A(x)|^2 = 2 (1 + x) R(x)^2 + 2 (1 - x) S(x)^2,
|
||||
*
|
||||
* where x = cos w, and R(x) and S(x) are the direct polynomials
|
||||
* resulting from the Chebyshev series representation of P(z)
|
||||
* and Q(z).
|
||||
*
|
||||
* This routine assumes the grid X = 1, x[0], x[1], .., x[m-1],
|
||||
* -, ..., -x[1], -x[0], -1 such that x[i] = cos((i+1)*pi/N) for
|
||||
* evaluating the power spectrum. Only m = (N-1)/2 - 1 grid points
|
||||
* need to be stored, because cos(0) and cos(pi/2) are trivial,
|
||||
* and the points above pi/2 are obtained readily using the symmetry
|
||||
* of cosine.
|
||||
*
|
||||
* The power spectrum can be scaled as a*G[], where a is chosen
|
||||
* for convenience. This is because the scaling has no impact on
|
||||
* the LP coefficients to be determined based on the power spectrum.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
void powerspect_fx(
|
||||
const Word16 x[], /* i: Q15 Grid points x[0:m-1] */
|
||||
Word16 N, /* i: Number of grid points */
|
||||
Word32 R[], /* i: Q20 Coefficients of R(x) in R[0:NC] */
|
||||
Word32 S[], /* i: Q20 Coefficients of S(x) in S[0:NC] */
|
||||
Word32 G[], /* o: Q15 Power spectrum G[0:N] */
|
||||
Word16 mode /* i: Flag for up or down conversion */
|
||||
)
|
||||
{
|
||||
Word32 s0, se, so, r0, re, ro;
|
||||
Word16 i, j;
|
||||
Word16 iuni, imid;
|
||||
Word32 L_tmp;
|
||||
Word16 x2;
|
||||
Word32 mh;
|
||||
UWord16 ml;
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Down conversion yields iuni unique grid points that do not have
|
||||
* symmetric counterparts above x = cos(pi/2) = 0.
|
||||
* Set the mid point of the frequency grid.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
IF (mode == DOWNCONV)
|
||||
{
|
||||
iuni = (GRID50_POINTS - 1)/5 - 1;
|
||||
move16();
|
||||
imid = (GRID50_POINTS - 1)/2;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Power spectrum x = cos(pi) = -1 that is not needed in down
|
||||
* conversion. Set the mid point of the frequency grid.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
ELSE
|
||||
{
|
||||
iuni = 0;
|
||||
move16();
|
||||
imid = (GRID40_POINTS - 1)/2;
|
||||
move16();
|
||||
|
||||
G[N-1] = S[0];
|
||||
move32();
|
||||
|
||||
FOR (j = 1; j <= NC; j++)
|
||||
{
|
||||
G[N-1] = L_sub(S[j], G[N-1]);
|
||||
move32();
|
||||
}
|
||||
G[N-1] = b_inv_sq(G[N-1], 19);
|
||||
move32();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Power spectrum x = cos(0) = 1.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
G[0] = R[0];
|
||||
move32();
|
||||
FOR (j = 1; j <= NC; j++)
|
||||
{
|
||||
G[0] = L_add(R[j], G[0]);
|
||||
move32();
|
||||
}
|
||||
|
||||
G[0] = b_inv_sq(L_max(G[0],1), 19);
|
||||
move32();
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Power spectrum at x = cos(pi/2) = 0.
|
||||
*---------------------------------------------------------------------*/
|
||||
G[imid] = inv_pow(R[NC], S[NC], 0);
|
||||
move32();
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Power spectrum at unique points that do not have symmetric
|
||||
* counterparts at x > cos(pi/2) = 0.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
FOR (i = 1; i <= iuni; i++)
|
||||
{
|
||||
Mpy_32_16_ss(R[0], x[i-1], &mh, &ml);
|
||||
r0 = L_add(R[1], mh);
|
||||
|
||||
Mpy_32_16_ss(S[0], x[i-1], &mh, &ml);
|
||||
s0 = L_add(S[1], mh);
|
||||
|
||||
|
||||
FOR (j = 2; j <= NC; j++)
|
||||
{
|
||||
Mpy_32_16_ss(r0, x[i-1], &mh, &ml);
|
||||
r0 = L_add(R[j], mh);
|
||||
|
||||
Mpy_32_16_ss(s0, x[i-1], &mh, &ml);
|
||||
s0 = L_add(S[j], mh);
|
||||
}
|
||||
|
||||
G[i] = inv_pow(r0, s0, x[i-1]);
|
||||
move32();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Power spectrum at points other than x = -1, 0, and 1 and unique
|
||||
* points is computed using the anti-symmetry of the grid relative
|
||||
* to the midpoint x = 0 in order to reduce looping.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
FOR ( ; i < imid; i++)
|
||||
{
|
||||
x2 = mult_r(x[i-1], x[i-1]);
|
||||
|
||||
Mpy_32_16_ss(R[0], x2, &mh, &ml);
|
||||
re = L_add(R[2], mh);
|
||||
Mpy_32_16_ss(R[1], x2, &mh, &ml);
|
||||
ro = L_add(R[3], mh);
|
||||
|
||||
Mpy_32_16_ss(S[0], x2, &mh, &ml);
|
||||
se = L_add(S[2], mh);
|
||||
Mpy_32_16_ss(S[1], x2, &mh, &ml);
|
||||
so = L_add(S[3], mh);
|
||||
|
||||
FOR (j = 4; j < NC; j+=2)
|
||||
{
|
||||
Mpy_32_16_ss(re, x2, &mh, &ml);
|
||||
re = L_add(R[j], mh);
|
||||
Mpy_32_16_ss(ro, x2, &mh, &ml);
|
||||
ro = L_add(R[j+1], mh);
|
||||
Mpy_32_16_ss(se, x2, &mh, &ml);
|
||||
se = L_add(S[j], mh);
|
||||
Mpy_32_16_ss(so, x2, &mh, &ml);
|
||||
so = L_add(S[j+1], mh);
|
||||
}
|
||||
|
||||
Mpy_32_16_ss(re, x2, &mh, &ml);
|
||||
L_tmp = L_add(R[j], mh);
|
||||
Mpy_32_16_ss(ro, x[i-1], &mh, &ml);
|
||||
re = L_add(L_tmp, mh);
|
||||
ro = L_sub(L_tmp, mh);
|
||||
|
||||
Mpy_32_16_ss(se, x2, &mh, &ml);
|
||||
L_tmp = L_add(S[j], mh);
|
||||
Mpy_32_16_ss(so, x[i-1], &mh, &ml);
|
||||
se = L_add(L_tmp, mh);
|
||||
so = L_sub(L_tmp, mh);
|
||||
|
||||
G[i] = inv_pow(re, se, x[i-1]);
|
||||
move32();
|
||||
G[N-i-1] = inv_pow(so, ro, x[i-1]);
|
||||
move32();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static Word32 b_inv_sq(
|
||||
const Word32 in32, /* i : Input not normalized to inverse */
|
||||
const Word16 exp_in /* i : input current exponent */
|
||||
)
|
||||
{
|
||||
Word16 m_den, exp_den;
|
||||
Word16 div_out;
|
||||
Word32 Ltmp;
|
||||
|
||||
exp_den = norm_l(in32);
|
||||
m_den = extract_h(L_shl(in32, exp_den));
|
||||
exp_den = add(sub(30,exp_den),sub(16,exp_in));
|
||||
|
||||
m_den = mult_r(m_den, m_den);
|
||||
exp_den = shl(exp_den,1);
|
||||
|
||||
div_out = div_s(8192,m_den);
|
||||
Ltmp = L_shl(div_out, add(sub(30-13, exp_den),15)); /*Q15*/
|
||||
|
||||
return Ltmp;
|
||||
}
|
||||
|
||||
static Word32 inv_pow(
|
||||
const Word32 re,
|
||||
const Word32 se,
|
||||
const Word16 x
|
||||
)
|
||||
{
|
||||
Word16 exp1, exp2;
|
||||
Word16 tmp;
|
||||
Word32 L_tmp;
|
||||
Word32 mh;
|
||||
UWord16 ml;
|
||||
Word32 r0, s0;
|
||||
|
||||
IF(re==0)
|
||||
{
|
||||
exp1 = 30;
|
||||
move16();
|
||||
r0 = L_deposit_l(0);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
exp1 = norm_l(re);
|
||||
tmp = extract_h(L_shl(re, exp1));
|
||||
L_tmp = L_shr(L_mult(tmp, tmp), 1);
|
||||
Mpy_32_16_ss(L_tmp, x, &mh, &ml);
|
||||
r0 = L_add(L_tmp, mh);
|
||||
}
|
||||
|
||||
IF(se==0)
|
||||
{
|
||||
exp2 = 30;
|
||||
move16();
|
||||
s0 = L_deposit_l(0);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
exp2 = norm_l(se);
|
||||
tmp = extract_h(L_shl(se, exp2));
|
||||
L_tmp = L_shr(L_mult(tmp, tmp), 1);
|
||||
Mpy_32_16_ss(L_tmp, x, &mh, &ml);
|
||||
s0 = L_sub(L_tmp, mh);
|
||||
}
|
||||
|
||||
IF(exp1 > exp2)
|
||||
{
|
||||
exp1 = shl(sub(exp1, exp2), 1);
|
||||
r0 = L_shr(r0, exp1);
|
||||
|
||||
exp2 = add(add(exp2, exp2), 8);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
exp2 = shl(sub(exp2, exp1), 1);
|
||||
s0 = L_shr(s0, exp2);
|
||||
|
||||
exp2 = add(add(exp1, exp1), 8);
|
||||
}
|
||||
|
||||
r0 = L_add(r0, s0);
|
||||
exp1 = norm_l(r0);
|
||||
L_tmp = L_shl(r0, exp1);
|
||||
tmp = extract_h(L_tmp);
|
||||
IF(tmp==0)
|
||||
{
|
||||
return MAX_32;
|
||||
}
|
||||
tmp = div_s((Word16)((1<<14)-1), tmp);
|
||||
exp1 = add(exp1, exp2);
|
||||
L_tmp = L_shr(tmp, sub(31, exp1)); /* result in Q15 */
|
||||
|
||||
return(L_tmp);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* spectautocorr()
|
||||
*
|
||||
* Computes the autocorrelation r[j] for j = 0, 1, ..., M from
|
||||
* the power spectrum P(w) by using rectangle rule to approximate
|
||||
* the integral
|
||||
*
|
||||
* 1 pi
|
||||
* r[j] = --- I P(w) cos(j*w) dw.
|
||||
* 2*pi -pi
|
||||
*
|
||||
* It is sufficient to evaluate the integrand only from w = 0 to
|
||||
* w = pi due to the symmetry P(-w) = P(w). We can further
|
||||
* employ the relation
|
||||
*
|
||||
* cos(j*(pi - w)) = (-1)^j cos(j*w)
|
||||
*
|
||||
* to use symmetries relative to w = pi/2.
|
||||
*
|
||||
* When applying the rectangle rule, it is useful to separate w = 0,
|
||||
* w = pi/2, and w = pi. By using a frequency grid of N points, we
|
||||
* can express the rectangle rule as
|
||||
*
|
||||
* r[j] = G[0] + 2*a*G[(N-1)/2] + b*G[N-1]
|
||||
*
|
||||
* M
|
||||
* + 2 sum (G[i] - G[N-i-1]) cos(j*x[i])
|
||||
* i=1
|
||||
*
|
||||
* where G[i] is the power spectrum at the grid point cos(i*pi/N)
|
||||
* and M = (N-1)/2 - 1 is the number of the grid points in the
|
||||
* interval(0, pi/2).
|
||||
*
|
||||
* The coefficients
|
||||
*
|
||||
* b = (-1)^j
|
||||
* a = (1 + (-1)^(j+1))(-1)^floor(j/2)
|
||||
*
|
||||
* follow from the properties of cosine. The computation further
|
||||
* uses the recursion
|
||||
*
|
||||
* cos(j*w) = 2*cos(w)*cos((j-1)*w) - cos((j-2)*w)
|
||||
*
|
||||
* Note that the autocorrelation can be scaled for convenience,
|
||||
* because this scaling has no impact on the LP coefficients to be
|
||||
* calculated from the autocorrelation. The expression of r[j] thus
|
||||
* omits the division by N.
|
||||
*
|
||||
* See the powerspect function on the definition of the grid.
|
||||
*
|
||||
* References
|
||||
* J. Makhoul, "Spectral linear prediction: properties and
|
||||
* applications," IEEE Trans. on Acoustics, Speech and Signal
|
||||
* Processing, Vol. 23, No. 3, pp.283-296, June 1975
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
static void spectautocorr_fx(
|
||||
const Word16 x[], /* i: Grid points x[0:m-1] */
|
||||
const Word16 N, /* i: Number of grid points */
|
||||
const Word32 G[], /* i: Power spectrum G[0:N-1] */
|
||||
Word16 rh[], /* o: Autocorrelation r[0:M] */
|
||||
Word16 rl[] /* o: Autocorrelation r[0:M] */
|
||||
)
|
||||
{
|
||||
Word16 c[M+1]; /* c[j] = cos(j*w) */
|
||||
Word32 gp, gn;
|
||||
Word16 i, j;
|
||||
Word16 imid;
|
||||
Word32 mh;
|
||||
UWord16 ml;
|
||||
Word32 r[M+1];
|
||||
Word16 exp0;
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* The mid point of the cosine table x of m entries assuming an odd m.
|
||||
* Only the entries x[0] = cos(pi/m), x[1] = cos(2*pi/m), ...,
|
||||
* x[imid-1] = cos((imid-1)*pi/m) need to be stored due to trivial
|
||||
* cos(0), cos(pi/2), cos(pi), and symmetry relative to pi/2.
|
||||
* Here m = 51.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
imid = (N - 1)/2;
|
||||
move16();
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Autocorrelation r[j] at zero lag j = 0 for the upper half of the
|
||||
* unit circle, but excluding the points x = cos(0) and x = cos(pi).
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
r[0] = G[1];
|
||||
move32();
|
||||
FOR (i = 2; i < N-1; i++)
|
||||
{
|
||||
r[0] = L_add(r[0], G[i]);
|
||||
move32();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Initialize the autocorrelation r[j] at lags greater than zero
|
||||
* by adding the midpoint x = cos(pi/2) = 0.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
r[1] = L_deposit_l(0);
|
||||
r[2] = -G[imid];
|
||||
move32();
|
||||
|
||||
FOR (i = 3; i < M; i+=2)
|
||||
{
|
||||
r[i] = L_deposit_l(0);
|
||||
r[i+1] = -r[i-1];
|
||||
move32();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Autocorrelation r[j] at lags j = 1, 2, ..., M. The computation
|
||||
* employes the relation cos(j*(pi - w)) = (-1)^j cos(j*w) and
|
||||
* cos(j*w) = 2*cos(w)*cos((j-1)*w) - cos((j-2)*w) for obtaining
|
||||
* the cosine c[j] = cos(j*w).
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
c[0] = (Word16)32767;
|
||||
move16(); /* 1.0 in Q15 */
|
||||
FOR (i = 1; i < imid; i++)
|
||||
{
|
||||
gp = L_add(G[i], G[N-i-1]);
|
||||
gn = L_sub(G[i], G[N-i-1]);
|
||||
|
||||
/*r[1] = L_mac(r[1], x[i-1], gn);*/
|
||||
Mpy_32_16_ss(gn, x[i-1], &mh, &ml);
|
||||
r[1] = L_add(r[1], mh);
|
||||
move32();
|
||||
c[1] = x[i-1];
|
||||
move16();
|
||||
|
||||
FOR (j = 2; j < M; j+=2)
|
||||
{
|
||||
c[j] = mult_r(c[j-1], x[i-1]);
|
||||
move16();
|
||||
c[j] = add(c[j], sub(c[j], c[j-2]));
|
||||
move16();
|
||||
|
||||
/*r[j] = L_mac(r[j], c[j], gp);*/
|
||||
Mpy_32_16_ss(gp, c[j], &mh, &ml);
|
||||
r[j] = L_add(r[j], mh);
|
||||
move32();
|
||||
|
||||
c[j+1] = mult_r(c[j], x[i-1]);
|
||||
move16();
|
||||
c[j+1] = add(c[j+1], sub(c[j+1], c[j-1]));
|
||||
move16();
|
||||
|
||||
/*r[j+1] = L_mac(r[j+1], c[j+1], gn);*/
|
||||
Mpy_32_16_ss(gn, c[j+1], &mh, &ml);
|
||||
r[j+1] = L_add(r[j+1], mh);
|
||||
move32();
|
||||
}
|
||||
c[j] = mult_r(c[j-1], x[i-1]);
|
||||
move16();
|
||||
c[j] = add(c[j], sub(c[j], c[j-2]));
|
||||
move16();
|
||||
|
||||
Mpy_32_16_ss(gp, c[j], &mh, &ml);
|
||||
r[j] = L_add(r[j], mh);
|
||||
move32();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Add the endpoints x = cos(0) = 1 and x = cos(pi) = -1 as
|
||||
* well as the lower half of the unit circle.
|
||||
*---------------------------------------------------------------------*/
|
||||
gp = L_shr(L_add(G[0], G[N-1]), 1);
|
||||
gn = L_shr(L_sub(G[0], G[N-1]), 1);
|
||||
|
||||
r[0]= L_add(r[0], gp);
|
||||
move32();
|
||||
exp0 = norm_l(r[0]);
|
||||
L_Extract(L_shl(r[0], exp0), &rh[0], &rl[0]);
|
||||
|
||||
FOR (j = 1; j < M; j+=2)
|
||||
{
|
||||
L_Extract(L_shl(L_add(r[j], gn), exp0), &rh[j], &rl[j]);
|
||||
L_Extract(L_shl(L_add(r[j+1], gp), exp0), &rh[j+1], &rl[j+1]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* zeros2poly()
|
||||
*
|
||||
* Computes the coefficients of the polynomials
|
||||
*
|
||||
* R(x) = prod (x - x[i]),
|
||||
* i = 0,2,4,...
|
||||
*
|
||||
* S(x) = prod (x - x[i]),
|
||||
* i = 1,3,5,...
|
||||
*
|
||||
* when their zeros x[i] are given for i = 0, 1, ..., n-1. The
|
||||
* routine assumes n = 1 or even n greater than or equal to 4.
|
||||
*
|
||||
* The polynomial coefficients are returned in R[0:n/2-1] and
|
||||
* S[0:n/2-1]. The leading coefficients are in R[0] and S[0].
|
||||
*---------------------------------------------------------------------*/
|
||||
static void zeros2poly_fx(
|
||||
Word16 x[], /* i: Q15 Zeros of R(x) and S(x) */
|
||||
Word32 R[], /* o: Q22 Coefficients of R(x) */
|
||||
Word32 S[] /* o: Q22 Coefficients of S(x) */
|
||||
)
|
||||
{
|
||||
Word16 xr, xs;
|
||||
Word16 i, j;
|
||||
Word32 mh;
|
||||
UWord16 ml;
|
||||
|
||||
R[0] = (1<<27)-1;
|
||||
move32();
|
||||
S[0] = (1<<27)-1;
|
||||
move32();
|
||||
R[1] = L_msu(0, x[0], 1<<11);
|
||||
move32();
|
||||
S[1] = L_msu(0, x[1], 1<<11);
|
||||
move32();
|
||||
|
||||
FOR (i = 2; i <= NC; i++)
|
||||
{
|
||||
xr = negate(x[2*i-2]);
|
||||
xs = negate(x[2*i-1]);
|
||||
|
||||
Mpy_32_16_ss(R[i-1], xr, &R[i], &ml);
|
||||
Mpy_32_16_ss(S[i-1], xs, &S[i], &ml);
|
||||
|
||||
FOR (j = i-1; j > 0; j--)
|
||||
{
|
||||
Mpy_32_16_ss(R[j-1], xr, &mh, &ml);
|
||||
R[j] = L_add(R[j], mh);
|
||||
Mpy_32_16_ss(S[j-1], xs, &mh, &ml);
|
||||
S[j] = L_add(S[j], mh);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* polydecomp()
|
||||
*
|
||||
* Computes the coefficients of the symmetric and antisymmetric
|
||||
* polynomials P(z) and Q(z) that define the line spectrum pair
|
||||
* decomposition of a given polynomial A(z) of order n. For even n,
|
||||
*
|
||||
* P(z) = [A(z) + z^(n+1) A(1/z)]/(1/z + 1),
|
||||
* Q(z) = [A(z) - z^(n+1) A(1/z)]/(1/z - 1),
|
||||
*
|
||||
* These polynomials are then expressed in their direct form,
|
||||
* respectively, R(x) and S(x), on the real axis x = cos w using
|
||||
* explicit Chebyshev polynomials of the first kind.
|
||||
*
|
||||
* The coefficients of the polynomials R(x) and S(x) are returned
|
||||
* in R[0:n/2] and S[0:n/2] for the given linear prediction
|
||||
* coefficients A[0:n/2]. Note that R(x) and S(x) are formed in
|
||||
* place such that P(z) is stored in the same array than R(x),
|
||||
* and Q(z) is stored in the same array than S(x).
|
||||
*
|
||||
* The routines assumes n = 16.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
static void polydecomp_fx(
|
||||
Word16 A[], /* i: Q12 linear prediction coefficients */
|
||||
Word32 R[], /* o: Q20 coefficients of R(x) */
|
||||
Word32 S[] /* o: Q20 coefficients of S(x) */
|
||||
)
|
||||
{
|
||||
Word16 scale;
|
||||
Word16 i;
|
||||
Word32 Ltmp1, Ltmp2;
|
||||
|
||||
scale = shl((1<<5), norm_s(A[0]));
|
||||
|
||||
R[0] = (1<<20)-1;
|
||||
move32(); /* Q20 */
|
||||
S[0] = (1<<20)-1;
|
||||
move32();
|
||||
|
||||
FOR(i=0; i<NC; i++)
|
||||
{
|
||||
Ltmp1 = L_mult(A[i+1], scale);
|
||||
|
||||
Ltmp2 = L_msu(Ltmp1, A[M-i], scale);
|
||||
Ltmp1 = L_mac(Ltmp1, A[M-i], scale);
|
||||
|
||||
R[i+1] = L_sub(Ltmp1, R[i]);
|
||||
move32();
|
||||
S[i+1] = L_add(Ltmp2, S[i]);
|
||||
move32();
|
||||
}
|
||||
|
||||
cheb2poly_fx(R);
|
||||
cheb2poly_fx(S);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* cheb2poly_fx()
|
||||
*
|
||||
* Computes the coefficients of the explicit Chebyshev polynomial
|
||||
* P(x) = P[0]*x^n + P[1]*x^(n-1) + ... + P[n] given the coefficients
|
||||
* of the series
|
||||
*
|
||||
* C(x) = C[0]*T_n(x) + C[1]*T_n-1(x) + ... + C[n]*T_0(x)
|
||||
*
|
||||
* where T_n(x) is the nth Chebyshev polynomial of the first kind.
|
||||
* This implementation assumes C[0] = 1. Only value n = 8 is
|
||||
* supported.
|
||||
*
|
||||
* The conversion from C(x) to P(x) is done in place such that the
|
||||
* coefficients of C(x) are given in P[0:8] and those of P(x) are
|
||||
* returned in the same array.
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
static void cheb2poly_fx(
|
||||
Word32 L_P[] /* i/o Q20: The coefficients of C(x) and P(x) */
|
||||
)
|
||||
{
|
||||
Word32 L_C[NC+1], L_tmp;
|
||||
Word16 i;
|
||||
|
||||
FOR(i=1; i<=NC; i++)
|
||||
{
|
||||
L_C[i] = L_P[i];
|
||||
move32();
|
||||
}
|
||||
|
||||
L_P[0] = (1<<27)-1;
|
||||
move32();
|
||||
|
||||
L_P[1] = L_shl(L_C[1], 6);
|
||||
move32(); /* 64.0*C[1] */
|
||||
L_P[8] = L_shl(L_C[1], 3);
|
||||
move32(); /* 8.0*C[1] */
|
||||
|
||||
L_P[5] = L_sub(L_P[1], L_P[8]);
|
||||
move32(); /* 56.0*C[1] */
|
||||
|
||||
L_P[2] = L_shl(L_C[3], 2);
|
||||
move32();
|
||||
L_tmp = L_add(L_C[3], L_P[2]); /* 5.0*C[3] */
|
||||
L_P[7] = L_sub(L_tmp, L_sub(L_P[8], L_C[1]));
|
||||
move32(); /* -7.0*C[1] */
|
||||
|
||||
L_P[8] = L_shl(L_C[3], 4);
|
||||
move32(); /* 16.0*C[3] */
|
||||
L_P[3] = L_sub(L_P[8], L_shl(L_P[5], 1));
|
||||
move32(); /*-112.0*C[1] */
|
||||
|
||||
L_P[5] = L_sub(L_P[5], L_add(L_P[8], L_P[2]));
|
||||
move32(); /* -20.0*C[3] */
|
||||
|
||||
L_P[2] = L_shl(L_C[5], 2);
|
||||
move32();
|
||||
L_P[5] = L_add(L_P[5], L_P[2]);
|
||||
move32(); /* 4.0*C[5] */
|
||||
|
||||
L_tmp = L_sub(L_P[7], L_sub(L_P[2], L_C[5])); /* -3.0*C[5] */
|
||||
L_P[7] = L_add(L_tmp, L_C[7]);
|
||||
move32(); /* C[7] */
|
||||
|
||||
L_P[6] = L_shl(L_C[2], 4);
|
||||
move32();
|
||||
L_tmp = L_sub((160<<20), L_P[6]);
|
||||
L_P[4] = L_sub(L_tmp, L_shl(L_C[2], 5));
|
||||
move32(); /* -48.0*C[2] */
|
||||
|
||||
L_tmp = L_add(L_P[6], L_shl(L_C[2], 1)); /* 18.0*C[2] */
|
||||
L_P[6] = L_sub(L_tmp, (32<<20));
|
||||
move32();
|
||||
|
||||
L_P[8] = L_shl(L_C[4], 3);
|
||||
move32();
|
||||
L_P[4] = L_add(L_P[4], L_P[8]);
|
||||
move32(); /* 8.0*C[4] */
|
||||
|
||||
L_tmp = L_sub(L_P[6], L_P[8]); /* -8.0*C[4] */
|
||||
L_P[6] = L_add(L_tmp, L_shl(L_C[6], 1));
|
||||
move32(); /* 2.0*C[6] */
|
||||
|
||||
L_tmp = L_shl(L_C[2], 5); /* 32.0*C[2] */
|
||||
L_P[2] = L_sub(L_tmp, (256<<20));
|
||||
move32();
|
||||
|
||||
L_tmp = L_add((1<<21)+1, L_C[8]);
|
||||
L_tmp = L_shr(L_tmp, 1); /* 1+0.5*C[8] */
|
||||
L_tmp = L_sub(L_tmp, L_C[2]);
|
||||
L_tmp = L_add(L_tmp, L_C[4]);
|
||||
L_P[8] = L_sub(L_tmp, L_C[6]);
|
||||
move32();
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+423
@@ -0,0 +1,423 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#define AMRWB_MAGIC_NUMBER "#!AMR-WB\n" /* defined in RFC4867 */
|
||||
#define EVS_MAGIC_NUMBER "#!EVS_MC1.0\n" /* defined in 26.445 */
|
||||
|
||||
static const Word32 AMRWB_IOmode2rate[16] =
|
||||
{
|
||||
6600, /* AMRWB_IO_6600 */
|
||||
8850, /* AMRWB_IO_8850 */
|
||||
12650, /* AMRWB_IO_1265 */
|
||||
14250, /* AMRWB_IO_1425 */
|
||||
15850, /* AMRWB_IO_1585 */
|
||||
18250, /* AMRWB_IO_1825 */
|
||||
19850, /* AMRWB_IO_1985 */
|
||||
23050, /* AMRWB_IO_2305 */
|
||||
23850, /* AMRWB_IO_2385 */
|
||||
1750, /* AMRWB_IO_SID */
|
||||
-1, /* AMRWB_IO_FUT1 */
|
||||
-1, /* AMRWB_IO_FUT2 */
|
||||
-1, /* AMRWB_IO_FUT3 */
|
||||
-1, /* AMRWB_IO_FUT4 */
|
||||
0, /* SPEECH_LOST */
|
||||
0 /* NO_DATA_TYPE */
|
||||
};
|
||||
|
||||
static const Word32 PRIMARYmode2rate[16] =
|
||||
{
|
||||
2800, /* PRIMARY_2800 */
|
||||
7200, /* PRIMARY_7200 */
|
||||
8000, /* PRIMARY_8000 */
|
||||
9600, /* PRIMARY_9600 */
|
||||
13200, /* PRIMARY_13200 */
|
||||
16400, /* PRIMARY_16400 */
|
||||
24400, /* PRIMARY_24400 */
|
||||
32000, /* PRIMARY_32000 */
|
||||
48000, /* PRIMARY_48000 */
|
||||
64000, /* PRIMARY_64000 */
|
||||
96000, /* PRIMARY_96000 */
|
||||
128000, /* PRIMARY_128000 */
|
||||
2400, /* PRIMARY_SID */
|
||||
-1, /* PRIMARY_FUT1 */
|
||||
0, /* SPEECH_LOST */
|
||||
0 /* NO_DATA_TYPE */
|
||||
};
|
||||
|
||||
/* sorting tables for all AMR-WB IO modes */
|
||||
|
||||
static const Word16 sort_660[132] =
|
||||
{
|
||||
0, 5, 6, 7, 61, 84, 107, 130, 62, 85,
|
||||
8, 4, 37, 38, 39, 40, 58, 81, 104, 127,
|
||||
60, 83, 106, 129, 108, 131, 128, 41, 42, 80,
|
||||
126, 1, 3, 57, 103, 82, 105, 59, 2, 63,
|
||||
109, 110, 86, 19, 22, 23, 64, 87, 18, 20,
|
||||
21, 17, 13, 88, 43, 89, 65, 111, 14, 24,
|
||||
25, 26, 27, 28, 15, 16, 44, 90, 66, 112,
|
||||
9, 11, 10, 12, 67, 113, 29, 30, 31, 32,
|
||||
34, 33, 35, 36, 45, 51, 68, 74, 91, 97,
|
||||
114, 120, 46, 69, 92, 115, 52, 75, 98, 121,
|
||||
47, 70, 93, 116, 53, 76, 99, 122, 48, 71,
|
||||
94, 117, 54, 77, 100, 123, 49, 72, 95, 118,
|
||||
55, 78, 101, 124, 50, 73, 96, 119, 56, 79,
|
||||
102, 125
|
||||
};
|
||||
|
||||
static const Word16 sort_885[177] =
|
||||
{
|
||||
0, 4, 6, 7, 5, 3, 47, 48, 49, 112,
|
||||
113, 114, 75, 106, 140, 171, 80, 111, 145, 176,
|
||||
77, 108, 142, 173, 78, 109, 143, 174, 79, 110,
|
||||
144, 175, 76, 107, 141, 172, 50, 115, 51, 2,
|
||||
1, 81, 116, 146, 19, 21, 12, 17, 18, 20,
|
||||
16, 25, 13, 10, 14, 24, 23, 22, 26, 8,
|
||||
15, 52, 117, 31, 82, 147, 9, 33, 11, 83,
|
||||
148, 53, 118, 28, 27, 84, 149, 34, 35, 29,
|
||||
46, 32, 30, 54, 119, 37, 36, 39, 38, 40,
|
||||
85, 150, 41, 42, 43, 44, 45, 55, 60, 65,
|
||||
70, 86, 91, 96, 101, 120, 125, 130, 135, 151,
|
||||
156, 161, 166, 56, 87, 121, 152, 61, 92, 126,
|
||||
157, 66, 97, 131, 162, 71, 102, 136, 167, 57,
|
||||
88, 122, 153, 62, 93, 127, 158, 67, 98, 132,
|
||||
163, 72, 103, 137, 168, 58, 89, 123, 154, 63,
|
||||
94, 128, 159, 68, 99, 133, 164, 73, 104, 138,
|
||||
169, 59, 90, 124, 155, 64, 95, 129, 160, 69,
|
||||
100, 134, 165, 74, 105, 139, 170
|
||||
};
|
||||
|
||||
static const Word16 sort_1265[253] =
|
||||
{
|
||||
0, 4, 6, 93, 143, 196, 246, 7, 5, 3,
|
||||
47, 48, 49, 50, 51, 150, 151, 152, 153, 154,
|
||||
94, 144, 197, 247, 99, 149, 202, 252, 96, 146,
|
||||
199, 249, 97, 147, 200, 250, 100, 203, 98, 148,
|
||||
201, 251, 95, 145, 198, 248, 52, 2, 1, 101,
|
||||
204, 155, 19, 21, 12, 17, 18, 20, 16, 25,
|
||||
13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
|
||||
156, 31, 102, 205, 9, 33, 11, 103, 206, 54,
|
||||
157, 28, 27, 104, 207, 34, 35, 29, 46, 32,
|
||||
30, 55, 158, 37, 36, 39, 38, 40, 105, 208,
|
||||
41, 42, 43, 44, 45, 56, 106, 159, 209, 57,
|
||||
66, 75, 84, 107, 116, 125, 134, 160, 169, 178,
|
||||
187, 210, 219, 228, 237, 58, 108, 161, 211, 62,
|
||||
112, 165, 215, 67, 117, 170, 220, 71, 121, 174,
|
||||
224, 76, 126, 179, 229, 80, 130, 183, 233, 85,
|
||||
135, 188, 238, 89, 139, 192, 242, 59, 109, 162,
|
||||
212, 63, 113, 166, 216, 68, 118, 171, 221, 72,
|
||||
122, 175, 225, 77, 127, 180, 230, 81, 131, 184,
|
||||
234, 86, 136, 189, 239, 90, 140, 193, 243, 60,
|
||||
110, 163, 213, 64, 114, 167, 217, 69, 119, 172,
|
||||
222, 73, 123, 176, 226, 78, 128, 181, 231, 82,
|
||||
132, 185, 235, 87, 137, 190, 240, 91, 141, 194,
|
||||
244, 61, 111, 164, 214, 65, 115, 168, 218, 70,
|
||||
120, 173, 223, 74, 124, 177, 227, 79, 129, 182,
|
||||
232, 83, 133, 186, 236, 88, 138, 191, 241, 92,
|
||||
142, 195, 245
|
||||
};
|
||||
|
||||
static const Word16 sort_1425[285] =
|
||||
{
|
||||
0, 4, 6, 101, 159, 220, 278, 7, 5, 3,
|
||||
47, 48, 49, 50, 51, 166, 167, 168, 169, 170,
|
||||
102, 160, 221, 279, 107, 165, 226, 284, 104, 162,
|
||||
223, 281, 105, 163, 224, 282, 108, 227, 106, 164,
|
||||
225, 283, 103, 161, 222, 280, 52, 2, 1, 109,
|
||||
228, 171, 19, 21, 12, 17, 18, 20, 16, 25,
|
||||
13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
|
||||
172, 31, 110, 229, 9, 33, 11, 111, 230, 54,
|
||||
173, 28, 27, 112, 231, 34, 35, 29, 46, 32,
|
||||
30, 55, 174, 37, 36, 39, 38, 40, 113, 232,
|
||||
41, 42, 43, 44, 45, 56, 114, 175, 233, 62,
|
||||
120, 181, 239, 75, 133, 194, 252, 57, 115, 176,
|
||||
234, 63, 121, 182, 240, 70, 128, 189, 247, 76,
|
||||
134, 195, 253, 83, 141, 202, 260, 92, 150, 211,
|
||||
269, 84, 142, 203, 261, 93, 151, 212, 270, 85,
|
||||
143, 204, 262, 94, 152, 213, 271, 86, 144, 205,
|
||||
263, 95, 153, 214, 272, 64, 122, 183, 241, 77,
|
||||
135, 196, 254, 65, 123, 184, 242, 78, 136, 197,
|
||||
255, 87, 145, 206, 264, 96, 154, 215, 273, 58,
|
||||
116, 177, 235, 66, 124, 185, 243, 71, 129, 190,
|
||||
248, 79, 137, 198, 256, 88, 146, 207, 265, 97,
|
||||
155, 216, 274, 59, 117, 178, 236, 67, 125, 186,
|
||||
244, 72, 130, 191, 249, 80, 138, 199, 257, 89,
|
||||
147, 208, 266, 98, 156, 217, 275, 60, 118, 179,
|
||||
237, 68, 126, 187, 245, 73, 131, 192, 250, 81,
|
||||
139, 200, 258, 90, 148, 209, 267, 99, 157, 218,
|
||||
276, 61, 119, 180, 238, 69, 127, 188, 246, 74,
|
||||
132, 193, 251, 82, 140, 201, 259, 91, 149, 210,
|
||||
268, 100, 158, 219, 277
|
||||
};
|
||||
|
||||
static const Word16 sort_1585[317] =
|
||||
{
|
||||
0, 4, 6, 109, 175, 244, 310, 7, 5, 3,
|
||||
47, 48, 49, 50, 51, 182, 183, 184, 185, 186,
|
||||
110, 176, 245, 311, 115, 181, 250, 316, 112, 178,
|
||||
247, 313, 113, 179, 248, 314, 116, 251, 114, 180,
|
||||
249, 315, 111, 177, 246, 312, 52, 2, 1, 117,
|
||||
252, 187, 19, 21, 12, 17, 18, 20, 16, 25,
|
||||
13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
|
||||
188, 31, 118, 253, 9, 33, 11, 119, 254, 54,
|
||||
189, 28, 27, 120, 255, 34, 35, 29, 46, 32,
|
||||
30, 55, 190, 37, 36, 39, 38, 40, 121, 256,
|
||||
41, 42, 43, 44, 45, 56, 122, 191, 257, 63,
|
||||
129, 198, 264, 76, 142, 211, 277, 89, 155, 224,
|
||||
290, 102, 168, 237, 303, 57, 123, 192, 258, 70,
|
||||
136, 205, 271, 83, 149, 218, 284, 96, 162, 231,
|
||||
297, 62, 128, 197, 263, 75, 141, 210, 276, 88,
|
||||
154, 223, 289, 101, 167, 236, 302, 58, 124, 193,
|
||||
259, 71, 137, 206, 272, 84, 150, 219, 285, 97,
|
||||
163, 232, 298, 59, 125, 194, 260, 64, 130, 199,
|
||||
265, 67, 133, 202, 268, 72, 138, 207, 273, 77,
|
||||
143, 212, 278, 80, 146, 215, 281, 85, 151, 220,
|
||||
286, 90, 156, 225, 291, 93, 159, 228, 294, 98,
|
||||
164, 233, 299, 103, 169, 238, 304, 106, 172, 241,
|
||||
307, 60, 126, 195, 261, 65, 131, 200, 266, 68,
|
||||
134, 203, 269, 73, 139, 208, 274, 78, 144, 213,
|
||||
279, 81, 147, 216, 282, 86, 152, 221, 287, 91,
|
||||
157, 226, 292, 94, 160, 229, 295, 99, 165, 234,
|
||||
300, 104, 170, 239, 305, 107, 173, 242, 308, 61,
|
||||
127, 196, 262, 66, 132, 201, 267, 69, 135, 204,
|
||||
270, 74, 140, 209, 275, 79, 145, 214, 280, 82,
|
||||
148, 217, 283, 87, 153, 222, 288, 92, 158, 227,
|
||||
293, 95, 161, 230, 296, 100, 166, 235, 301, 105,
|
||||
171, 240, 306, 108, 174, 243, 309
|
||||
};
|
||||
|
||||
static const Word16 sort_1825[365] =
|
||||
{
|
||||
0, 4, 6, 121, 199, 280, 358, 7, 5, 3,
|
||||
47, 48, 49, 50, 51, 206, 207, 208, 209, 210,
|
||||
122, 200, 281, 359, 127, 205, 286, 364, 124, 202,
|
||||
283, 361, 125, 203, 284, 362, 128, 287, 126, 204,
|
||||
285, 363, 123, 201, 282, 360, 52, 2, 1, 129,
|
||||
288, 211, 19, 21, 12, 17, 18, 20, 16, 25,
|
||||
13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
|
||||
212, 31, 130, 289, 9, 33, 11, 131, 290, 54,
|
||||
213, 28, 27, 132, 291, 34, 35, 29, 46, 32,
|
||||
30, 55, 214, 37, 36, 39, 38, 40, 133, 292,
|
||||
41, 42, 43, 44, 45, 56, 134, 215, 293, 198,
|
||||
299, 136, 120, 138, 60, 279, 58, 62, 357, 139,
|
||||
140, 295, 156, 57, 219, 297, 63, 217, 137, 170,
|
||||
300, 222, 64, 106, 61, 78, 294, 92, 142, 141,
|
||||
135, 221, 296, 301, 343, 59, 298, 184, 329, 315,
|
||||
220, 216, 265, 251, 218, 237, 352, 223, 157, 86,
|
||||
171, 87, 164, 351, 111, 302, 65, 178, 115, 323,
|
||||
72, 192, 101, 179, 93, 73, 193, 151, 337, 309,
|
||||
143, 274, 69, 324, 165, 150, 97, 338, 110, 310,
|
||||
330, 273, 68, 107, 175, 245, 114, 79, 113, 189,
|
||||
246, 259, 174, 71, 185, 96, 344, 100, 322, 83,
|
||||
334, 316, 333, 252, 161, 348, 147, 82, 269, 232,
|
||||
260, 308, 353, 347, 163, 231, 306, 320, 188, 270,
|
||||
146, 177, 266, 350, 256, 85, 149, 116, 191, 160,
|
||||
238, 258, 336, 305, 255, 88, 224, 99, 339, 230,
|
||||
228, 227, 272, 242, 241, 319, 233, 311, 102, 74,
|
||||
180, 275, 66, 194, 152, 325, 172, 247, 244, 261,
|
||||
117, 158, 166, 354, 75, 144, 108, 312, 94, 186,
|
||||
303, 80, 234, 89, 195, 112, 340, 181, 345, 317,
|
||||
326, 276, 239, 167, 118, 313, 70, 355, 327, 253,
|
||||
190, 176, 271, 104, 98, 153, 103, 90, 76, 267,
|
||||
277, 248, 225, 262, 182, 84, 154, 235, 335, 168,
|
||||
331, 196, 341, 249, 162, 307, 148, 349, 263, 321,
|
||||
257, 243, 229, 356, 159, 119, 67, 187, 173, 145,
|
||||
240, 77, 304, 332, 314, 342, 109, 254, 81, 278,
|
||||
105, 91, 346, 318, 183, 250, 197, 328, 95, 155,
|
||||
169, 268, 226, 236, 264
|
||||
};
|
||||
|
||||
static const Word16 sort_1985[397] =
|
||||
{
|
||||
0, 4, 6, 129, 215, 304, 390, 7, 5, 3,
|
||||
47, 48, 49, 50, 51, 222, 223, 224, 225, 226,
|
||||
130, 216, 305, 391, 135, 221, 310, 396, 132, 218,
|
||||
307, 393, 133, 219, 308, 394, 136, 311, 134, 220,
|
||||
309, 395, 131, 217, 306, 392, 52, 2, 1, 137,
|
||||
312, 227, 19, 21, 12, 17, 18, 20, 16, 25,
|
||||
13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
|
||||
228, 31, 138, 313, 9, 33, 11, 139, 314, 54,
|
||||
229, 28, 27, 140, 315, 34, 35, 29, 46, 32,
|
||||
30, 55, 230, 37, 36, 39, 38, 40, 141, 316,
|
||||
41, 42, 43, 44, 45, 56, 142, 231, 317, 63,
|
||||
73, 92, 340, 82, 324, 149, 353, 159, 334, 165,
|
||||
338, 178, 163, 254, 77, 168, 257, 153, 343, 57,
|
||||
248, 238, 79, 252, 166, 67, 80, 201, 101, 267,
|
||||
143, 164, 341, 255, 339, 187, 376, 318, 78, 328,
|
||||
362, 115, 232, 242, 253, 290, 276, 62, 58, 158,
|
||||
68, 93, 179, 319, 148, 169, 154, 72, 385, 329,
|
||||
333, 344, 102, 83, 144, 233, 323, 124, 243, 192,
|
||||
354, 237, 64, 247, 202, 209, 150, 116, 335, 268,
|
||||
239, 299, 188, 196, 298, 94, 195, 258, 123, 363,
|
||||
384, 109, 325, 371, 170, 370, 84, 110, 295, 180,
|
||||
74, 210, 191, 106, 291, 205, 367, 381, 377, 206,
|
||||
355, 122, 119, 120, 383, 160, 105, 108, 277, 380,
|
||||
294, 284, 285, 345, 208, 269, 249, 366, 386, 300,
|
||||
297, 259, 125, 369, 197, 97, 194, 286, 211, 281,
|
||||
280, 183, 372, 87, 155, 283, 59, 348, 327, 184,
|
||||
76, 111, 330, 203, 349, 69, 98, 152, 145, 189,
|
||||
66, 320, 337, 173, 358, 251, 198, 174, 263, 262,
|
||||
126, 241, 193, 88, 388, 117, 95, 387, 112, 359,
|
||||
287, 244, 103, 272, 301, 171, 162, 234, 273, 127,
|
||||
373, 181, 292, 85, 378, 302, 121, 107, 364, 346,
|
||||
356, 212, 278, 213, 65, 382, 288, 207, 113, 175,
|
||||
99, 296, 374, 368, 199, 260, 185, 336, 331, 161,
|
||||
270, 264, 250, 240, 75, 350, 151, 60, 89, 321,
|
||||
156, 274, 360, 326, 70, 282, 167, 146, 352, 81,
|
||||
91, 389, 266, 245, 177, 235, 190, 256, 204, 342,
|
||||
128, 118, 303, 104, 379, 182, 114, 375, 200, 96,
|
||||
293, 172, 214, 365, 279, 86, 289, 351, 347, 357,
|
||||
261, 186, 176, 271, 90, 100, 147, 322, 275, 361,
|
||||
71, 332, 61, 265, 157, 246, 236
|
||||
};
|
||||
|
||||
static const Word16 sort_2305[461] =
|
||||
{
|
||||
0, 4, 6, 145, 247, 352, 454, 7, 5, 3,
|
||||
47, 48, 49, 50, 51, 254, 255, 256, 257, 258,
|
||||
146, 248, 353, 455, 151, 253, 358, 460, 148, 250,
|
||||
355, 457, 149, 251, 356, 458, 152, 359, 150, 252,
|
||||
357, 459, 147, 249, 354, 456, 52, 2, 1, 153,
|
||||
360, 259, 19, 21, 12, 17, 18, 20, 16, 25,
|
||||
13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
|
||||
260, 31, 154, 361, 9, 33, 11, 155, 362, 54,
|
||||
261, 28, 27, 156, 363, 34, 35, 29, 46, 32,
|
||||
30, 55, 262, 37, 36, 39, 38, 40, 157, 364,
|
||||
41, 42, 43, 44, 45, 56, 158, 263, 365, 181,
|
||||
192, 170, 79, 57, 399, 90, 159, 297, 377, 366,
|
||||
275, 68, 183, 388, 286, 194, 299, 92 , 70, 182,
|
||||
401, 172, 59, 91, 58, 400, 368, 161, 81, 160,
|
||||
264, 171, 80, 389, 390, 378, 379, 193, 298, 69,
|
||||
266, 265, 367, 277, 288, 276, 287, 184, 60, 195,
|
||||
82, 93, 71, 369, 402, 173, 162, 444, 300, 391,
|
||||
98, 76, 278, 61, 267, 374, 135, 411, 167, 102,
|
||||
380, 200, 87, 178, 65, 94, 204, 124, 72, 342,
|
||||
189, 305, 381, 396, 433, 301, 226, 407, 289, 237,
|
||||
113, 215, 185, 128, 309, 403, 116, 320, 196, 331,
|
||||
370, 422, 174, 64, 392, 83, 425, 219, 134, 188,
|
||||
432, 112, 427, 139, 279, 163, 436, 208, 447, 218,
|
||||
236, 229, 97, 294, 385, 230, 166, 268, 177, 443,
|
||||
225, 426, 101, 272, 138, 127, 290, 117, 347, 199,
|
||||
414, 95, 140, 240, 410, 395, 209, 129, 283, 346,
|
||||
105, 241, 437, 86, 308, 448, 203, 345, 186, 107,
|
||||
220, 415, 334, 319, 106, 313, 118, 123, 73, 207,
|
||||
421, 214, 384, 373, 438, 62, 371, 341, 75, 449,
|
||||
168, 323, 164, 242, 416, 324, 304, 197, 335, 404,
|
||||
271, 63, 191, 325, 96, 169, 231, 280, 312, 187,
|
||||
406, 84, 201, 100, 67, 382, 175, 336, 202, 330,
|
||||
269, 393, 376, 383, 293, 307, 409, 179, 285, 314,
|
||||
302, 372, 398, 190, 180, 89, 99, 103, 232, 78,
|
||||
88, 77, 136, 387, 165, 198, 394, 125, 176, 428,
|
||||
74, 375, 238, 227, 66, 273, 282, 141, 306, 412,
|
||||
114, 85, 130, 348, 119, 291, 296, 386, 233, 397,
|
||||
303, 405, 284, 445, 423, 221, 210, 205, 450, 108,
|
||||
274, 434, 216, 343, 337, 142, 243, 321, 408, 451,
|
||||
310, 292, 120, 109, 281, 439, 270, 429, 332, 295,
|
||||
418, 211, 315, 222, 326, 131, 430, 244, 327, 349,
|
||||
417, 316, 143, 338, 440, 234, 110, 212, 452, 245,
|
||||
121, 419, 350, 223, 132, 441, 328, 413, 317, 339,
|
||||
126, 104, 137, 446, 344, 239, 435, 115, 333, 206,
|
||||
322, 217, 228, 424, 453, 311, 351, 111, 442, 224,
|
||||
213, 122, 431, 340, 235, 246, 133, 144, 420, 329,
|
||||
318
|
||||
};
|
||||
|
||||
static const Word16 sort_2385[477] =
|
||||
{
|
||||
0, 4, 6, 145, 251, 360, 466, 7, 5, 3,
|
||||
47, 48, 49, 50, 51, 262, 263, 264, 265, 266,
|
||||
146, 252, 361, 467, 151, 257, 366, 472, 148, 254,
|
||||
363, 469, 149, 255, 364, 470, 156, 371, 150, 256,
|
||||
365, 471, 147, 253, 362, 468, 52, 2, 1, 157,
|
||||
372, 267, 19, 21, 12, 17, 18, 20, 16, 25,
|
||||
13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
|
||||
268, 31, 152, 153, 154, 155, 258, 259, 260, 261,
|
||||
367, 368, 369, 370, 473, 474, 475, 476, 158, 373,
|
||||
9, 33, 11, 159, 374, 54, 269, 28, 27, 160,
|
||||
375, 34, 35, 29, 46, 32, 30, 55, 270, 37,
|
||||
36, 39, 38, 40, 161, 376, 41, 42, 43, 44,
|
||||
45, 56, 162, 271, 377, 185, 196, 174, 79, 57,
|
||||
411, 90, 163, 305, 389, 378, 283, 68, 187, 400,
|
||||
294, 198, 307, 92, 70, 186, 413, 176, 59, 91,
|
||||
58, 412, 380, 165, 81, 164, 272, 175, 80, 401,
|
||||
402, 390, 391, 197, 306, 69, 274, 273, 379, 285,
|
||||
296, 284, 295, 188, 60, 199, 82, 93, 71, 381,
|
||||
414, 177, 166, 456, 308, 403, 98, 76, 286, 61,
|
||||
275, 386, 135, 423, 171, 102, 392, 204, 87, 182,
|
||||
65, 94, 208, 124, 72, 350, 193, 313, 393, 408,
|
||||
445, 309, 230, 419, 297, 241, 113, 219, 189, 128,
|
||||
317, 415, 116, 328, 200, 339, 382, 434, 178, 64,
|
||||
404, 83, 437, 223, 134, 192, 444, 112, 439, 139,
|
||||
287, 167, 448, 212, 459, 222, 240, 233, 97, 302,
|
||||
397, 234, 170, 276, 181, 455, 229, 438, 101, 280,
|
||||
138, 127, 298, 117, 355, 203, 426, 95, 140, 244,
|
||||
422, 407, 213, 129, 291, 354, 105, 245, 449, 86,
|
||||
316, 460, 207, 353, 190, 107, 224, 427, 342, 327,
|
||||
106, 321, 118, 123, 73, 211, 433, 218, 396, 385,
|
||||
450, 62, 383, 349, 75, 461, 172, 331, 168, 246,
|
||||
428, 332, 312, 201, 343, 416, 279, 63, 195, 333,
|
||||
96, 173, 235, 288, 320, 191, 418, 84, 205, 100,
|
||||
67, 394, 179, 344, 206, 338, 277, 405, 388, 395,
|
||||
301, 315, 421, 183, 293, 322, 310, 384, 410, 194,
|
||||
184, 89, 99, 103, 236, 78, 88, 77, 136, 399,
|
||||
169, 202, 406, 125, 180, 440, 74, 387, 242, 231,
|
||||
66, 281, 290, 141, 314, 424, 114, 85, 130, 356,
|
||||
119, 299, 304, 398, 237, 409, 311, 417, 292, 457,
|
||||
435, 225, 214, 209, 462, 108, 282, 446, 220, 351,
|
||||
345, 142, 247, 329, 420, 463, 318, 300, 120, 109,
|
||||
289, 451, 278, 441, 340, 303, 430, 215, 323, 226,
|
||||
334, 131, 442, 248, 335, 357, 429, 324, 143, 346,
|
||||
452, 238, 110, 216, 464, 249, 121, 431, 358, 227,
|
||||
132, 453, 336, 425, 325, 347, 126, 104, 137, 458,
|
||||
352, 243, 447, 115, 341, 210, 330, 221, 232, 436,
|
||||
465, 319, 359, 111, 454, 228, 217, 122, 443, 348,
|
||||
239, 250, 133, 144, 432, 337, 326
|
||||
};
|
||||
|
||||
static const Word16 sort_SID[35] =
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34
|
||||
};
|
||||
|
||||
/* pointer table for bit sorting tables */
|
||||
static const Word16 * const sort_ptr[16] = { sort_660, sort_885, sort_1265, sort_1425, sort_1585, sort_1825, sort_1985, sort_2305,
|
||||
sort_2385, sort_SID, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
/* 4 bit to 3 bit AMR-WB CMR remapping table */
|
||||
static const Word16 amrwb_3bit_cmr[16] =
|
||||
{
|
||||
0x00, /* AMRWB_660 */
|
||||
0x01, /* AMRWB_885 */
|
||||
0x02, /* AMRWB_1265 */
|
||||
0x05, /* AMRWB_1425 */
|
||||
0x03, /* AMRWB_1585 */
|
||||
0x06, /* AMRWB_1825 */
|
||||
0x06, /* AMRWB_1985 -> AMRWB_1825 */
|
||||
0x06, /* AMRWB_2305 -> AMRWB_1825 */
|
||||
0x04, /* AMRWB_2385 */
|
||||
0x07, /* invalid request -> none */
|
||||
0x07, /* invalid request -> none */
|
||||
0x07, /* invalid request -> none */
|
||||
0x07, /* invalid request -> none */
|
||||
0x07, /* invalid request -> none */
|
||||
0x07, /* invalid request -> none */
|
||||
0x07 /* invalid request -> none */
|
||||
};
|
||||
|
||||
/* 3 bit to 4 bit AMR-WB CMR remapping table */
|
||||
static const Word16 amrwb_4bit_cmr[8] =
|
||||
{
|
||||
0x00, /* AMRWB_660 */
|
||||
0x01, /* AMRWB_885 */
|
||||
0x02, /* AMRWB_1265 */
|
||||
0x04, /* AMRWB_1585 */
|
||||
0x08, /* AMRWB_2385 */
|
||||
0x03, /* AMRWB_1425 */
|
||||
0x05, /* AMRWB_1825 */
|
||||
0x0f /* invalid */
|
||||
};
|
||||
Executable
+1297
File diff suppressed because it is too large
Load Diff
Executable
+882
@@ -0,0 +1,882 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "prot_fx.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "stl.h"
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Local functions
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
static void make_offset_scale_fx( Word16 j, const Word32 tab_no_cv[], const Word16 no_ld[],
|
||||
Word16 no_scl, Word32 offset_scale[][MAX_NO_SCALES+1]);
|
||||
static void init_offset_fx( Word32 offset_scale1[][MAX_NO_SCALES+1], Word32 offset_scale2[][MAX_NO_SCALES+1],
|
||||
Word32 offset_scale1_p[][MAX_NO_SCALES+1], Word32 offset_scale2_p[][MAX_NO_SCALES+1],
|
||||
Word16 no_scales[][2], Word16 no_scales_p[][2]);
|
||||
static void decode_comb_fx(Word32 index,Word16 *cv,Word16 idx_lead);
|
||||
static void decode_sign_pc1_fx( Word16 *c, Word16 idx_sign, Word16 parity );
|
||||
static void put_value_fx(Word16 *cv, Word16 *p, Word16 val, Word16 dim, Word16 no_new_val);
|
||||
static void decode_leaders_fx(Word16 index, Word16 idx_lead, Word16 *cv );
|
||||
static void idx2c_fx(Word16 n, Word16 *p, Word16 k, Word16 val );
|
||||
static void divide_64_32_fx(Word16 *xs,Word32 y, Word32 *result, Word32 *rem);
|
||||
static Word16
|
||||
decode_indexes_fx(Word16 * index,Word16 no_bits,const Word16 * p_scales, Word16 * p_no_scales,
|
||||
Word32 * p_offset_scale1, Word32 * p_offset_scale2,Word16 * x_lvq,Word16 mode_glb, Word16 *scales);
|
||||
static Word32 divide_32_32_fx(Word32 y, Word32 x, Word32 * rem);
|
||||
static Word16 divide_16_16_fx(Word16 y, Word16 x, Word16 *rem);
|
||||
|
||||
/* used in CNG-LP coding */
|
||||
void permute_fx(
|
||||
Word16 *pTmp1, /* i/o: vector whose components are to be permuted */
|
||||
const Word16 *perm /* i : permutation info (indexes that should be interchanged), max two perms */
|
||||
)
|
||||
{
|
||||
Word16 p1, p2;
|
||||
Word16 tmp;
|
||||
|
||||
p1 = perm[0];
|
||||
move16();
|
||||
p2 = perm[1];
|
||||
move16();
|
||||
tmp = pTmp1[p1];
|
||||
move16();
|
||||
pTmp1[p1] = pTmp1[p2];
|
||||
move16();
|
||||
move16();
|
||||
pTmp1[p2] = tmp;
|
||||
move16();
|
||||
p1 = perm[2];
|
||||
move16();
|
||||
|
||||
IF ( add(p1, 1) > 0 )
|
||||
{
|
||||
p2 = perm[3];
|
||||
move16();
|
||||
tmp = pTmp1[p1];
|
||||
move16();
|
||||
pTmp1[p1] = pTmp1[p2];
|
||||
move16();
|
||||
move16();
|
||||
pTmp1[p2] = tmp;
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void init_lvq_fx(
|
||||
Word32 offset_scale1[][MAX_NO_SCALES+1], /* o: lattice truncation index offset for the first LSF subvector - safety net structures*/
|
||||
Word32 offset_scale2[][MAX_NO_SCALES+1], /* o: lattice truncation index offset for the second LSF subvector - safety net structures*/
|
||||
Word32 offset_scale1_p[][MAX_NO_SCALES+1], /* o: lattice truncation index offset for the first LSF subvector - predictive structures*/
|
||||
Word32 offset_scale2_p[][MAX_NO_SCALES+1], /* o: lattice truncation index offset for the second LSF subvector - predictive structures*/
|
||||
Word16 no_scales[][2], /* o: number of truncations for each LSF subvector at each MSLVQ structure - safety net */
|
||||
Word16 no_scales_p[][2] /* o: number of truncations for each LSF subvector at each MSLVQ structure - predictive */
|
||||
)
|
||||
{
|
||||
Word16 i, j;
|
||||
/* safety-net mode */
|
||||
FOR(i=0; i<MAX_NO_MODES; i++)
|
||||
{
|
||||
j=0;
|
||||
move16();
|
||||
test();
|
||||
WHILE ((sub(j,MAX_NO_SCALES)<0) && (no_lead_fx[i][j] >0 ))
|
||||
{
|
||||
j++;
|
||||
}
|
||||
no_scales[i][0] = j;
|
||||
move16();
|
||||
j = MAX_NO_SCALES;
|
||||
move16();
|
||||
test();
|
||||
WHILE ((sub(j,shl(MAX_NO_SCALES,1))<0) && (no_lead_fx[i][j] >0 ))
|
||||
{
|
||||
j++;
|
||||
}
|
||||
no_scales[i][1] = sub(j, MAX_NO_SCALES);
|
||||
move16();
|
||||
}
|
||||
/* predictive mode */
|
||||
FOR(i=0; i<MAX_NO_MODES_p; i++)
|
||||
{
|
||||
j=0;
|
||||
move16();
|
||||
WHILE ((sub(j,MAX_NO_SCALES)<0) && (no_lead_p_fx[i][j] >0 ))
|
||||
{
|
||||
j++;
|
||||
}
|
||||
no_scales_p[i][0] = j;
|
||||
move16();
|
||||
j = MAX_NO_SCALES;
|
||||
move16();
|
||||
WHILE ((sub(j, shl(MAX_NO_SCALES,1))<0) && (no_lead_p_fx[i][j] >0 ))
|
||||
{
|
||||
j++;
|
||||
}
|
||||
no_scales_p[i][1] = sub(j,MAX_NO_SCALES);
|
||||
move16();
|
||||
}
|
||||
/* index offsets for each truncation */
|
||||
init_offset_fx( offset_scale1, offset_scale2, offset_scale1_p, offset_scale2_p, no_scales, no_scales_p );
|
||||
}
|
||||
|
||||
/* make_offset_scale_fx() - calculates scale offset values for a particular MSLVQ structure */
|
||||
static
|
||||
void make_offset_scale_fx(
|
||||
Word16 j, /* i: MSLVQ structure index */
|
||||
const Word32 tab_no_cv[], /* i: cummulated number of codevectors in each leader class */
|
||||
const Word16 no_ld[], /* i: number of leaders in each truncation for the MSLVQ structure j*/
|
||||
Word16 no_scl, /* i: number of truncations in the MSLVQ structure j */
|
||||
Word32 offset_scale[][MAX_NO_SCALES+1]/* o: offset values */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
|
||||
offset_scale[j][0] = L_deposit_l(1);
|
||||
FOR( i=1; i<=no_scl; i++ )
|
||||
{
|
||||
offset_scale[j][i] = L_add(offset_scale[j][sub(i,1)], tab_no_cv[no_ld[sub(i,1)]]);
|
||||
move32();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void init_offset_fx(
|
||||
Word32 offset_scale1[][MAX_NO_SCALES+1], /* o: lattice truncation index offset for the first LSF subvector - safety net structures*/
|
||||
Word32 offset_scale2[][MAX_NO_SCALES+1], /* o: lattice truncation index offset for the second LSF subvector - safety net structures*/
|
||||
Word32 offset_scale1_p[][MAX_NO_SCALES+1],/* o: lattice truncation index offset for the first LSF subvector - predictive structures*/
|
||||
Word32 offset_scale2_p[][MAX_NO_SCALES+1],/* o: lattice truncation index offset for the second LSF subvector - predictive structures*/
|
||||
Word16 no_scales[][2], /* i: number of truncations for each LSF subvector at each MSLVQ structure - safety net */
|
||||
Word16 no_scales_p[][2] /* i: number of truncations for each LSF subvector at each MSLVQ structure - predictive */
|
||||
)
|
||||
{
|
||||
Word16 j;
|
||||
/* safety-net */
|
||||
FOR( j=0; j<MAX_NO_MODES; j++ )
|
||||
{
|
||||
make_offset_scale_fx( j, table_no_cv_fx, no_lead_fx[j], no_scales[j][0], offset_scale1 );
|
||||
make_offset_scale_fx( j, table_no_cv_fx, &no_lead_fx[j][MAX_NO_SCALES], no_scales[j][1], offset_scale2 );
|
||||
}
|
||||
/* predictive modes AR and MA */
|
||||
FOR( j=0; j<MAX_NO_MODES_p; j++ )
|
||||
{
|
||||
make_offset_scale_fx(j, table_no_cv_fx, no_lead_p_fx[j], no_scales_p[j][0], offset_scale1_p);
|
||||
make_offset_scale_fx(j, table_no_cv_fx, &no_lead_p_fx[j][MAX_NO_SCALES], no_scales_p[j][1], offset_scale2_p);
|
||||
}
|
||||
|
||||
offset_scale1[MAX_NO_MODES][0] = 1;
|
||||
move32();
|
||||
offset_scale2[MAX_NO_MODES][0] = 1;
|
||||
move32();
|
||||
offset_scale1_p[MAX_NO_MODES_p][0] = 1;
|
||||
move32();
|
||||
offset_scale2_p[MAX_NO_MODES_p][0] = 1;
|
||||
move32();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static Word16
|
||||
decode_indexes_fx(
|
||||
Word16 * index, /* i: LSF vector index, written as array of Word16 because it generally uses more than 16 bits */
|
||||
Word16 no_bits, /* i: number of bits for the index */
|
||||
const Word16 * p_scales, /* i: scale values for the MSLVQ structures */
|
||||
Word16 * p_no_scales, /* i: number of truncations for each MSLVQ structure */
|
||||
Word32 * p_offset_scale1, /* i: scale index offset for first LSF subvector */
|
||||
Word32 * p_offset_scale2, /* i: scale index offset for second LSF subvector */
|
||||
Word16 * x_lvq, /* o: decoded LSF vector in Q1 */
|
||||
Word16 mode_glb, /* i: index of LSLVQ structure */
|
||||
Word16 * scales /* o: scale values for the decoded MSLVQ LSF codevector */
|
||||
)
|
||||
{
|
||||
Word32 index1=0, index2=0;
|
||||
Word16 len_scales = MAX_NO_SCALES*2, no_modes;
|
||||
Word16 i, im1, idx_scale;
|
||||
Word16 tmp;
|
||||
|
||||
no_modes = MAX_NO_SCALES+1;
|
||||
move16();
|
||||
|
||||
IF (sub(no_bits,shl(LEN_INDICE,1)) <= 0) /* the third short is not used */
|
||||
{
|
||||
index[2] = 0;
|
||||
move16();
|
||||
if ( sub(no_bits,LEN_INDICE) <= 0 )
|
||||
{
|
||||
index[1] =0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
/* safety check in case of bit errors */
|
||||
FOR( i = 0; i<3; i++ )
|
||||
{
|
||||
IF( index[i] < 0 )
|
||||
{
|
||||
set16_fx( x_lvq, 0, 2*LATTICE_DIM );
|
||||
scales[0] = 0;
|
||||
scales[1] = 0;
|
||||
index[i] = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* first subvector */
|
||||
tmp = i_mult2(mode_glb,no_modes);
|
||||
|
||||
IF ( p_offset_scale2[add(tmp, p_no_scales[add(shl(mode_glb,1),1)])] > 0 )
|
||||
{
|
||||
divide_64_32_fx( index, p_offset_scale2[tmp+ p_no_scales[add(shl(mode_glb,1),1)]], &index1, &index2 );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
index1 = L_deposit_l(index[0]); /* this is for very low bitrates, so there is no loss in truncation */
|
||||
index2 = L_deposit_l(0);
|
||||
}
|
||||
IF ( index1 == 0 )
|
||||
{
|
||||
FOR( i=0; i<LATTICE_DIM; i++ )
|
||||
{
|
||||
x_lvq[i] = 0;
|
||||
move16();
|
||||
}
|
||||
scales[0] = 0;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
IF( L_sub(index1, p_offset_scale1[mode_glb*no_modes+p_no_scales[mode_glb*2]]) >= 0 )
|
||||
{
|
||||
/* safety check in case of bit errors */
|
||||
set16_fx( x_lvq, 0, 2*LATTICE_DIM );
|
||||
scales[0] = 0;
|
||||
scales[1] = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* find idx_scale */
|
||||
i = 1;
|
||||
move16();
|
||||
WHILE( sub(i, p_no_scales[mode_glb*2]) <= 0 && L_sub(index1, p_offset_scale1[mode_glb*no_modes +i])>= 0 )
|
||||
{
|
||||
i = add(i,1);
|
||||
}
|
||||
idx_scale = sub(i,1);
|
||||
move16();
|
||||
index1 = L_sub(index1, p_offset_scale1[tmp+idx_scale]);
|
||||
|
||||
/* find idx_leader */
|
||||
i = 1;
|
||||
move16();
|
||||
|
||||
WHILE( L_sub(index1, table_no_cv_fx[i]) >= 0 )
|
||||
{
|
||||
i = add(i, 1);
|
||||
}
|
||||
im1 = sub(i,1);
|
||||
decode_comb_fx(L_sub(index1,table_no_cv_fx[im1]), x_lvq, im1 );
|
||||
scales[0] = p_scales[mode_glb*len_scales+idx_scale];
|
||||
}
|
||||
|
||||
/* second subvector */
|
||||
IF ( index2 == 0 )
|
||||
{
|
||||
FOR( i=LATTICE_DIM; i<2*LATTICE_DIM; i++ )
|
||||
{
|
||||
x_lvq[i] = 0;
|
||||
move16();
|
||||
}
|
||||
scales[1] = 0;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* find the index for the scale/truncation */
|
||||
i = 1;
|
||||
move16();
|
||||
WHILE( L_sub(index2, p_offset_scale2[tmp+i]) >= 0 )
|
||||
{
|
||||
i = add(i, 1);
|
||||
}
|
||||
|
||||
idx_scale = sub(i,1);
|
||||
index2 = L_sub(index2, p_offset_scale2[add(tmp,idx_scale)]);
|
||||
/* find the index of the leader vector */
|
||||
i = 1;
|
||||
move16();
|
||||
WHILE ( L_sub(index2, table_no_cv_fx[i]) >= 0 )
|
||||
{
|
||||
i = add(i, 1);
|
||||
}
|
||||
im1 = sub(i,1);
|
||||
decode_comb_fx( index2-table_no_cv_fx[im1], &x_lvq[LATTICE_DIM], im1 );
|
||||
scales[1] = p_scales[add(i_mult2(mode_glb,len_scales),add(MAX_NO_SCALES,idx_scale))];
|
||||
move16();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Word16 deindex_lvq_fx(
|
||||
Word16 *index, /* i : index to be decoded, as an array of 3 Word16 */
|
||||
Word16 *x_lvq, /* o : decoded codevector Q(x2.56) */
|
||||
Word16 mode, /* i : LVQ coding mode/MSLVQ structure index (select scales & no_lead ), or idx_cv for CNG case */
|
||||
Word16 sf_flag, /* i : safety net flag */
|
||||
Word16 no_bits, /* i : number of bits for lattice */
|
||||
Word32 *p_offset_scale1, /* i : offset for first subvector */
|
||||
Word32 *p_offset_scale2, /* i : offset for the second subvector */
|
||||
Word16 *p_no_scales /* i : number of scales for each truncation and each MSLVQ structure */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
const Word16 * p_scales;
|
||||
Word16 mode_glb;
|
||||
Word32 L_tmp;
|
||||
Word16 scales[2];
|
||||
Word16 ber_flag;
|
||||
|
||||
IF ( sub(sf_flag,1) == 0 )
|
||||
{
|
||||
mode_glb = add(offset_lvq_modes_SN_fx[mode], offset_in_lvq_mode_SN_fx[mode][sub(no_bits,min_lat_bits_SN_fx[mode])]);
|
||||
p_scales = &scales_fx[0][0];
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
mode_glb = add(offset_lvq_modes_pred_fx[mode], offset_in_lvq_mode_pred_fx[mode][sub(no_bits,min_lat_bits_pred_fx[mode])]);
|
||||
p_scales = &scales_p_fx[0][0];
|
||||
move16();
|
||||
}
|
||||
|
||||
/* decode the lattice index into the lattice codevectors for the two subvectors */
|
||||
ber_flag =
|
||||
decode_indexes_fx( index, no_bits, p_scales, p_no_scales, p_offset_scale1,
|
||||
p_offset_scale2, x_lvq, mode_glb, scales ); /* x_lvq is here Q1 */
|
||||
|
||||
|
||||
IF ( sub(sf_flag,1) == 0 )
|
||||
{
|
||||
/* safety-net case*/
|
||||
IF(scales[0])
|
||||
{
|
||||
FOR( i=0; i<LATTICE_DIM; i++ )
|
||||
{
|
||||
L_tmp = L_mult(x_lvq[i],scales[0]); /* Q1+Q11+Q1 = Q13 */
|
||||
/* Increase calculation accuracy by shifting more to the left and using rounding instead of truncation*/
|
||||
L_tmp = L_shl(Mult_32_16(L_tmp, shl(sigma_MSLVQ_fx[mode][i], 3)), 15); /* Q13 + Q2 +x2.56 -Q15 */
|
||||
x_lvq[i]= round_fx(L_tmp);
|
||||
}
|
||||
}
|
||||
IF (scales[1])
|
||||
{
|
||||
FOR( i=LATTICE_DIM; i<2*LATTICE_DIM; i++ )
|
||||
{
|
||||
L_tmp = L_mult(x_lvq[i],scales[1]); /* Q1+Q11+Q1 = Q13 */
|
||||
L_tmp = L_shl(Mult_32_16(L_tmp, shl(sigma_MSLVQ_fx[mode][i], 3)), 15); /* Q13 + Q2 +x2.56 -Q15 */
|
||||
x_lvq[i]= round_fx(L_tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* predictive mode AR or MA */
|
||||
IF(scales[0])
|
||||
{
|
||||
FOR( i=0; i<LATTICE_DIM; i++ )
|
||||
{
|
||||
L_tmp = L_mult(x_lvq[i],scales[0]); /* Q1+Q11+Q1 = Q13 */
|
||||
L_tmp = L_shl(Mult_32_16(L_tmp,shl(sigma_p_fx[mode][i],3)),15); /* Q13 + Q2 +x2.56 -Q15 */
|
||||
x_lvq[i]= round_fx(L_tmp);
|
||||
|
||||
}
|
||||
}
|
||||
IF (scales[1])
|
||||
{
|
||||
FOR( i=LATTICE_DIM; i<2*LATTICE_DIM; i++ )
|
||||
{
|
||||
L_tmp = L_mult(x_lvq[i],scales[1]); /* Q1+Q11+Q1 = Q13 */
|
||||
L_tmp = L_shl(Mult_32_16(L_tmp,shl(sigma_p_fx[mode][i],3)),15); /* Q13 + Q2 +x2.56 -Q15 */
|
||||
x_lvq[i]= round_fx(L_tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ber_flag;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------*
|
||||
* deindex_lvq_cng()
|
||||
* Note:
|
||||
* The sampling frequency for the LVQ CNG decoder frame can be determined by checking the fully decoded
|
||||
* value of the highest order LSF coefficient. Thus sampling rate information, nor extra codebooks are
|
||||
* not needed for deindex_lvq_cng(), since it is embedded inside the LSF codebooks.
|
||||
*----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
Word16 deindex_lvq_cng_fx(
|
||||
Word16 *index, /* i: index to be decoded, as an array of 3 short */
|
||||
Word16 *x_lvq, /* o: decoded codevector Q9 */
|
||||
Word16 idx_cv, /* i: relative mode_lvq, wrt START_CNG */
|
||||
Word16 no_bits, /* i: number of bits for lattice */
|
||||
Word32 * p_offset_scale1, /* i: scale index offset for first LSF subvector */
|
||||
Word32 * p_offset_scale2, /* i: scale index offset for second LSF subvector */
|
||||
Word16 * p_no_scales /* i: number of scales for each MSLVQ structure and each subvector */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 L_tmp;
|
||||
const Word16 *p_scales;
|
||||
Word16 mode_glb, mode;
|
||||
Word16 scales[2];
|
||||
Word16 ber_flag;
|
||||
|
||||
/* the MSLVQ structure in the second LP-CNG stage depends on the index from the first stage */
|
||||
mode_glb = add(START_CNG, idx_cv);
|
||||
mode = add(LVQ_COD_MODES, idx_cv);
|
||||
|
||||
p_scales = &scales_fx[0][0];
|
||||
move16();
|
||||
ber_flag =
|
||||
decode_indexes_fx( index, no_bits, p_scales, p_no_scales, p_offset_scale1, p_offset_scale2, x_lvq, mode_glb ,scales);
|
||||
|
||||
FOR(i=0; i<LATTICE_DIM; i++)
|
||||
{
|
||||
L_tmp = L_mult(x_lvq[i],scales[0]); /* Q1+Q11+Q1 = Q13 */
|
||||
L_tmp = L_shl(Mult_32_16(L_tmp, shl(sigma_MSLVQ_fx[mode][i], 3)), 15); /* Q13 + Q2 +x2.56 -Q15 */
|
||||
x_lvq[i]= round_fx(L_tmp);
|
||||
}
|
||||
FOR(i=LATTICE_DIM; i<2*LATTICE_DIM; i++)
|
||||
{
|
||||
L_tmp = L_mult(x_lvq[i],scales[1]); /* Q1+Q11+Q1 = Q13 */
|
||||
L_tmp = L_shl(Mult_32_16(L_tmp, shl(sigma_MSLVQ_fx[mode][i], 3)), 15); /* Q13 + Q2 +x2.56 -Q15 */
|
||||
x_lvq[i]= round_fx(L_tmp);
|
||||
}
|
||||
|
||||
/* check if permutting needed */
|
||||
IF ( cng_sort_fx[idx_cv] )
|
||||
{
|
||||
permute_fx( x_lvq, perm_MSLVQ_fx[idx_cv] );
|
||||
}
|
||||
|
||||
return ber_flag;
|
||||
}
|
||||
|
||||
|
||||
/* combinatorial indexing */
|
||||
static void idx2c_fx(
|
||||
Word16 n, /* i : total number of positions (components)*/
|
||||
Word16 *p, /* o : array with positions of the k components */
|
||||
Word16 k, /* i : number of components whose position is to be determined */
|
||||
Word16 val /* i : index to be decoded */
|
||||
)
|
||||
{
|
||||
Word16 i, skip, pos, k1;
|
||||
|
||||
skip = 0;
|
||||
move16();
|
||||
pos = 0;
|
||||
move16();
|
||||
k1 = sub(k,1);
|
||||
move16();
|
||||
WHILE( sub(add(skip, sub(C_VQ_fx[n-pos-1][k1] ,1)), val) < 0 )
|
||||
{
|
||||
skip = add(skip, C_VQ_fx[n-pos-1][k1]);
|
||||
move16();
|
||||
pos++;
|
||||
move16();
|
||||
}
|
||||
|
||||
p[0] = pos;
|
||||
move16();
|
||||
n = sub(n,add(pos,1));
|
||||
val = sub(val,skip);
|
||||
IF ( sub(k, 1) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
idx2c_fx( n, p+1, k1, val );
|
||||
|
||||
/* pos+1 */
|
||||
FOR( i=1; i<k; i++ )
|
||||
{
|
||||
p[i] = add(p[i], add(pos,1));
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/* combinatorial deindexing */
|
||||
static void decode_comb_fx(
|
||||
Word32 index, /* i : index to be decoded */
|
||||
Word16 *cv, /* o : decoded codevector Q1*/
|
||||
Word16 idx_lead /* i : leader class index */
|
||||
)
|
||||
{
|
||||
Word16 idx_sign;
|
||||
|
||||
idx_sign = extract_l(div_l(L_shl(index,1), pi0_fx[idx_lead])); /*(index/pi0_fx[idx_lead]); */
|
||||
index = L_sub(index, L_mult0(idx_sign, pi0_fx[idx_lead]));
|
||||
decode_leaders_fx(extract_l(index), idx_lead, cv);
|
||||
decode_sign_pc1_fx(cv, idx_sign, pl_par_fx[idx_lead]);
|
||||
|
||||
return;
|
||||
}
|
||||
void decode_sign_pc1_fx(
|
||||
Word16 *c, /* o : decoded codevector Q1*/
|
||||
Word16 idx_sign, /* i : sign index */
|
||||
Word16 parity /* i : parity flag (+1/-1/0) */
|
||||
)
|
||||
{
|
||||
Word16 i, len = LATTICE_DIM, cnt_neg = 1;
|
||||
|
||||
if ( parity )
|
||||
{
|
||||
len = sub(len,1);
|
||||
}
|
||||
|
||||
FOR( i=0; i<len; i++ )
|
||||
{
|
||||
IF (c[i] > 0)
|
||||
{
|
||||
/*if (idx_sign % 2) */
|
||||
IF(s_and(idx_sign,1))
|
||||
{
|
||||
c[i] = negate(c[i]);
|
||||
move16();
|
||||
cnt_neg = negate(cnt_neg);
|
||||
move16();
|
||||
}
|
||||
idx_sign = shr(idx_sign,1); /* >>= 1; */
|
||||
}
|
||||
}
|
||||
|
||||
IF ( sub(len, LATTICE_DIM)<0 )
|
||||
{
|
||||
IF (sub(cnt_neg, parity) != 0)
|
||||
{
|
||||
c[len] = negate(c[len]);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* multiply32_32_64_fx()
|
||||
*
|
||||
* (function for int64 )
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
void multiply32_32_64_fx(
|
||||
Word32 x, /* i: first factor */
|
||||
Word32 y, /* i: second factor */
|
||||
Word32 *res /* o: multiplication result as array of 2 Word32*/
|
||||
)
|
||||
{
|
||||
Word32 tmp, high;
|
||||
Word16 x_tmp[2], y_tmp[2];
|
||||
|
||||
x_tmp[0] = extract_l(L_and(x, 0x7fff)); /*extract_l(x); */ /* lowest 16 bits */
|
||||
x_tmp[1] = extract_l(L_and(L_shr(x,15),0x7fff)); /*extract_h(x); */
|
||||
y_tmp[0] = extract_l(L_and(y, 0x7fff)); /*extract_l(y); */
|
||||
y_tmp[1] = extract_l(L_and(L_shr(y,15),0x7fff)); /*extract_h(y); */
|
||||
tmp = L_mult0(x_tmp[0], y_tmp[0]);
|
||||
high = L_shr(tmp,15); /*extract_h(tmp); */
|
||||
res[0] = L_and(tmp, 0x7fff); /* extract_l(tmp); */
|
||||
tmp = L_mac0(L_mac0(high, x_tmp[1], y_tmp[0]), x_tmp[0],y_tmp[1]); /* x and y are not using all 32 bits, so this is valid */
|
||||
high = L_shr(tmp,15);/*extract_h(tmp); */
|
||||
res[0] = L_add(res[0], L_shl(L_and(tmp,0x7fff), 15));
|
||||
move32();
|
||||
res[1] = L_mac0(high, x_tmp[1], y_tmp[1]);
|
||||
move32();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void decode_leaders_fx(
|
||||
Word16 index, /* i : index to be decoded */
|
||||
Word16 idx_lead, /* i : leader class index */
|
||||
Word16 *cv /* o : decoded codevector Q1*/
|
||||
)
|
||||
{
|
||||
Word16 i, no_vals_loc, no_vals_last, p[LATTICE_DIM], dim_loc, n_crt;
|
||||
Word16 index1;
|
||||
Word16 val_crt;
|
||||
|
||||
no_vals_loc = no_vals_fx[idx_lead];
|
||||
move16();
|
||||
val_crt = vals_fx[idx_lead][no_vals_loc-1];
|
||||
move16(); /*Q1 */
|
||||
no_vals_last = no_vals_ind_fx[idx_lead][no_vals_loc-1];
|
||||
move16();
|
||||
|
||||
FOR( i=0; i<no_vals_last; i++ )
|
||||
{
|
||||
cv[i] = val_crt;
|
||||
move16(); /*Q1 */
|
||||
}
|
||||
|
||||
val_crt = 1;
|
||||
move16();
|
||||
dim_loc = no_vals_last;
|
||||
move16();
|
||||
|
||||
SWITCH ( no_vals_loc )
|
||||
{
|
||||
case 1:
|
||||
BREAK;
|
||||
case 2:
|
||||
idx2c_fx(LATTICE_DIM, p, no_vals_ind_fx[idx_lead][0], index);
|
||||
put_value_fx(cv, p, vals_fx[idx_lead][0], no_vals_last, no_vals_ind_fx[idx_lead][0]);
|
||||
BREAK;
|
||||
case 4:
|
||||
dim_loc = add(dim_loc,no_vals_ind_fx[idx_lead][2]);
|
||||
n_crt = no_vals_ind_fx[idx_lead][2];
|
||||
index1 = divide_16_16_fx(index, C_VQ_fx[dim_loc][n_crt], &index); /* index1 = index/C_VQ_fx[dim_loc][n_crt]; */
|
||||
/*index = sub(index, i_mult2(index1, C_VQ_fx[dim_loc][n_crt]) ); */ /* index-= index1*C_VQ_fx[dim_loc][n_crt]; */ move16();
|
||||
idx2c_fx(dim_loc, p, n_crt, index);
|
||||
put_value_fx(cv, p, vals_fx[idx_lead][2], no_vals_last, no_vals_ind_fx[idx_lead][2]); /* Q1 */
|
||||
index = index1;
|
||||
move16();
|
||||
/* no break */
|
||||
case 3:
|
||||
dim_loc = add(dim_loc, no_vals_ind_fx[idx_lead][1]);
|
||||
n_crt = no_vals_ind_fx[idx_lead][1];
|
||||
move16();
|
||||
index1 = divide_16_16_fx(index, C_VQ_fx[dim_loc][n_crt], &index);
|
||||
/*index = sub(index, i_mult2(index1, C_VQ_fx[dim_loc][n_crt]));move16(); */
|
||||
idx2c_fx(dim_loc, p, n_crt, index);
|
||||
put_value_fx(cv, p, vals_fx[idx_lead][1], sub(dim_loc, n_crt), n_crt);
|
||||
idx2c_fx(LATTICE_DIM, p, no_vals_ind_fx[idx_lead][0], index1);
|
||||
move16();
|
||||
put_value_fx(cv, p, vals_fx[idx_lead][0], dim_loc, no_vals_ind_fx[idx_lead][0]);
|
||||
BREAK;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* divide_32_32_fx() :Division reminder - rem is the reminder of the division between y and x. */
|
||||
static Word32 divide_32_32_fx(Word32 y, /* i */
|
||||
Word32 x, /* i */
|
||||
Word32 *rem /* o */
|
||||
)
|
||||
{
|
||||
Word32 result, t, L_tmp;
|
||||
Word16 i, ny, nx, nyx;
|
||||
|
||||
|
||||
IF (L_sub(y, x) < 0)
|
||||
{
|
||||
result = L_deposit_l(0);
|
||||
*rem = y;
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
|
||||
result = L_deposit_l(0);
|
||||
IF (y==0)
|
||||
{
|
||||
ny = 0;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
ny = sub(31, norm_l(y));
|
||||
}
|
||||
IF (x==0)
|
||||
{
|
||||
nx = 0;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
nx = sub(31, norm_l(x));
|
||||
}
|
||||
|
||||
nyx = sub(ny,nx);
|
||||
|
||||
/*t = L_and(L_shr(y, add(nyx,1)),sub(shl(1,sub(nx,1)),1)); */
|
||||
t = L_shr(y,add(nyx,1));
|
||||
FOR(i=0; i<=nyx; i++)
|
||||
{
|
||||
t = L_add(L_shl(t,1), L_and(L_shr(y,sub(nyx,i)),1)); /* L_and(y,L_shl(1, sub(nyx,i)))); */
|
||||
result = L_shl(result,1);
|
||||
L_tmp = L_sub(t,x);
|
||||
IF(L_tmp >= 0)
|
||||
{
|
||||
result = L_add(result,1);
|
||||
t = L_add(L_tmp, 0);
|
||||
}
|
||||
}
|
||||
*rem = t;
|
||||
move32();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* divide_32_32_fx() :Division reminder for Word16 - rem is the reminder of the division between y and x. */
|
||||
static Word16 divide_16_16_fx(Word16 y, /* i */
|
||||
Word16 x, /* i */
|
||||
Word16 *rem /* o */
|
||||
)
|
||||
{
|
||||
Word16 result, t, tmp;
|
||||
Word16 i, ny, nx, nyx;
|
||||
|
||||
|
||||
IF (L_sub(y, x) < 0)
|
||||
{
|
||||
result = 0;
|
||||
move16();
|
||||
*rem = y;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
|
||||
result = 0;
|
||||
move16();
|
||||
IF (y==0)
|
||||
{
|
||||
ny = 0;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
ny = sub(15, norm_s(y));
|
||||
}
|
||||
IF (x==0)
|
||||
{
|
||||
nx = 0;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
nx = sub(15, norm_s(x));
|
||||
}
|
||||
|
||||
nyx = sub(ny,nx);
|
||||
|
||||
t = s_and(shr(y, add(nyx,1)),sub(shl(1,sub(nx,1)),1));
|
||||
FOR(i=0; i<=nyx; i++)
|
||||
{
|
||||
t = add(shl(t,1), s_and(shr(y,sub(nyx,i)),1)); /* L_and(y,L_shl(1, sub(nyx,i)))); */
|
||||
result = shl(result,1);
|
||||
tmp = sub(t,x);
|
||||
IF(tmp >= 0)
|
||||
{
|
||||
result = add(result,1);
|
||||
t = tmp;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
*rem = t;
|
||||
move16();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void divide_64_32_fx(
|
||||
Word16 *xs, /* i : denominator as array of two int32 */
|
||||
Word32 y, /* i : nominator on 32 bits */
|
||||
Word32 *result, /* o : integer division result on 32 bits */
|
||||
Word32 *rem /* o : integer division reminder on 32 bits */
|
||||
)
|
||||
{
|
||||
Word16 nb_x1;
|
||||
Word32 r, x_tmp, x[2], q, q1;
|
||||
|
||||
x[0] = L_add(L_add(L_shl(L_deposit_l(s_and(xs[2],1)),2*LEN_INDICE),L_shl(L_deposit_l(xs[1]), LEN_INDICE)),L_deposit_l(xs[0]));
|
||||
move32();
|
||||
x[1] = L_shr(L_deposit_l(xs[2]),1);
|
||||
move32();
|
||||
|
||||
/*x[0] = (((xs[2])&(1)<<(LEN_INDICE*2)) + (xs[1]<<LEN_INDICE) + xs[0];
|
||||
x[1] = xs[2]>>1; */
|
||||
|
||||
IF (x[1] ==0)
|
||||
{
|
||||
nb_x1 = 0;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
nb_x1 = sub(31, norm_l(x[1])); /*get_no_bits_fx(x[1]); */
|
||||
}
|
||||
/* take the first 31 bits */
|
||||
IF ( nb_x1 > 0 )
|
||||
{
|
||||
x_tmp = L_add(L_shl(x[1],sub(31,nb_x1)),L_shr(x[0], nb_x1));
|
||||
/* x_tmp = (x[1]<<(32-nb_x1)) + (x[0]>>nb_x1); */
|
||||
|
||||
q = divide_32_32_fx(x_tmp,y, &r); /* q = x_tmp/y, reminder r */
|
||||
r = L_add(L_shl(r, nb_x1), L_and(x[0],L_deposit_l(sub(shl(1,nb_x1),1)))); /* this is the first reminder */
|
||||
/* r = (r<<nb_x1)+(x[0]&((1<<nb_x1) - 1)); */
|
||||
|
||||
q1 = divide_32_32_fx(r, y, rem);
|
||||
*result = L_add(L_shl(q,nb_x1), q1);
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
*result = divide_32_32_fx(x[0], y, rem);
|
||||
move32();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void put_value_fx(
|
||||
Word16 *cv, /* i/o : input codevector Q1*/
|
||||
Word16 *p, /* i : array with positions */
|
||||
Word16 val, /* i : value to be inserted Q1*/
|
||||
Word16 dim, /* i : vector dimension */
|
||||
Word16 no_new_val /* i : number of values to be inserted */
|
||||
)
|
||||
{
|
||||
Word16 cv_out[LATTICE_DIM];
|
||||
Word16 i, occ[LATTICE_DIM], cnt, limit;
|
||||
|
||||
limit = add(dim, no_new_val);
|
||||
FOR( i=0; i<limit; i++ )
|
||||
{
|
||||
occ[i] = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR( i=0; i<no_new_val; i++ )
|
||||
{
|
||||
cv_out[p[i]] = val;
|
||||
move16();
|
||||
occ[p[i]] = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
cnt = 0;
|
||||
move16();
|
||||
FOR( i=0; i<limit; i++ )
|
||||
{
|
||||
if (occ[i] == 0)
|
||||
{
|
||||
cv_out[i] = cv[cnt++];
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
FOR( i=0; i<limit; i++ )
|
||||
{
|
||||
cv[i] = cv_out[i];
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+218
@@ -0,0 +1,218 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "rom_com_fx.h"
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
/*===================================================================*/
|
||||
/* FUNCTION : dequantize_uvg_fx() */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* PURPOSE : This function returns the quantized gain
|
||||
vector given the indices in the gain
|
||||
quantization tables */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16) iG1 : index into UVG1CB_fx table (Q0) */
|
||||
/* _ (Word16*) iG2 : indices into UVG2CB_fx (Q0) */
|
||||
/* - (Word32) Fs : output sampling rate */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*) G : Output quantized gain vector */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ None. */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None. */
|
||||
/*===================================================================*/
|
||||
Word16 dequantize_uvg_fx(
|
||||
Word16 iG1,
|
||||
Word16 *iG2,
|
||||
Word16 *G,
|
||||
Word16 bwidth_fx
|
||||
,Word16 do_scale
|
||||
)
|
||||
{
|
||||
Word16 i, k;
|
||||
const Word16 (*UVG1CB)[2]=NULL;
|
||||
const Word16 (*UVG2CB1)[5]=NULL;
|
||||
const Word16 (*UVG2CB2)[5]=NULL;
|
||||
Word16 frac, exp, sc;
|
||||
Word32 L_tmp;
|
||||
Word16 Q_gain = 0;
|
||||
|
||||
IF( sub(bwidth_fx,NB) == 0 )
|
||||
{
|
||||
UVG1CB = UVG1CB_NB_FX;
|
||||
move16();
|
||||
UVG2CB1 = UVG2CB1_NB_FX;
|
||||
move16();
|
||||
UVG2CB2 = UVG2CB2_NB_FX;
|
||||
move16();
|
||||
}
|
||||
ELSE IF( sub(bwidth_fx,WB) == 0 || sub(bwidth_fx,SWB) == 0)
|
||||
{
|
||||
test();
|
||||
UVG1CB = UVG1CB_WB_FX;
|
||||
move16();
|
||||
UVG2CB1 = UVG2CB1_WB_FX;
|
||||
move16();
|
||||
UVG2CB2 = UVG2CB2_WB_FX;
|
||||
move16();
|
||||
}
|
||||
|
||||
IF ( !do_scale)
|
||||
{
|
||||
sc = 11;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
test();
|
||||
IF ( ( sub(UVG1CB[iG1][0], 4096) < 0 ) && ( sub(UVG1CB[iG1][1],4096) < 0 ) ) /* if x < 1, where 10^x is used for gain computation */
|
||||
{
|
||||
sc = 8;
|
||||
move16();
|
||||
Q_gain = 3;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
sc = 11;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
FOR (i=0; i<2; i++)
|
||||
{
|
||||
FOR (k=0; k<5; k++)
|
||||
{
|
||||
IF( i==0 )
|
||||
{
|
||||
/* pow(10.0, UVG1CB[iG1][i]) = pow(2.0,UVG1CB[iG1][i]*3.321928 */
|
||||
L_tmp = L_mult(UVG1CB[iG1][i],27213); /* Q(13+13+1)->Q27 */
|
||||
L_tmp = L_shr_r(L_tmp,11); /* Q16 */
|
||||
frac = L_Extract_lc(L_tmp,&exp);
|
||||
frac = extract_l(Pow2(14,frac));
|
||||
G[i*5+k] = round_fx(L_shl(L_mult(frac,UVG2CB1[iG2[i]][k]),exp-sc)); /* Q0 */
|
||||
}
|
||||
ELSE IF (sub(i,1)==0)
|
||||
{
|
||||
L_tmp = L_mult(UVG1CB[iG1][i],27213); /* Q(13+13+1)->Q27 */
|
||||
L_tmp = L_shr_r(L_tmp,11); /* Q16 */
|
||||
frac = L_Extract_lc(L_tmp,&exp);
|
||||
frac = extract_l(Pow2(14,frac));
|
||||
G[i*5+k] = round_fx(L_shl(L_mult(frac,UVG2CB2[iG2[i]][k]),exp-sc)); /* Q0 */
|
||||
}
|
||||
}
|
||||
}
|
||||
return Q_gain;
|
||||
}
|
||||
|
||||
/*===================================================================*/
|
||||
/* FUNCTION : generate_nelp_excitation_fx */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* PURPOSE : This function computes the random
|
||||
excitation scaled by gain */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
|
||||
/* _ (Word16*) Gains : Gain vector (Q_exc) */
|
||||
/* _ (Word16) gain_fac : gain factor (Q14) */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*) seed : Random seed (Q0) */
|
||||
/* _ (Word16*) output : excitation output (Q_exc) */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ None. */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None. */
|
||||
/*===================================================================*/
|
||||
void generate_nelp_excitation_fx(
|
||||
Word16 *seed, /* i/o: random number seed */
|
||||
Word16 *Gains, /* i : excitation gains Q_exc*/
|
||||
Word16 *output, /* o : excitation output */
|
||||
Word16 gain_fac /* i : gain factor */
|
||||
)
|
||||
{
|
||||
Word16 i, len, j;
|
||||
Word16 tmp[31], tmp1[31], tmpf, L16;
|
||||
Word16 k1, k2, I[31], tmpi;
|
||||
Word32 L32;
|
||||
Word16 cnt;
|
||||
|
||||
FOR (i=0; i<10; i++)
|
||||
{
|
||||
IF (sub(i,9)==0)
|
||||
{
|
||||
len=31;
|
||||
move16();
|
||||
cnt=8;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
len=25;
|
||||
move16();
|
||||
cnt=6;
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (j=0; j<len; j++)
|
||||
{
|
||||
L32 = L_mult0(*seed,0x0209); /* L32 = *seed*521; */
|
||||
|
||||
L16 = extract_l(L_add(L32,259));
|
||||
*seed = L16;
|
||||
move16(); /* Q0 */
|
||||
tmp[j] = *seed;
|
||||
move16(); /* Q15, tmp[j]=*seed/32768 */
|
||||
|
||||
tmp1[j] = abs_s(tmp[j]);
|
||||
I[j] = j;
|
||||
move16();
|
||||
}
|
||||
|
||||
j = sub(len,1);
|
||||
FOR (k1=0; k1<j; k1++)
|
||||
{
|
||||
FOR (k2=add(k1,1); k2<len; k2++)
|
||||
{
|
||||
IF (sub(tmp1[k2],tmp1[k1])>0)
|
||||
{
|
||||
tmpi = I[k2];
|
||||
move16();
|
||||
tmpf = tmp1[k2];
|
||||
move16();
|
||||
tmp1[k2] = tmp1[k1];
|
||||
move16();
|
||||
I[k2] = I[k1];
|
||||
move16();
|
||||
tmp1[k1] = tmpf;
|
||||
move16();
|
||||
I[k1] = tmpi;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*using a factor of 1.37 to compensate for the ~ 2.5 ( or 2.73) dB diff between this scheme and EVS-UV */
|
||||
FOR (j=0; j<cnt; j++)
|
||||
{
|
||||
L16 = mult_r(tmp[I[j]], gain_fac); /* Q14 */
|
||||
L16 = mult_r(L16, 0x6EDA); /* Q13 */
|
||||
|
||||
output[i*25+I[j]]= round_fx(L_shl(L_mult(L16,Gains[i]),2)); /* Q_exc */
|
||||
}
|
||||
FOR (; j<len; j++)
|
||||
{
|
||||
output[i*25+I[j]] = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef OPTIONS_H
|
||||
#define OPTIONS_H
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
/* ################### Start compiler switches ######################## */
|
||||
/* */
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4310) /* cast truncates constant value this affects mainly constants tables*/
|
||||
#endif
|
||||
|
||||
#define SUPPORT_JBM_TRACEFILE /* support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */
|
||||
|
||||
/* */
|
||||
/* ##################### End compiler switches ######################## */
|
||||
|
||||
#endif /* OPTIONS_H */
|
||||
+276
@@ -0,0 +1,276 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include "stl.h"
|
||||
#include <assert.h>
|
||||
#include "prot_fx.h"
|
||||
|
||||
/********************************/
|
||||
/* Helper functions */
|
||||
/********************************/
|
||||
|
||||
/** Put nBits long encoded value from *pStream into bitstream. Using the function EncodeValue for encoding. */
|
||||
static Word16 PutIntoBitstream(Word16 const ** pStream, TEncodeValue EncodeValue, Word16 index, Encoder_State_fx *st_fx, Word16 nBits)
|
||||
{
|
||||
Word16 value;
|
||||
Word16 codedValue;
|
||||
|
||||
move16();
|
||||
value = *(*pStream)++;
|
||||
codedValue = EncodeValue(value, index);
|
||||
|
||||
push_next_indice_fx(st_fx, codedValue, nBits);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/** Get nBits long value from bitstream into *pStream. */
|
||||
static Word16 GetFromBitstream(Decoder_State_fx *st, TDecodeValue DecodeValue, Word16 index, Word16 nFixedBits, Word16 ** pStream)
|
||||
{
|
||||
Word16 value;
|
||||
|
||||
move16();
|
||||
move16();
|
||||
value = 0;
|
||||
|
||||
IF (DecodeValue != NULL)
|
||||
{
|
||||
DecodeValue(st, index, &value);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
value = get_next_indice_fx(st, nFixedBits);
|
||||
}
|
||||
move16();
|
||||
*(*pStream)++ = value;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static Word16 FixedWidthEncoding(Word16 value, Word16 index)
|
||||
{
|
||||
(void)index;
|
||||
return value;
|
||||
}
|
||||
|
||||
/********************************/
|
||||
/* Interface functions */
|
||||
/********************************/
|
||||
|
||||
void GetParameters(ParamsBitMap const * paramsBitMap, Word16 nArrayLength, void const * pParameter, Word16 ** pStream, Word16 * pnSize, Word16 * pnBits)
|
||||
{
|
||||
Word16 index;
|
||||
Word16 iParam, nParams;
|
||||
Word16 value;
|
||||
void const * pSubStruct;
|
||||
|
||||
|
||||
assert((paramsBitMap != NULL) && (nArrayLength > 0) && (pParameter != NULL) && (pStream != NULL) && (pnSize != NULL) && (pnBits != NULL));
|
||||
|
||||
move16();
|
||||
nParams = paramsBitMap->nParams;
|
||||
|
||||
FOR (index = 0; index < nArrayLength; index++)
|
||||
{
|
||||
|
||||
FOR (iParam = 0; iParam < nParams; iParam++)
|
||||
{
|
||||
ParamBitMap const * param;
|
||||
|
||||
move16();
|
||||
param = & paramsBitMap->params[iParam];
|
||||
|
||||
pSubStruct = param->GetParamValue(pParameter, index, &value);
|
||||
/* If a function for encoding/decoding value is defined than it should take care of 0 */
|
||||
IF ( s_or(param->fZeroAllowed != 0, param->EncodeValue != NULL) )
|
||||
{
|
||||
move16();
|
||||
*(*pStream)++ = value;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
move16();
|
||||
*(*pStream)++ = sub(value, 1);
|
||||
}
|
||||
|
||||
move16();
|
||||
*pnSize = add(*pnSize, 1);
|
||||
|
||||
IF (param->nBits != 0)
|
||||
{
|
||||
move16();
|
||||
*pnBits = add(*pnBits, param->nBits);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
move16();
|
||||
*pnBits = add(*pnBits, param->GetNumberOfBits(value, index));
|
||||
}
|
||||
|
||||
IF ( s_and(param->pSubParamBitMap != NULL, value > 0) )
|
||||
{
|
||||
const void *pointer;
|
||||
|
||||
move16();
|
||||
pointer = pParameter;
|
||||
if (pSubStruct != NULL)
|
||||
{
|
||||
move16();
|
||||
pointer = pSubStruct;
|
||||
}
|
||||
GetParameters(param->pSubParamBitMap, value, pointer, pStream, pnSize, pnBits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SetParameters(ParamsBitMap const * paramsBitMap, Word16 nArrayLength, void * pParameter, Word16 const ** pStream, Word16 * pnSize)
|
||||
{
|
||||
Word16 index;
|
||||
Word16 iParam, nParams;
|
||||
Word16 value;
|
||||
void * pSubStruct;
|
||||
void * pTmp;
|
||||
assert((paramsBitMap != NULL) && (nArrayLength > 0) && (pParameter != NULL) && (pStream != NULL) && (pnSize != NULL));
|
||||
nParams = paramsBitMap->nParams;
|
||||
|
||||
FOR (index = 0; index < nArrayLength; index++)
|
||||
{
|
||||
FOR (iParam = 0; iParam < nParams; iParam++)
|
||||
{
|
||||
ParamBitMap const *param;
|
||||
/* If a function for encoding/decoding value is defined than it should take care of 0 */
|
||||
|
||||
move16();
|
||||
param = ¶msBitMap->params[iParam];
|
||||
|
||||
move16();
|
||||
value = 1;
|
||||
if ( s_or(param->fZeroAllowed!=0, param->EncodeValue != NULL) )
|
||||
{
|
||||
move16();
|
||||
value = 0;
|
||||
}
|
||||
value = add(value, *(*pStream)++);
|
||||
|
||||
pSubStruct = param->SetParamValue(pParameter, index, value);
|
||||
move16();
|
||||
*pnSize = add(*pnSize, 1);
|
||||
|
||||
IF ( s_and(param->pSubParamBitMap != NULL, value > 0) )
|
||||
{
|
||||
pTmp = pParameter;
|
||||
if(pSubStruct != NULL) pTmp = pSubStruct;
|
||||
SetParameters(param->pSubParamBitMap, value, pTmp, pStream, pnSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void WriteToBitstream(ParamsBitMap const * paramsBitMap, Word16 nArrayLength, Word16 const ** pStream, Word16 * pnSize, Encoder_State_fx *st, Word16 * pnBits)
|
||||
{
|
||||
Word16 index;
|
||||
Word16 iParam, nParams;
|
||||
assert((paramsBitMap != NULL) && (nArrayLength > 0) && (pStream != NULL) && (pnSize != NULL) && (st != NULL) && (pnBits != NULL));
|
||||
nParams = paramsBitMap->nParams;
|
||||
|
||||
FOR (index = 0; index < nArrayLength; index++)
|
||||
{
|
||||
|
||||
FOR (iParam = 0; iParam < nParams; iParam++)
|
||||
{
|
||||
ParamBitMap const *param;
|
||||
Word16 nBits;
|
||||
/* If a function for encoding/decoding value is defined than it should take care of 0 */
|
||||
Word16 fShiftValue;
|
||||
TEncodeValue EncodeValue;
|
||||
Word16 value;
|
||||
|
||||
move16();
|
||||
param = ¶msBitMap->params[iParam];
|
||||
|
||||
move16();
|
||||
nBits = param->nBits;
|
||||
IF (param->nBits == 0)
|
||||
{
|
||||
nBits = param->GetNumberOfBits(**pStream, index);
|
||||
}
|
||||
|
||||
test();
|
||||
test();
|
||||
fShiftValue = s_and(param->fZeroAllowed==0, param->EncodeValue == NULL);
|
||||
move16();
|
||||
EncodeValue = param->EncodeValue;
|
||||
if (param->EncodeValue == NULL)
|
||||
{
|
||||
move16();
|
||||
EncodeValue = &FixedWidthEncoding;
|
||||
}
|
||||
value = PutIntoBitstream(pStream, EncodeValue, index, st, nBits);
|
||||
if (fShiftValue)
|
||||
{
|
||||
value = add(value, 1);
|
||||
}
|
||||
|
||||
move16();
|
||||
*pnSize = add(*pnSize, 1);
|
||||
move16();
|
||||
*pnBits = add(*pnBits, nBits);
|
||||
|
||||
IF ((param->pSubParamBitMap != NULL) && (value > 0))
|
||||
{
|
||||
WriteToBitstream(param->pSubParamBitMap, value, pStream, pnSize, st, pnBits);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReadFromBitstream(ParamsBitMap const * paramsBitMap, Word16 nArrayLength, Decoder_State_fx *st, Word16 ** pStream, Word16 * pnSize)
|
||||
{
|
||||
Word16 index;
|
||||
Word16 iParam, nParams;
|
||||
Word16 fShiftValue;
|
||||
Word16 value;
|
||||
assert((paramsBitMap != NULL) && (nArrayLength > 0) && (pStream != NULL) && (pnSize != NULL) && (st != NULL));
|
||||
move16();
|
||||
nParams = paramsBitMap->nParams;
|
||||
|
||||
FOR (index = 0; index < nArrayLength; index++)
|
||||
{
|
||||
|
||||
FOR (iParam = 0; iParam < nParams; iParam++)
|
||||
{
|
||||
ParamBitMap const * param;
|
||||
|
||||
|
||||
/* If a function for encoding/decoding value is defined than it should take care of 0 */
|
||||
move16();
|
||||
param = & paramsBitMap->params[iParam];
|
||||
|
||||
test();
|
||||
test();
|
||||
fShiftValue = s_and(param->fZeroAllowed==0, param->EncodeValue == NULL);
|
||||
value = GetFromBitstream(st, param->DecodeValue, index, param->nBits, pStream);
|
||||
if (fShiftValue)
|
||||
{
|
||||
move16();
|
||||
value = add(value, 1);
|
||||
}
|
||||
|
||||
IF ((param->pSubParamBitMap != NULL) && (value > 0))
|
||||
{
|
||||
|
||||
ReadFromBitstream(param->pSubParamBitMap, value, st, pStream, pnSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
move16();
|
||||
*pnSize = add(*pnSize, i_mult(nParams, nArrayLength));
|
||||
|
||||
}
|
||||
Executable
+177
@@ -0,0 +1,177 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include "options.h" /* EV-VBR compilation switches */
|
||||
#include "prot_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "stl.h" /* Weighted mops computation related code */
|
||||
|
||||
/*-----------------------------------------------------------------------*
|
||||
* phase_dispersion:
|
||||
*
|
||||
* post-processing to enhance noise at low bit rate.
|
||||
*-----------------------------------------------------------------------*/
|
||||
|
||||
void phase_dispersion(
|
||||
const Word32 gain_code, /* i : gain of code 15Q16 */
|
||||
const Word16 gain_pit, /* i : gain of pitch Q14 */
|
||||
Word16 code[], /* i/o: code vector */
|
||||
Word16 *code_exp, /* i/o: exponent of code */
|
||||
const Word16 mode, /* i : level, 0=hi, 1=lo, 2=off */
|
||||
Word32 *prev_gain_code, /* i/o: static memory 15Q16 */
|
||||
Word16 prev_gain_pit[], /* i/o: static memory Q14, size=6 */
|
||||
Word16 *prev_state, /* i/o: static memory Q0 */
|
||||
Word16 L_subfr /* i : subframe length [40,64,80]*/
|
||||
)
|
||||
{
|
||||
Word16 i, j, state, scale2;
|
||||
Word32 x32[2*L_SUBFR];
|
||||
Word16 *code_real, *code_imag;
|
||||
const Word16 *h_real, *h_imag;
|
||||
|
||||
|
||||
|
||||
move16();
|
||||
state = 2;
|
||||
|
||||
if ( sub(gain_pit,14746/*0.9f Q14*/) < 0)
|
||||
{
|
||||
move16();
|
||||
state = 1;
|
||||
}
|
||||
if ( sub(gain_pit, 9830/*0.6f Q14*/) < 0 )
|
||||
{
|
||||
move16();
|
||||
state = 0;
|
||||
}
|
||||
|
||||
FOR (i=5; i>0; i--)
|
||||
{
|
||||
move16();
|
||||
prev_gain_pit[i] = prev_gain_pit[i-1];
|
||||
}
|
||||
move16();
|
||||
prev_gain_pit[0] = gain_pit;
|
||||
|
||||
|
||||
IF ( L_sub(gain_code, L_add(*prev_gain_code, L_shl(*prev_gain_code,1))) > 0 )
|
||||
{
|
||||
if (sub(state,2) < 0)
|
||||
{
|
||||
state = add(state, 1);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
j=0;
|
||||
FOR (i=0; i<6; i++)
|
||||
{
|
||||
|
||||
if ( L_sub(prev_gain_pit[i], 9830/*0.6f Q14*/) < 0 )
|
||||
{
|
||||
j = add(j,1);
|
||||
}
|
||||
}
|
||||
|
||||
if (sub(j,2) > 0)
|
||||
{
|
||||
move16();
|
||||
state = 0;
|
||||
}
|
||||
|
||||
if ( sub(sub(state, *prev_state),1) > 0 )
|
||||
{
|
||||
state = sub(state,1);
|
||||
}
|
||||
}
|
||||
|
||||
move32();
|
||||
move16();
|
||||
*prev_gain_code = gain_code;
|
||||
*prev_state = state;
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* circular convolution
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
state = add(state, mode); /* level of dispersion */
|
||||
j = *code_exp;
|
||||
move16();
|
||||
IF( sub(state,2) < 0 )
|
||||
{
|
||||
FOR(i=0; i<L_subfr; i++)
|
||||
{
|
||||
x32[i] = L_deposit_h(code[i]);
|
||||
}
|
||||
|
||||
BASOP_rfft(x32, L_subfr, &j, -1);
|
||||
|
||||
/* Normalize output data. */
|
||||
scale2 = getScaleFactor32(x32, L_subfr);
|
||||
FOR (i=0; i<L_subfr/2-1; i++)
|
||||
{
|
||||
code[i] = round_fx(L_shl(x32[2*i+0], scale2));
|
||||
code[L_subfr-1-i] = round_fx(L_shl(x32[2*i+3], scale2));
|
||||
}
|
||||
|
||||
code[L_subfr/2-1] = round_fx(L_shl(x32[L_subfr-2], scale2));
|
||||
code[L_subfr/2] = round_fx(L_shl(x32[1], scale2));
|
||||
|
||||
j = sub(j, scale2);
|
||||
|
||||
h_real = low_H16k;
|
||||
move16();
|
||||
if( sub(L_subfr, 64) <= 0)
|
||||
{
|
||||
h_real = low_H;
|
||||
move16();
|
||||
}
|
||||
IF ( sub(state, 1) == 0)
|
||||
{
|
||||
h_real = mid_H16k;
|
||||
move16();
|
||||
if( sub(L_subfr, 64) <= 0)
|
||||
{
|
||||
h_real = mid_H;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
h_imag = h_real + L_subfr - 1;
|
||||
move16();
|
||||
|
||||
code_real = &code[0];
|
||||
code_imag = &code[L_subfr-1];
|
||||
|
||||
x32[0] = L_mult(*code_real++, *h_real++);
|
||||
move32();
|
||||
FOR (i=1; i<L_subfr/2; i++)
|
||||
{
|
||||
x32[2*i] = L_msu(L_mult(*code_real, *h_real) ,*code_imag, *h_imag);
|
||||
move32();
|
||||
x32[2*i+1] = L_mac(L_mult(*code_real++, *h_imag--),*code_imag--, *h_real++);
|
||||
move32();
|
||||
}
|
||||
x32[1] = L_mult(*code_real++, *h_real++);
|
||||
move32();
|
||||
|
||||
/* low_H and mid_H are in Q14 format, thus account that here. */
|
||||
j = add(j,1);
|
||||
|
||||
BASOP_rfft(x32, L_subfr, &j, 1);
|
||||
scale2 = getScaleFactor32(x32, L_subfr);
|
||||
FOR (i=0; i<L_subfr; i++)
|
||||
{
|
||||
code[i] = round_fx(L_shl(x32[i], scale2));
|
||||
}
|
||||
j = sub(j, scale2);
|
||||
}
|
||||
|
||||
/* Store exponent of code */
|
||||
move16();
|
||||
*code_exp = j;
|
||||
|
||||
}
|
||||
|
||||
Executable
+115
@@ -0,0 +1,115 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
|
||||
/*===================================================================*/
|
||||
/* FUNCTION : Interpol_delay_fx () */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* PURPOSE : Interpolate pitch lag for a subframe */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16) last_fx: previous frame delay, Q0 */
|
||||
/* _ (Word16) current_fx: current frame delay, Q0 */
|
||||
/* _ (Word16) SubNum : subframe number */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* */
|
||||
/* _ (Word16 []) out_fx : 3 Intepolated delays, Q4 */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : _ None. */
|
||||
/*===================================================================*/
|
||||
/* NOTE: this function uses a 5 entry table frac_fx (Q4 unsigned) */
|
||||
/*===================================================================*/
|
||||
|
||||
void Interpol_delay_fx(Word16 *out_fx, Word16 last_fx, Word16 current_fx,
|
||||
Word16 SubNum, const Word16* frac_fx)
|
||||
{
|
||||
Word16 i,temp;
|
||||
Word32 L_add1,L_add2;
|
||||
|
||||
FOR (i=0; i<3; i++)
|
||||
{
|
||||
temp= sub(16,frac_fx[SubNum+i]);/* Q4 */
|
||||
L_add1 = L_shr(L_mult(last_fx,temp),1);/* Q4 */
|
||||
L_add2 = L_shr(L_mult(current_fx,frac_fx[SubNum+i]),1);/* Q4 */
|
||||
out_fx[i] = (Word16)L_add(L_add1,L_add2);
|
||||
move16();/* Q4 */
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* deemph_lpc()
|
||||
*
|
||||
* De-emphasis of LP coefficients
|
||||
* convolve LPC with [1 -PREEMPH_FAC] to de-emphasise LPC
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
void deemph_lpc_fx(
|
||||
Word16 *p_Aq_curr_fx, /* i : LP coefficients current frame */
|
||||
Word16 *p_Aq_old_fx, /* i : LP coefficients previous frame */
|
||||
Word16 *LPC_de_curr_fx, /* o : De-emphasized LP coefficients current frame in Q12 */
|
||||
Word16 *LPC_de_old_fx, /* o : De-emphasized LP coefficients previous frame in Q12 */
|
||||
Word16 deemph_old
|
||||
|
||||
)
|
||||
{
|
||||
Word16 k,temp;
|
||||
Word16 b_fx[M+2];/* Q12 */
|
||||
Word16 a_fx[2] = {-22282, 32767};/* Q15 {-PREEMPH_FAC,1.0} */
|
||||
|
||||
b_fx[0] = 4096;
|
||||
move16();/* 1 in Q12 */
|
||||
FOR(k = 0; k < M; k++)
|
||||
{
|
||||
b_fx[k+1] = p_Aq_curr_fx[k];
|
||||
move16();/* Q12 */
|
||||
}
|
||||
b_fx[M+1] = 0;
|
||||
move16();
|
||||
|
||||
FOR(k = 0; k <= M; k++)
|
||||
{
|
||||
/* LPC_de_curr[k] = a[0]*b[k] + a[1]*b[k+1]; */
|
||||
temp = mult(a_fx[0],b_fx[k]);/* Q12 */
|
||||
LPC_de_curr_fx[k] = add(temp,b_fx[k+1]);
|
||||
move16();/* Q12 */
|
||||
}
|
||||
|
||||
IF ( sub( deemph_old, 1) == 0)
|
||||
{
|
||||
|
||||
/* ignoring the 1st value which is 1.0 in this case */
|
||||
b_fx[0] = 4096;
|
||||
move16();/* 1 in Q12 */
|
||||
FOR(k = 0; k < M; k++)
|
||||
{
|
||||
b_fx[k+1] = p_Aq_old_fx[k+1];
|
||||
move16();
|
||||
}
|
||||
b_fx[M+1] = 0;
|
||||
move16();
|
||||
|
||||
FOR(k = 0; k <= M; k++)
|
||||
{
|
||||
/* LPC_de_old[k] = a[0]*b[k] + a[1]*b[k+1]; */
|
||||
temp = mult(a_fx[0],b_fx[k]);/* Q12 */
|
||||
LPC_de_old_fx[k] = add(temp,b_fx[k+1]);
|
||||
move16();/* Q12 */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return; /* both outputs LPC_de_curr_fx and LPC_de_old_fx are in Q12 */
|
||||
}
|
||||
|
||||
|
||||
Executable
+162
@@ -0,0 +1,162 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Function pred_lt4: *
|
||||
* ~~~~~~~~~ *
|
||||
*-------------------------------------------------------------------*
|
||||
* Compute the result of long term prediction with fractional *
|
||||
* interpolation of resolution 1/4. *
|
||||
* *
|
||||
* On return exc[0..L_subfr-1] contains the interpolated signal *
|
||||
* (adaptive codebook excitation) *
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void pred_lt4(
|
||||
const Word16 excI[], /* in : excitation buffer */
|
||||
Word16 excO[], /* out: excitation buffer */
|
||||
Word16 T0, /* input : integer pitch lag */
|
||||
Word16 frac, /* input : fraction of lag */
|
||||
Word16 L_subfr, /* input : subframe size */
|
||||
const Word16 *win, /* i : interpolation window */
|
||||
const Word16 nb_coef, /* i : nb of filter coef */
|
||||
const Word16 up_sample /* i : up_sample */
|
||||
|
||||
)
|
||||
{
|
||||
Word16 i, j;
|
||||
Word32 s;
|
||||
const Word16 *x0, *x1, *x2, *c1, *c2;
|
||||
x0 = &excI[-T0];
|
||||
|
||||
|
||||
frac = negate(frac);
|
||||
|
||||
IF ( frac < 0 )
|
||||
{
|
||||
frac = add(frac,up_sample);
|
||||
x0--;
|
||||
}
|
||||
|
||||
FOR (j=0; j<L_subfr; j++)
|
||||
{
|
||||
x1 = x0++;
|
||||
x2 = x1+1;
|
||||
c1 = (&win[frac]);
|
||||
c2 = (&win[up_sample-frac]);
|
||||
|
||||
s = L_deposit_l(0);
|
||||
FOR(i=0; i<nb_coef; i++)
|
||||
{
|
||||
/*s += (*x1--) * (*c1) + (*x2++) * (*c2);*/
|
||||
s = L_mac0(s, (*x1--),(*c1));
|
||||
s = L_mac0(s, (*x2++),(*c2));
|
||||
|
||||
c1+=up_sample;
|
||||
c2+=up_sample;
|
||||
}
|
||||
#if (INTERP_EXP != -1)
|
||||
s = L_shl(s,INTERP_EXP+1);
|
||||
#endif
|
||||
|
||||
excO[j] = round_fx(s);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*======================================================================*/
|
||||
/* FUNCTION : pred_lt4_tc_fx() */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PURPOSE : * adapt. search of the second impulse in the same subframe (when appears) */
|
||||
/* On return, exc[0..L_subfr-1] contains the interpolated signal */
|
||||
/* (adaptive codebook excitation) */
|
||||
/* */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16 []) exc : excitation buffer Q0 */
|
||||
/* _ (Word16) L_subfr : subframe size Q0 */
|
||||
/* _ (Word16 ) T0 : integer pitch lag Q0 */
|
||||
/* _ (Word16 ) frac : fraction of lag Q0 */
|
||||
/* _ (Word16 ) imp_pos : glottal impulse position Q0 */
|
||||
/* _ (Word16 *) win : Interpolation window used Q14 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16 []) exc : output excitation buffer Q0 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* INPUT OUTPUT ARGUMENTS */
|
||||
/* NONE */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* NONE */
|
||||
/*=======================================================================*/
|
||||
void pred_lt4_tc_fx(
|
||||
Word16 exc[], /* i/o: excitation buffer */
|
||||
const Word16 T0, /* i : integer pitch lag */
|
||||
Word16 frac, /* i: fraction of lag */
|
||||
const Word16 *win, /* i : interpolation window */
|
||||
const Word16 imp_pos, /* i : glottal impulse position */
|
||||
const Word16 i_subfr /* i : subframe index */
|
||||
)
|
||||
{
|
||||
Word16 i, j,k,l;
|
||||
const Word16 *x0;
|
||||
Word16 excO[L_SUBFR+1];
|
||||
Word32 L_sum;
|
||||
Word16 excI[2*L_SUBFR];
|
||||
Copy( exc + sub(i_subfr, L_SUBFR), excI, shl(L_SUBFR,1) );
|
||||
|
||||
test();
|
||||
IF (sub(add(T0, sub(imp_pos, L_IMPULSE2)), L_SUBFR) < 0 && sub(T0, L_SUBFR) < 0)
|
||||
{
|
||||
set16_fx(&excI[sub(L_SUBFR,T0)], 0, T0);
|
||||
set16_fx(excO, 0, L_SUBFR+1 );
|
||||
x0 = excI + sub(L_SUBFR, L_INTERPOL2-1);
|
||||
|
||||
IF (frac > 0)
|
||||
{
|
||||
frac = sub(frac,UP_SAMP);
|
||||
x0--;
|
||||
}
|
||||
|
||||
l = add(UP_SAMP-1, frac);
|
||||
FOR (j = T0; j < L_SUBFR+1; j++)
|
||||
{
|
||||
k = l;
|
||||
move16();
|
||||
L_sum = L_mult(x0[0], win[k]);
|
||||
FOR (i = 1; i < 2 * L_INTERPOL2; i++)
|
||||
{
|
||||
/*
|
||||
* Here, additions with UP_SAMP are not counted
|
||||
ki* because, the window could easily be modified
|
||||
* so that the values needed are contiguous.
|
||||
*/
|
||||
k += UP_SAMP;
|
||||
L_sum = L_mac(L_sum, x0[i], win[k]); /*Q1 */
|
||||
}
|
||||
L_sum = L_shl(L_sum, 1); /*Q0h */
|
||||
|
||||
excO[j] = round_fx(L_sum);
|
||||
|
||||
x0++;
|
||||
}
|
||||
FOR (i = T0; i < L_SUBFR; i++)
|
||||
{
|
||||
exc[i+i_subfr] = add(exc[i+i_subfr], mult_r(PIT_SHARP_fx, excO[i]));
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
Executable
+136
@@ -0,0 +1,136 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*-------------------------------------------------------------*
|
||||
* preemph_copy_fx()
|
||||
*
|
||||
* Preemphasis: filtering through 1 - mu z^-1
|
||||
*-------------------------------------------------------------*/
|
||||
void preemph_copy_fx(
|
||||
const Word16 x[], /* i : input signal Qx */
|
||||
Word16 y[], /* o : output signal Qx */
|
||||
const Word16 mu, /* i : preemphasis coefficient Q15 */
|
||||
const Word16 lg, /* i : vector size Q0 */
|
||||
Word16 *mem /* i/o: memory (x[-1]) Qx */
|
||||
)
|
||||
{
|
||||
Word16 i, temp;
|
||||
|
||||
temp = x[lg - 1];
|
||||
move16();
|
||||
FOR (i = sub(lg, 1); i > 0; i--)
|
||||
{
|
||||
y[i] = msu_r(L_deposit_h(x[i]), x[i - 1], mu);
|
||||
move16();
|
||||
}
|
||||
y[0] = msu_r(L_deposit_h(x[0]), *mem, mu);
|
||||
move16();
|
||||
|
||||
*mem = temp;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*
|
||||
* E_UTIL_f_preemph2
|
||||
*
|
||||
* Parameters:
|
||||
* shift I: scale output
|
||||
* signal I/O: signal Qx/Qx+shift
|
||||
* mu I: preemphasis factor Q15
|
||||
* L I: vector size
|
||||
* mem I/O: memory (x[-1])
|
||||
*
|
||||
* Function:
|
||||
* Filtering through 1 - mu z^-1
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void E_UTIL_f_preemph2(Word16 shift, Word16 *signal, const Word16 mu, const Word16 lg, Word16 *mem)
|
||||
{
|
||||
Word16 i, temp;
|
||||
Word32 L_tmp;
|
||||
|
||||
temp = signal[lg - 1];
|
||||
move16();
|
||||
|
||||
FOR (i = sub(lg, 1); i > 0; i--)
|
||||
{
|
||||
L_tmp = L_mult(signal[i], 16384);
|
||||
L_tmp = L_msu0(L_tmp, signal[i - 1], mu);
|
||||
L_tmp = L_shl(L_tmp, add(shift,1));
|
||||
signal[i] = round_fx(L_tmp);
|
||||
}
|
||||
|
||||
L_tmp = L_mult(signal[0], 16384);
|
||||
L_tmp = L_msu0(L_tmp, *mem, mu);
|
||||
L_tmp = L_shl(L_tmp, add(shift,1));
|
||||
signal[0] = round_fx(L_tmp);
|
||||
|
||||
*mem = temp;
|
||||
move16();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Word16 E_UTIL_f_preemph3(Word16 *signal, const Word16 mu, const Word16 lg, Word16 *mem, Word16 bits)
|
||||
{
|
||||
Word16 i, QVal, mus, tmp_fixed, Q_new;
|
||||
Word32 L_tmp, L_maxloc;
|
||||
|
||||
|
||||
|
||||
QVal = shl(1, sub(15,bits));
|
||||
mus = shr(mu, bits);
|
||||
|
||||
L_tmp = L_mult(signal[0], QVal);
|
||||
L_tmp = L_msu(L_tmp, *mem, mus);
|
||||
L_maxloc = L_abs(L_tmp);
|
||||
|
||||
FOR (i = 1; i < lg; i++)
|
||||
{
|
||||
L_tmp = L_mult(signal[i], QVal);
|
||||
L_tmp = L_msu(L_tmp, signal[i - 1], mus);
|
||||
L_tmp = L_abs(L_tmp);
|
||||
L_maxloc = L_max(L_tmp, L_maxloc);
|
||||
}
|
||||
|
||||
tmp_fixed = extract_h(L_maxloc);
|
||||
|
||||
Q_new = Q_MAX;
|
||||
move16();
|
||||
IF (tmp_fixed != 0)
|
||||
{
|
||||
Q_new = sub(norm_s(tmp_fixed), bits);
|
||||
Q_new = s_max(Q_new, 0);
|
||||
Q_new = s_min(Q_new, Q_MAX);
|
||||
}
|
||||
|
||||
tmp_fixed = signal[lg - 1];
|
||||
move16();
|
||||
|
||||
FOR (i = sub(lg,1); i > 0; i--)
|
||||
{
|
||||
L_tmp = L_mult(signal[i], QVal);
|
||||
L_tmp = L_msu(L_tmp, signal[i - 1], mus);
|
||||
L_tmp = L_shl(L_tmp, Q_new);
|
||||
signal[i] = round_fx(L_tmp);
|
||||
}
|
||||
|
||||
L_tmp = L_mult(signal[0], QVal);
|
||||
L_tmp = L_msu(L_tmp, *mem, mus);
|
||||
L_tmp = L_shl(L_tmp, Q_new);
|
||||
signal[0] = round_fx(L_tmp);
|
||||
|
||||
*mem = tmp_fixed;
|
||||
move16();
|
||||
|
||||
return Q_new;
|
||||
}
|
||||
|
||||
Executable
+11078
File diff suppressed because it is too large
Load Diff
Executable
+753
@@ -0,0 +1,753 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
|
||||
|
||||
#include "options.h"
|
||||
|
||||
|
||||
UWord32 intLimCDivPos_fx(
|
||||
UWord32 NUM,
|
||||
Word16 DEN
|
||||
)
|
||||
{
|
||||
UWord32 UL_ru, UL_rl;
|
||||
Mpy_32_32_uu(UL_lshl(NUM, 1), intLimCDivInvDQ31[DEN], &UL_ru, &UL_rl);
|
||||
return UL_ru;
|
||||
}
|
||||
|
||||
|
||||
Word32 intLimCDivSigned_fx(
|
||||
Word32 NUM,
|
||||
Word16 DEN)
|
||||
{
|
||||
Word32 L_tmp;
|
||||
|
||||
L_tmp = intLimCDivPos_fx( L_abs(NUM) , DEN);
|
||||
if (NUM < 0)
|
||||
{
|
||||
L_tmp= L_negate(L_tmp); /* one op */
|
||||
}
|
||||
return L_tmp;
|
||||
}
|
||||
|
||||
|
||||
Word16 shrtCDivSignedApprox( const Word16 num,
|
||||
const Word16 den
|
||||
)
|
||||
{
|
||||
Word16 pool_part;
|
||||
|
||||
pool_part = extract_h( L_mult( negate(abs_s(num)), lim_neg_inv_tbl_fx[den] ));
|
||||
/* neg_in always, positive out always, so that positive truncation(rounding) is used */
|
||||
if ( num < 0 )
|
||||
{
|
||||
pool_part = negate(pool_part); /* make negative, one op */
|
||||
}
|
||||
return pool_part;
|
||||
}
|
||||
|
||||
void nearProjQ15_fx(
|
||||
Word16 x,
|
||||
Word16 *result
|
||||
)
|
||||
{
|
||||
const Word16 a[4] = {14967, -25518, 3415, 32351};
|
||||
Word32 b;
|
||||
UWord16 lsb;
|
||||
|
||||
b = L_deposit_l(a[0]);
|
||||
b = L_shl((Word32)add(a[1], extract_h(L_mult0((Word16)b, x))), 1);
|
||||
Mpy_32_16_ss(b, x, &b, &lsb);
|
||||
b = L_add((Word32)a[2], b);
|
||||
Mpy_32_16_ss(b, x, &b, &lsb);
|
||||
b = L_add((Word32)a[3], b);
|
||||
*result = extract_l(b);
|
||||
return ;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* obtainEnergyQuantizerDensity_fx()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
void obtainEnergyQuantizerDensity_fx(
|
||||
const Word16 L,
|
||||
const Word16 R,
|
||||
Word16 *Density )
|
||||
{
|
||||
Word16 Rnrg, den, n;
|
||||
|
||||
den = sub(shl(L, 1), 1);
|
||||
IF( den <= 67 )
|
||||
{
|
||||
Rnrg = extract_l(intLimCDivPos_fx( L_deposit_l(R) , den));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
n = norm_s(den);
|
||||
Rnrg = shr(div_s(R, shl(den, n)), sub(15, n));
|
||||
}
|
||||
Rnrg = add(Rnrg, 28);
|
||||
|
||||
Rnrg = s_min(Rnrg, 56);
|
||||
Rnrg = s_min(Rnrg, sub(R, 96));
|
||||
|
||||
Rnrg = s_max(Rnrg, 3);
|
||||
*Density = obtainEnergyQuantizerDensity_f[Rnrg];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* dsDirac2Dirac_fx()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
void dsDirac2Dirac_fx(
|
||||
const Word16 dsDiracIndex,
|
||||
Word16 *diracs
|
||||
)
|
||||
{
|
||||
*diracs = dsDiracsTab[dsDiracIndex];
|
||||
return;
|
||||
}
|
||||
|
||||
void dsDiracPerQuanta_fx(
|
||||
const Word16 td,
|
||||
const Word16 t_quanta,
|
||||
const Word16 dsm,
|
||||
const unsigned char* const *frQuanta,
|
||||
Word16 *DsIdx
|
||||
)
|
||||
{
|
||||
const unsigned char *sv;
|
||||
Word16 nsv;
|
||||
Word16 t_quanta_o;
|
||||
Word16 dsIndex;
|
||||
Word16 i;
|
||||
|
||||
sv = frQuanta[td];
|
||||
nsv = sv[0];
|
||||
|
||||
t_quanta_o = sub(t_quanta, QUANTAQ3OFFSET);
|
||||
|
||||
IF (sub(t_quanta_o, sv[nsv]) >= 0)
|
||||
{
|
||||
*DsIdx = nsv;
|
||||
move16();
|
||||
return ;
|
||||
}
|
||||
|
||||
IF (sub(t_quanta_o, sv[1]) <= 0)
|
||||
{
|
||||
*DsIdx = 1;
|
||||
move16();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
dsIndex = shl(1, frQuanta[0][td]);
|
||||
if (sub(t_quanta_o, sv[shr(nsv, 1) ]) > 0 )
|
||||
{
|
||||
dsIndex = sub(nsv, dsIndex );
|
||||
}
|
||||
FOR (i = sub(frQuanta[0][td], 1); i >= 0; i--)
|
||||
{
|
||||
dsIndex = add(dsIndex, shl(sub(shl(lshr(sub(sv[dsIndex], t_quanta_o), 15), 1), 1), i));
|
||||
}
|
||||
|
||||
dsIndex = add(dsIndex, lshr(sub(sv[dsIndex], t_quanta_o), 15));
|
||||
dsIndex = sub(dsIndex, lshr(sub(1, dsIndex), 15));
|
||||
|
||||
IF (dsm > 0)
|
||||
{
|
||||
*DsIdx=dsIndex;
|
||||
move16();
|
||||
return;
|
||||
}
|
||||
*DsIdx = add(dsIndex, lshr(sub(add(sv[add(dsIndex,1)], sv[dsIndex]), shl(t_quanta_o, 1)), 15));
|
||||
return;
|
||||
}
|
||||
|
||||
void QuantaPerDsDirac_fx(
|
||||
Word16 td,
|
||||
Word16 dsDiracIndex,
|
||||
const unsigned char* const* dimFrQuanta,
|
||||
Word16 *Quanta
|
||||
)
|
||||
{
|
||||
*Quanta = dimFrQuanta[td][dsDiracIndex];
|
||||
move16();
|
||||
if(dsDiracIndex == 0)
|
||||
{
|
||||
*Quanta = -1; /* single op */ move16();
|
||||
}
|
||||
*Quanta = add(*Quanta, QUANTAQ3OFFSET);
|
||||
return ;
|
||||
}
|
||||
|
||||
void conservativeL1Norm_fx(
|
||||
Word16 L,
|
||||
Word16 Qvec,
|
||||
Word16 Fcons,
|
||||
Word16 Qavail,
|
||||
Word16 Qreserv,
|
||||
Word16 Dspec,
|
||||
Word16 *Dvec,
|
||||
Word16 *Qspare,
|
||||
Word16 *Qreservplus,
|
||||
Word16 *Dspecplus
|
||||
)
|
||||
{
|
||||
|
||||
Word16 Minit, Mprime;
|
||||
Word16 Qtestminus;
|
||||
const unsigned char *frQuantaL;
|
||||
|
||||
frQuantaL = hBitsN[L];
|
||||
|
||||
*Qreservplus = add(Qreserv, sub(Qvec, QUANTAQ3OFFSET));
|
||||
|
||||
dsDiracPerQuanta_fx(L, Qvec, Fcons, hBitsN, &Minit);
|
||||
|
||||
Mprime = Minit;
|
||||
move16();
|
||||
DO
|
||||
{
|
||||
Qtestminus = (short)frQuantaL[Mprime];
|
||||
move16();
|
||||
*Qspare = sub(Qavail, Qtestminus);
|
||||
Mprime = sub(Mprime, 1);
|
||||
}
|
||||
WHILE ( (Mprime >= 0) && sub(*Qspare, QUANTAQ3OFFSET ) < 0 );
|
||||
|
||||
if(Mprime < 0)
|
||||
{
|
||||
*Qspare = add(Qavail, QUANTAQ3OFFSET); /* single op */
|
||||
}
|
||||
dsDirac2Dirac_fx(add(Mprime, 1), Dvec);
|
||||
|
||||
*Dspecplus = add(Dspec, *Dvec);
|
||||
*Qreservplus = sub(*Qreservplus, (short)frQuantaL[Minit]);
|
||||
*Qspare = sub(*Qspare, QUANTAQ3OFFSET);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void bandBitsAdjustment_fx(
|
||||
Word16 Brc,
|
||||
UWord32 INTrc,
|
||||
Word16 Bavail,
|
||||
Word16 Nbands,
|
||||
Word16 D,
|
||||
Word16 L,
|
||||
Word16 Bband,
|
||||
Word16 Breserv,
|
||||
Word16 *Bband_adj,
|
||||
Word16 *Brem,
|
||||
Word16 *Breservplus)
|
||||
{
|
||||
Word16 Btemp;
|
||||
Word16 Bff;
|
||||
Word32 L_tmp;
|
||||
|
||||
rangeCoderFinalizationFBits_fx(Brc, INTrc, &Bff);
|
||||
|
||||
IF(sub(D, Nbands) < 0)
|
||||
{
|
||||
L_tmp = L_deposit_l(sub(Breserv, Bff));
|
||||
Btemp = extract_l(intLimCDivSigned_fx(L_tmp, s_min(D, 3))); /* result always fits in Word16 */
|
||||
*Breservplus = add(Bband, Breserv);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Btemp = 0;
|
||||
move16();
|
||||
*Breservplus = add(Bband, Bff);
|
||||
}
|
||||
*Bband_adj = s_min(extract_l(L_mult(L, 40)), Bband);
|
||||
*Brem = sub(Bavail, Bff);
|
||||
*Bband_adj = s_min(*Brem, add(*Bband_adj, Btemp));
|
||||
*Bband_adj = s_max(0, *Bband_adj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static Word16 Ratio_base2Q11_fx( /* o : Q11 */
|
||||
const Word16 opp, /* i : Q15 */
|
||||
const Word16 near /* i : Q15 */
|
||||
)
|
||||
{
|
||||
Word16 mc, nc, ms, ns, d, z;
|
||||
Word16 result;
|
||||
Word32 acc;
|
||||
|
||||
ns = norm_s(opp ); /* exponent */
|
||||
nc = norm_s(near ); /* exponent */
|
||||
|
||||
ms = shl(opp, ns); /* mantissa */
|
||||
mc = shl(near, nc); /* mantissa */
|
||||
|
||||
acc = L_mac(538500224L, mc, -2776); /* a0*mc + a1, acc(Q27), a0(Q11), a1(Q27) */
|
||||
z = mac_r(acc, ms, -2776); /* z in Q11, a0 in Q11 */
|
||||
d = sub(ms, mc); /* d in Q15 */
|
||||
z = mult_r(z, d); /* z in Q11 */
|
||||
|
||||
result = add(z, shl(sub(nc, ns), 11));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Ratio_rQ3_fx(
|
||||
Word16 opp,
|
||||
Word16 near,
|
||||
Word16 *result
|
||||
)
|
||||
{
|
||||
Word16 tmp;
|
||||
|
||||
tmp = add(1<<7 , Ratio_base2Q11_fx(opp, near));
|
||||
*result = shr(tmp, 8);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
void densityAngle2RmsProjDec_fx(
|
||||
Word16 D,
|
||||
Word16 indexphi,
|
||||
Word16 *oppQ15,
|
||||
Word16 *nearQ15,
|
||||
Word16 *oppRatioQ3
|
||||
)
|
||||
{
|
||||
Word16 phiQ14q;
|
||||
Word16 oppTail, nearTail;
|
||||
|
||||
phiQ14q = (Word16)intLimCDivPos_fx(L_shl(L_deposit_l(indexphi), 13), shr(D, 1));
|
||||
if (indexphi < 0)
|
||||
{
|
||||
phiQ14q = 1 << 13; /* one op */ move16();
|
||||
}
|
||||
|
||||
oppTail = shr(sub(16320, phiQ14q), 15);
|
||||
nearTail = shr(sub(phiQ14q, 64), 15);
|
||||
|
||||
IF (s_or(oppTail, nearTail) < 0)
|
||||
{
|
||||
*oppQ15 = s_and(oppTail, (1 << 15) - 1);
|
||||
*nearQ15 = s_and(nearTail, (1 << 15) - 1);
|
||||
*oppRatioQ3 = shl(add(1, shl(nearTail, 1)), 14);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
nearProjQ15_fx( shl(sub(1 << 14, phiQ14q), 1), oppQ15);
|
||||
nearProjQ15_fx(shl(phiQ14q, 1), nearQ15);
|
||||
Ratio_rQ3_fx(*oppQ15, *nearQ15, oppRatioQ3);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void densityAngle2RmsProjEnc_fx(
|
||||
Word16 D,
|
||||
Word16 phiQ14uq,
|
||||
Word16 *indexphi,
|
||||
Word16 *oppQ15,
|
||||
Word16 *nearQ15,
|
||||
Word16 *oppRatioQ3
|
||||
)
|
||||
{
|
||||
*indexphi = mult_r(shl(D, 1), phiQ14uq);
|
||||
if (s_and(D, 1) > 0)
|
||||
{
|
||||
*indexphi = -1; /* one op */ move16();
|
||||
}
|
||||
densityAngle2RmsProjDec_fx(D, *indexphi, oppQ15, nearQ15, oppRatioQ3);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void NearOppSplitAdjustment_fx(
|
||||
const Word16 qband,
|
||||
const Word16 qzero,
|
||||
const Word16 Qac,
|
||||
const UWord32 INTac,
|
||||
const Word16 qglobal,
|
||||
const Word16 FlagCons,
|
||||
const Word16 Np,
|
||||
const Word16 Nhead,
|
||||
const Word16 Ntail,
|
||||
const Word16 Nnear,
|
||||
const Word16 Nopp,
|
||||
Word16 oppRQ3,
|
||||
Word16 *qnear,
|
||||
Word16 *qopp,
|
||||
Word16 *qglobalupd
|
||||
)
|
||||
{
|
||||
|
||||
Word16 qac, qboth, qskew, qavg, qmin, Midx;
|
||||
Word32 L_QIb, L_qnum;
|
||||
Word16 QIb, QIa;
|
||||
|
||||
rangeCoderFinalizationFBits_fx(Qac, INTac, &qac);
|
||||
qboth = sub(qband, sub(qac, qzero));
|
||||
/* skew calc code */
|
||||
qskew = 0 ;
|
||||
move16();
|
||||
IF (sub(Nhead, 1) > 0)
|
||||
{
|
||||
qavg = extract_h(L_shl(intLimCDivSigned_fx((Word32)qboth, Np),16)); /* qboth may be negative */
|
||||
dsDiracPerQuanta_fx(Ntail, qavg, FlagCons, hBitsN, &Midx );
|
||||
QuantaPerDsDirac_fx(Nhead, Midx, hBitsN, &qmin);
|
||||
qskew = sub(qavg, qmin);
|
||||
qskew = s_max(0, qskew);
|
||||
} /* end of skew calc code*/
|
||||
|
||||
QIa = add(extract_l(intLimCDivPos_fx((UWord32)L_deposit_l(Nopp), Nnear)), 1); /* always positive Word16 out */
|
||||
L_qnum = L_sub( L_deposit_l(sub(sub(add(qband, qzero), qac), qskew)), L_mult0(Nopp, oppRQ3));
|
||||
|
||||
L_QIb = L_deposit_l(0);
|
||||
IF (L_qnum > 0)
|
||||
{
|
||||
L_QIb = (Word32) intLimCDivPos_fx(L_qnum, QIa);
|
||||
}
|
||||
*qnear = qboth;
|
||||
QIb = extract_h(L_shl(L_QIb, 16)); /* may saturate */
|
||||
if (sub(QIb, qboth) <= 0)
|
||||
{
|
||||
*qnear = QIb;
|
||||
}
|
||||
*qopp = sub(qboth, *qnear);
|
||||
*qglobalupd = sub(qglobal, sub(qac, qzero));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* apply_gain()
|
||||
*
|
||||
* Apply gain
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void apply_gain_fx(
|
||||
const Word16 *ord, /* i : Indices for energy order */
|
||||
const Word16 *band_start, /* i : Sub band start indices */
|
||||
const Word16 *band_end, /* i : Sub band end indices */
|
||||
const Word16 num_sfm, /* i : Number of bands */
|
||||
const Word16 *gains, /* i : Band gain vector Q12 */
|
||||
Word16 *xq /* i/o: Float synthesis / Gain adjusted synth Q15/Q12 */
|
||||
)
|
||||
{
|
||||
Word16 band,i;
|
||||
Word16 g; /* Q12 */
|
||||
|
||||
FOR ( band = 0; band < num_sfm; band++)
|
||||
{
|
||||
g = gains[ord[band]];
|
||||
|
||||
FOR( i = band_start[band]; i < band_end[band]; i++)
|
||||
{
|
||||
/*xq[i] *= g; */
|
||||
xq[i] = mult_r(g, xq[i]);
|
||||
move16(); /*12+15+1-16=12 */
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* fine_gain_quant()
|
||||
*
|
||||
* Fine gain quantization
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void fine_gain_quant_fx(
|
||||
Encoder_State_fx *st_fx,
|
||||
const Word16 *ord, /* i : Indices for energy order */
|
||||
const Word16 num_sfm, /* i : Number of bands */
|
||||
const Word16 *gain_bits, /* i : Gain adjustment bits per sub band */
|
||||
Word16 *fg_pred, /* i/o: Predicted gains / Corrected gains Q12 */
|
||||
const Word16 *gopt /* i : Optimal gains Q12 */
|
||||
)
|
||||
{
|
||||
Word16 band;
|
||||
Word16 gbits;
|
||||
Word16 idx;
|
||||
Word16 gain_db,gain_dbq;
|
||||
Word16 err;
|
||||
|
||||
Word16 tmp1, tmp2, exp1, exp2;
|
||||
Word32 L_tmp;
|
||||
UWord16 lsb;
|
||||
|
||||
FOR ( band = 0; band < num_sfm; band++)
|
||||
{
|
||||
gbits = gain_bits[ord[band]];
|
||||
test();
|
||||
IF ( fg_pred[band] != 0 && gbits > 0 )
|
||||
{
|
||||
exp1 = norm_s(gopt[band]);
|
||||
exp1 = sub(exp1, 1);
|
||||
tmp1 = shl(gopt[band], exp1);
|
||||
exp2 = norm_s(fg_pred[band]);
|
||||
tmp2 = shl(fg_pred[band], exp2);
|
||||
exp1 = add(15, sub(exp1, exp2));
|
||||
err = div_s(tmp1, tmp2);
|
||||
tmp1 = norm_s(err);
|
||||
exp2 = Log2_norm_lc(L_deposit_h(shl(err, tmp1)));
|
||||
tmp1 = sub(14, tmp1);
|
||||
tmp1 = sub(tmp1, exp1);
|
||||
L_tmp = L_Comp(tmp1, exp2);
|
||||
Mpy_32_16_ss(L_tmp, 24660, &L_tmp, &lsb); /* 24660 = 20*log10(2) in Q12 */ /*16+12-15=13 */
|
||||
gain_db = round_fx(L_shl(L_tmp, 17));
|
||||
|
||||
idx = squant_fx(gain_db, &gain_dbq, finegain_fx[gbits-1], gain_cb_size[gbits-1]);
|
||||
push_indice_fx( st_fx, IND_PVQ_FINE_GAIN, idx, gbits );
|
||||
|
||||
L_tmp = L_mult0(gain_dbq, 21771); /* 21771=0.05*log2(10) */ /* 14+17=31 */
|
||||
L_tmp = L_shr(L_tmp, 15);
|
||||
tmp1 = L_Extract_lc(L_tmp, &exp1);
|
||||
tmp1 = abs_s(tmp1);
|
||||
tmp1 = extract_l(Pow2(14, tmp1));
|
||||
exp1 = sub(14, exp1);
|
||||
|
||||
L_tmp = L_mult0(fg_pred[band], tmp1); /*12+exp1 */
|
||||
fg_pred[band] = round_fx(L_shl(L_tmp, sub(16, exp1))); /*12+exp1+16-exp1-16=12 */
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* srt_vec_ind()
|
||||
*
|
||||
* sort vector and save sorting indeces
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void srt_vec_ind16_fx (
|
||||
const Word16 *linear, /* linear input */
|
||||
Word16 *srt, /* sorted output*/
|
||||
Word16 *I, /* index for sorted output */
|
||||
Word16 length
|
||||
)
|
||||
{
|
||||
Word16 pos,npos;
|
||||
Word16 idxMem;
|
||||
Word16 valMem;
|
||||
|
||||
/*initilize */
|
||||
FOR (pos = 0; pos < length; pos++)
|
||||
{
|
||||
I[pos] = pos;
|
||||
move16();
|
||||
}
|
||||
|
||||
Copy(linear, srt,length);
|
||||
|
||||
/* now iterate */
|
||||
FOR (pos = 0; pos < (length - 1); pos++)
|
||||
{
|
||||
FOR (npos = (pos + 1); npos < length; npos++)
|
||||
{
|
||||
IF (sub(srt[npos], srt[pos]) < 0)
|
||||
{
|
||||
idxMem = I[pos];
|
||||
move16();
|
||||
I[pos] = I[npos];
|
||||
move16();
|
||||
I[npos] = idxMem;
|
||||
move16();
|
||||
|
||||
valMem = srt[pos];
|
||||
move16();
|
||||
srt[pos] = srt[npos];
|
||||
move16();
|
||||
srt[npos] = valMem;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* atan2_fx():
|
||||
*
|
||||
* Approximates arctan piecewise with various 4th to 5th order least square fit
|
||||
* polynomials for input in 5 segments:
|
||||
* - 0.0 to 1.0
|
||||
* - 1.0 to 2.0
|
||||
* - 2.0 to 4.0
|
||||
* - 4.0 to 8.0
|
||||
* - 8.0 to infinity
|
||||
*---------------------------------------------------------------------------*/
|
||||
Word16 atan2_fx( /* o: Angle between 0 and PI/2 radian (Q14) */
|
||||
const Word32 y, /* i: Argument must be positive (Q15) */
|
||||
const Word32 x /* i: Q15 */
|
||||
)
|
||||
{
|
||||
Word32 acc, arg;
|
||||
Word16 man, expo, reciprocal;
|
||||
Word16 angle, w, z;
|
||||
|
||||
IF (x == 0)
|
||||
{
|
||||
return 25736; /* PI/2 in Q14 */
|
||||
}
|
||||
man = ratio(y, x, &expo); /* man in Q14 */
|
||||
expo = sub(expo, (15 - 14)); /* Now, man is considered in Q15 */
|
||||
arg = L_shr((Word32)man, expo);
|
||||
|
||||
IF (L_shr(arg, 3+15) != 0)
|
||||
/*===============================*
|
||||
* 8.0 <= x < infinity *
|
||||
*===============================*/
|
||||
{
|
||||
/* atan(x) = PI/2 - 1/x + 1/(3x^3) - 1/(5x^5) + ...
|
||||
* ~ PI/2 - 1/x, for x >= 8.
|
||||
*/
|
||||
expo = norm_l(arg);
|
||||
man = extract_h(L_shl(arg, expo));
|
||||
reciprocal = div_s(0x3fff, man);
|
||||
expo = sub(15 + 1, expo);
|
||||
reciprocal = shr(reciprocal, expo); /* Q14 */
|
||||
angle = sub(25736, reciprocal); /* Q14 (PI/2 - 1/x) */
|
||||
|
||||
/* For 8.0 <= x < 10.0, 1/(5x^5) is not completely negligible.
|
||||
* For more accurate result, add very small correction term.
|
||||
*/
|
||||
if (L_sub(L_shr(arg, 15), 10L) < 0)
|
||||
{
|
||||
angle = add(angle, 8); /* Add tiny correction term. */
|
||||
}
|
||||
}
|
||||
ELSE IF (L_shr(arg, 2+15) != 0)
|
||||
/*==========================*
|
||||
* 4.0 <= x < 8.0 *
|
||||
*==========================*/
|
||||
{
|
||||
/* interval: [3.999, 8.001]
|
||||
* atan(x) ~ (((a0*x + a1)*x + a2)*x + a3)*x + a4
|
||||
* = (((a0*8*y + a1)*8*y + a2)*8*y + a3)*8*y + a4 Substitute 8*y -> x
|
||||
* = (((a0*8^3*y + a1*8^2)*y + a2*8)*y + a3)*8*y + a4
|
||||
* = ((( c0*y + c1)*y + c2)*y + c3)*8*y + c4,
|
||||
* where y = x/8
|
||||
* and a0 = -1.28820869667651e-04, a1 = 3.88263533346295e-03,
|
||||
* a2 = -4.64216306484597e-02, a3 = 2.75986060068931e-01,
|
||||
* a4 = 7.49208077809799e-01.
|
||||
*/
|
||||
w = extract_l(L_shr(arg, 3)); /* Q15 y = x/8 */
|
||||
acc = L_add(533625337L, 0); /* Q31 c1 = a1*8^2 */
|
||||
z = mac_r(acc, w, -2161); /* Q15 c0 = a0*8^3 */
|
||||
acc = L_add(-797517542L, 0); /* Q31 c2 = a2*8 */
|
||||
z = mac_r(acc, w, z); /* Q15 */
|
||||
acc = L_add(592675551L, 0); /* Q31 c3 = a3 */
|
||||
z = mac_r(acc, w, z); /* z (in:Q15, out:Q12) */
|
||||
acc = L_add(201114012L, 0); /* Q28 c4 = a4 */
|
||||
acc = L_mac(acc, w, z); /* Q28 */
|
||||
angle = extract_l(L_shr(acc, (28 - 14))); /* Q14 result of atan(x), where 4 <= x < 8 */
|
||||
}
|
||||
ELSE IF (L_shr(arg, 1+15) != 0)
|
||||
/*==========================*
|
||||
* 2.0 <= x < 4.0 *
|
||||
*==========================*/
|
||||
{
|
||||
/* interval: [1.999, 4.001]
|
||||
* atan(x) ~ (((a0*x + a1)*x + a2)*x + a3)*x + a4
|
||||
* = (((a0*4*y + a1)*4*y + a2)*4*y + a3)*4*y + a4 Substitute 4*y -> x
|
||||
* = (((a0*16*y + a1*4)*y + a2)*4*y + a3)*4*y + a4
|
||||
* = (((a0*32*y + a1*8)*y + a2*2)*2*y + a3)*4*y + a4
|
||||
* = ((( c0*y + c1)*y + c2)*2*y + c3)*4*y + c4,
|
||||
* where y = x/4
|
||||
* and a0 = -0.00262378195660943, a1 = 0.04089687039888652,
|
||||
* a2 = -0.25631148958325911, a3 = 0.81685854627399479,
|
||||
* a4 = 0.21358070563097167
|
||||
* */
|
||||
w = extract_l(L_shr(arg, 2)); /* Q15 y = x/4 */
|
||||
acc = L_add(702602883L, 0); /* Q31 c1 = a1*8 */
|
||||
z = mac_r(acc, w, -2751); /* Q15 c0 = a0*32 */
|
||||
acc = L_add(-1100849465L, 0); /* Q31 c2 = a2*2 */
|
||||
z = mac_r(acc, w, z); /* z (in:Q15, out:Q14) */
|
||||
acc = L_add(877095185L, 0); /* Q30 c3 = a3 */
|
||||
z = mac_r(acc, w, z); /* z (in:Q14, out:Q12) */
|
||||
acc = L_add(57332634L, 0); /* Q28 c4 = a4 */
|
||||
acc = L_mac(acc, w, z); /* Q28 */
|
||||
angle = extract_l(L_shr(acc, (28 - 14))); /* Q14 result of atan(x) where 2 <= x < 4 */
|
||||
}
|
||||
ELSE IF (L_shr(arg, 15) != 0)
|
||||
/*==========================*
|
||||
* 1.0 <= x < 2.0 *
|
||||
*==========================*/
|
||||
{
|
||||
/* interval: [0.999, 2.001]
|
||||
* atan(x) ~ (((a0*x + 1)*x + a2)*x + a3)*x + a4
|
||||
* = (((a0*2*y + a1)*2*y + a2)*2*y + a3)*2*y + a4 Substitute 2*y -> x
|
||||
* = (((a0*4*y + a1*2)*y + a2)*2*y + a3)*2*y + a4
|
||||
* = (((a0*4*y + a1*2)*y + a2)*y + a3/2)*4*y + a4
|
||||
* = ((( c0*y + c1)*y + c2)*y + c3)*4*y + c4,
|
||||
* where y = x/2
|
||||
* and a0 = -0.0160706457245251, a1 = 0.1527106504065224,
|
||||
* a2 = -0.6123208404800871, a3 = 1.3307896976322915,
|
||||
* a4 = -0.0697089375247448
|
||||
*/
|
||||
w = extract_l(L_shr(arg, 1)); /* Q15 y= x/2 */
|
||||
acc = L_add(655887249L, 0); /* Q31 c1 = a1*2 */
|
||||
z = mac_r(acc, w, -2106); /* Q15 c0 = a0*4 */
|
||||
acc = L_add(-1314948992L, 0); /* Q31 c2 = a2 */
|
||||
z = mac_r(acc, w, z);
|
||||
acc = L_add(1428924557L, 0); /* Q31 c3 = a3/2 */
|
||||
z = mac_r(acc, w, z); /* z (in:Q15, out:Q13) */
|
||||
acc = L_add(-37424701L, 0); /* Q29 c4 = a4 */
|
||||
acc = L_mac(acc, w, z); /* Q29 */
|
||||
angle = extract_l(L_shr(acc, (29 - 14))); /* Q14 result of atan(x) where 1 <= x < 2 */
|
||||
}
|
||||
ELSE
|
||||
/*==========================*
|
||||
* 0.0 <= x < 1.0 *
|
||||
*==========================*/
|
||||
{
|
||||
/* interval: [-0.001, 1.001]
|
||||
* atan(x) ~ ((((a0*x + a1)*x + a2)*x + a3)*x + a4)*x + a5
|
||||
* = ((((a0*2*x + a1*2)*x/2 + a2)*x + a3)*x + a4)*x + a5
|
||||
* = (((( c0*x + c1)*x/2 + c2)*x + c3)*x + c4)*x + c5
|
||||
* where
|
||||
* a0 = -5.41182677118661e-02, a1 = 2.76690449232515e-01,
|
||||
* a2 = -4.63358392562492e-01, a3 = 2.87188466598566e-02,
|
||||
* a4 = 9.97438122814383e-01, a5 = 5.36158556179092e-05.
|
||||
*/
|
||||
w = extract_l(arg); /* Q15 */
|
||||
acc = L_add(1188376431L, 0); /* Q31 c1 = a1*2 */
|
||||
z = mac_r(acc, w, -3547); /* Q15 c0 = a0*2 */
|
||||
acc = L_add(-995054571L, 0); /* Q31 c2 = a2 */
|
||||
z = extract_h(L_mac0(acc, w, z)); /* Q15 non-fractional mode multiply */
|
||||
acc = L_add(61673254L, 0); /* Q31 c3 = a3 */
|
||||
z = mac_r(acc, w, z);
|
||||
acc = L_add(2141982059L, 0); /* Q31 c4 = a4 */
|
||||
z = mac_r(acc, w, z);
|
||||
acc = L_add(115139L, 0); /* Q31 c5 = a5 */
|
||||
acc = L_mac(acc, w, z); /* Q31 */
|
||||
angle = extract_l(L_shr(acc, 31 - 14)); /* Q14 result of atan(x), where 0 <= x < 1 */
|
||||
}
|
||||
|
||||
return angle; /* Q14 between 0 and PI/2 radian. */
|
||||
}
|
||||
|
||||
|
||||
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* rc_get_bits2()
|
||||
*
|
||||
* Get number of bits needed to finalize range coder
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
Word16 rc_get_bits2_fx( /* o: Number of bits needed */
|
||||
const Word16 N, /* i: Number of bits currently used */
|
||||
const UWord32 range /* i: Range of range coder */
|
||||
)
|
||||
{
|
||||
return add(add(N, 2), norm_ul(range));
|
||||
}
|
||||
|
||||
void rangeCoderFinalizationFBits_fx(
|
||||
Word16 Brc,
|
||||
UWord32 INTrc,
|
||||
Word16 *FBits
|
||||
)
|
||||
{
|
||||
Word32 L_Bq15;
|
||||
UWord32 h, UL_tmp;
|
||||
UWord16 Bq15ui16, l;
|
||||
Word16 B, E, x, k;
|
||||
*FBits = shl(add(Brc, 32), 3);
|
||||
|
||||
B = sub(30, norm_ul(INTrc));
|
||||
x = sub(B, RCF_INIT_SHIFT );
|
||||
L_Bq15 = 0;
|
||||
move16();
|
||||
if (x >= 0)
|
||||
{
|
||||
L_Bq15 = (Word32)UL_lshr(INTrc, x);
|
||||
}
|
||||
|
||||
E = 2;
|
||||
move16();
|
||||
FOR(k = 1; k < 4; k++)
|
||||
{
|
||||
Bq15ui16 = u_extract_l(L_shr(L_Bq15, s_and(E, 1)));
|
||||
UL_tmp = UL_lshl(UL_deposit_l(Bq15ui16), 1);
|
||||
Mpy_32_16_uu(UL_tmp, Bq15ui16, &h , &l);
|
||||
L_Bq15 = (Word32) h;
|
||||
E = add(shl(B, 1), extract_l(L_lshr(L_sub(((1L << 16) - 1L), L_Bq15), 31)));
|
||||
B = E;
|
||||
move16();
|
||||
}
|
||||
*FBits = sub(*FBits, B);
|
||||
return;
|
||||
}
|
||||
|
||||
Executable
+193
@@ -0,0 +1,193 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Prototypes
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
static void nearest_neighbor_2D8_fx( const Word32 x[], Word16 y[] );
|
||||
static Word32 compute_error_2D8_fx( const Word32 x[], const Word16 y[] );
|
||||
|
||||
/*--------------------------------------------------------------*
|
||||
* RE8_PPV:
|
||||
*
|
||||
* NEAREST NEIGHBOR SEARCH IN INFINITE LATTICE RE8
|
||||
* the algorithm is based on the definition of RE8 as
|
||||
* RE8 = (2D8) U (2D8+[1,1,1,1,1,1,1,1])
|
||||
* it applies the coset decoding of Sloane and Conway
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
void re8_PPV_fx(
|
||||
const Word32 x[], /* i : point in R^8Q15 */
|
||||
Word16 y[] /* o : point in RE8 (8-dimensional integer vector) */
|
||||
)
|
||||
{
|
||||
Word16 i, y0[8];
|
||||
Word32 e0, e1, x1[8];
|
||||
|
||||
/*--------------------------------------------------------------*
|
||||
* find the nearest neighbor y0 of x in 2D8
|
||||
*--------------------------------------------------------------*/
|
||||
nearest_neighbor_2D8_fx( x, y0 );
|
||||
|
||||
/*--------------------------------------------------------------*
|
||||
* find the nearest neighbor y1 of x in 2D8+(1,...,1) (by coset decoding)
|
||||
*--------------------------------------------------------------*/
|
||||
|
||||
FOR( i=0; i<8; i++ )
|
||||
{
|
||||
x1[i] = L_sub(x[i], QR);
|
||||
move32();
|
||||
}
|
||||
nearest_neighbor_2D8_fx( x1, y );
|
||||
|
||||
FOR ( i = 0; i < 8; i++ )
|
||||
{
|
||||
y[i] = add(y[i], 1);
|
||||
move16();
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------*
|
||||
* compute e0=||x-y0||^2 and e1=||x-y1||^2
|
||||
*--------------------------------------------------------------*/
|
||||
|
||||
e0 = compute_error_2D8_fx( x, y0 );
|
||||
e1 = compute_error_2D8_fx( x, y );
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*
|
||||
* select best candidate y0 or y1 to minimize distortion
|
||||
*--------------------------------------------------------------*/
|
||||
IF( L_sub(e0, e1) < 0 )
|
||||
{
|
||||
Copy( y0, y, 8 );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*
|
||||
* Nearest_neighbor_2D8(x,y)
|
||||
*
|
||||
* NEAREST NEIGHBOR SEARCH IN INFINITE LATTICE 2D8
|
||||
* algorithm: nn_2D8(x) = 2*nn_D8(x/2)
|
||||
* nn_D8 = decoding of Z^8 with Wagner rule
|
||||
* (see Conway and Sloane's paper in IT-82)
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
static void nearest_neighbor_2D8_fx(
|
||||
const Word32 x[], /* i : point in R^8 */
|
||||
Word16 y[] /* o : point in 2D8 (8-dimensional integer vector) */
|
||||
)
|
||||
{
|
||||
Word16 i,j;
|
||||
Word16 sum, tmp16, tmp16b;
|
||||
Word32 s, e, em;
|
||||
|
||||
/*--------------------------------------------------------------*
|
||||
* round x into 2Z^8 i.e. compute y=(y1,...,y8) such that yi = 2[xi/2]
|
||||
* where [.] is the nearest integer operator
|
||||
* in the mean time, compute sum = y1+...+y8
|
||||
*--------------------------------------------------------------*/
|
||||
sum = 0;
|
||||
move16();
|
||||
|
||||
FOR( i=0; i<8; i++ )
|
||||
{
|
||||
/* round to ..., -2, 0, 2, ... ([-1..1[ --> 0) */
|
||||
tmp16 = round_fx(L_add(x[i], L_shr(x[i], 31)));
|
||||
y[i] = shl(tmp16, 1);
|
||||
move16();
|
||||
/* sum += y[i] */
|
||||
sum = add(sum, y[i]);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------*
|
||||
* check if y1+...+y8 is a multiple of 4
|
||||
* if not, y is not round xj in the wrong way where j is defined by
|
||||
* j = arg max_i | xi -yi|
|
||||
* (this is called the Wagner rule)
|
||||
*--------------------------------------------------------------*/
|
||||
IF( s_and(sum, 2) != 0 )
|
||||
{
|
||||
/* find j = arg max_i | xi -yi| */
|
||||
em = L_deposit_l(0);
|
||||
j = 0;
|
||||
move16();
|
||||
|
||||
FOR( i=0; i<8; i++ )
|
||||
{
|
||||
/* compute ei = xi-yi */
|
||||
/* e[i]=x[i]-y[i] */
|
||||
e = L_msu(x[i], y[i], QR/2);
|
||||
|
||||
/* compute |ei| = | xi-yi | */
|
||||
s = L_abs(e);
|
||||
|
||||
/* check if |ei| is maximal, if so, set j=i */
|
||||
if( L_sub(em, s) < 0 )
|
||||
{
|
||||
j = i;
|
||||
move16();
|
||||
}
|
||||
em = L_max(s, em);
|
||||
}
|
||||
|
||||
/* round xj in the "wrong way" */
|
||||
e = L_msu(x[j], y[j], QR/2);
|
||||
tmp16 = extract_h(e);
|
||||
tmp16b = add(y[j], 2);
|
||||
|
||||
if( tmp16 < 0 )
|
||||
{
|
||||
tmp16b = sub(tmp16b, 2+2);
|
||||
}
|
||||
y[j] = tmp16b;
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*
|
||||
* Compute_error_2D8(x,y)
|
||||
*
|
||||
* Compute mean square error between input vector and
|
||||
* (quantized) point in 2D8.
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
static Word32 compute_error_2D8_fx( /* o : mean squared error */
|
||||
const Word32 x[], /* i : input vector */
|
||||
const Word16 y[] /* i : point in 2D8 (8-dimensional integer vector) */
|
||||
)
|
||||
{
|
||||
Word16 i, hi, lo;
|
||||
Word32 err, Ltmp;
|
||||
|
||||
err = L_deposit_l(0);
|
||||
FOR( i=0; i<8; i++ )
|
||||
{
|
||||
/*tmp = x[i]-y[i];*/
|
||||
Ltmp = L_msu(x[i], y[i], 16384);
|
||||
hi = extract_h(L_shl(Ltmp, 1));
|
||||
lo = extract_l(L_msu(Ltmp, hi, 16384));
|
||||
|
||||
Ltmp = L_mult(hi, hi);
|
||||
Ltmp = L_shl(Ltmp, 14);
|
||||
Ltmp = L_mac(Ltmp, hi, lo);
|
||||
Ltmp = L_mac0(Ltmp, mult(lo, lo), 1);
|
||||
|
||||
/* err+=tmp*tmp */
|
||||
err = L_add(Ltmp, err);
|
||||
}
|
||||
|
||||
return( err );
|
||||
}
|
||||
Executable
+387
@@ -0,0 +1,387 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Prototypes
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
static Word16 re8_identify_absolute_leader_fx( const Word16 y[] );
|
||||
static void re8_coord_fx( const Word16 *y, Word16 *k) ;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* re8_vor_fx()
|
||||
*
|
||||
* MULTI-RATE RE8 INDEXING BY VORONOI EXTENSION
|
||||
*----------------------------------------------------------------*/
|
||||
void re8_vor_fx(
|
||||
const Word16 y[], /* i : point in RE8 (8-dimensional integer vector) */
|
||||
Word16 *n, /* o : codebook number n=0,2,3,4,... (scalar integer) */
|
||||
Word16 k[], /* o : Voronoi index (integer vector of dimension 8) used only if n>4*/
|
||||
Word16 c[], /* o : codevector in Q0, Q2, Q3, or Q4 if n<=4, y=c */
|
||||
Word16 *ka /* o : identifier of absolute leader (to index c) */
|
||||
)
|
||||
{
|
||||
Word16 i, r, iter, ka_tmp, n_tmp, mask;
|
||||
Word16 k_tmp[8], v[8], c_tmp[8], k_mod[8];
|
||||
Word32 Ltmp, Lsphere;
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* verify if y is in Q0, Q2, Q3 or Q4
|
||||
* (a fast search is used here:
|
||||
* the codebooks Q0, Q2, Q3 or Q4 are specified in terms of RE8 absolute leaders
|
||||
* (see FORinstance Xie and Adoul's paper in ICASSP 96)
|
||||
* - a unique code identifying the absolute leader related to y is computed
|
||||
* in re8_identify_absolute_leader()
|
||||
* this code is searched FORin a pre-defined list which specifies Q0, Q2, Q3 or Q4)
|
||||
* the absolute leader is identified by ka
|
||||
* - a translation table maps ka to the codebook number n)
|
||||
*----------------------------------------------------------------*/
|
||||
*ka = re8_identify_absolute_leader_fx( y );
|
||||
move16();
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* compute codebook number n of Qn (by table look-up)
|
||||
* at this stage, n=0,2,3,4 or out=100
|
||||
*----------------------------------------------------------------*/
|
||||
*n = Da_nq_fx[*ka];
|
||||
move16();
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* decompose y into :
|
||||
* (if n<=4:)
|
||||
* y = c where c is in Q0, Q2, Q3 or Q4
|
||||
* or
|
||||
* (if n>4:)
|
||||
* y = m c + v where c is in Q3 or Q4, v is a Voronoi codevector
|
||||
* m=2^r (r integer >=2)
|
||||
*
|
||||
* in the latter case (if n>4), as a side-product, compute the (Voronoi) index k[] of v
|
||||
* and replace n by n = n' + 2r where n' = 3 or 4 (c is in Qn') and r is defined above
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
IF( sub(*n, 4) <= 0 )
|
||||
{
|
||||
Copy( y, c, 8 );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/*------------------------------------------------------------*
|
||||
* initialize r and m=2^r based on || y ||^2/8
|
||||
*------------------------------------------------------------*/
|
||||
Ltmp = L_mult(y[0], y[0]);
|
||||
FOR( i = 1; i < 8; i++ )
|
||||
{
|
||||
Ltmp = L_mac( Ltmp, y[i], y[i]);
|
||||
}
|
||||
|
||||
Lsphere = L_shr(Ltmp, 5+1); /* *0.125*0.25 / 2 to remove L_mac effect */
|
||||
|
||||
r = 1;
|
||||
move16();
|
||||
FOR( ; Lsphere > 11; Lsphere >>= 2 )
|
||||
{
|
||||
r = add(r, 1);
|
||||
}
|
||||
/*------------------------------------------------------------*
|
||||
* compute the coordinates of y in the RE8 basis
|
||||
*------------------------------------------------------------*/
|
||||
re8_coord_fx( y, k_mod );
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* compute m and the mask needed for modulo m (for Voronoi coding)
|
||||
*------------------------------------------------------------*/
|
||||
mask = sub(shl(1, r), 1); /* 0x0..011...1 */
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* find the minimal value of r (or equivalently of m) in 2 iterations
|
||||
*------------------------------------------------------------*/
|
||||
|
||||
FOR( iter=0; iter<2; iter++ )
|
||||
{
|
||||
/*--------------------------------------------------------*
|
||||
* compute v such that y is in m RE_8 +v (by Voronoi coding)
|
||||
*--------------------------------------------------------*/
|
||||
FOR( i=0; i<8; i++ )
|
||||
{
|
||||
k_tmp[i] = s_and( k_mod[i], mask);
|
||||
move16();
|
||||
}
|
||||
|
||||
re8_k2y_fx( k_tmp, r, v );
|
||||
|
||||
/*--------------------------------------------------------*
|
||||
* compute c = (y-v)/m
|
||||
* (y is in RE8, c is also in RE8 by definition of v)
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
FOR( i=0; i<8; i++ )
|
||||
{
|
||||
c_tmp[i] = shr(sub(y[i], v[i]), r);
|
||||
move16();
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------*
|
||||
* verify if c_tmp is in Q2, Q3 or Q4
|
||||
*--------------------------------------------------------*/
|
||||
ka_tmp = re8_identify_absolute_leader_fx( c_tmp );
|
||||
|
||||
/*--------------------------------------------------------*
|
||||
* at this stage, n_tmp=2,3,4 or out = 100 -- n=0 is not possible
|
||||
*--------------------------------------------------------*/
|
||||
n_tmp = Da_nq_fx[ka_tmp];
|
||||
move16();
|
||||
|
||||
IF( sub(n_tmp, 4) > 0 )
|
||||
{
|
||||
/*--------------------------------------------------------*
|
||||
* if c is not in Q2, Q3, or Q4 (i.e. n_tmp>4), use m = 2^(r+1) instead of 2^r
|
||||
*--------------------------------------------------------*/
|
||||
r = add(r, 1);
|
||||
mask = add(shl(mask, 1), 1); /* mask = m-1 <- this is less complex */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/*--------------------------------------------------------*
|
||||
* c is in Q2, Q3, or Q4 -> the decomposition of y as y = m c + v is valid
|
||||
*
|
||||
* since Q2 is a subset of Q3, indicate n=3 instead of n=2 (this is because
|
||||
* for n>4, n=n'+2r with n'=3 or 4, so n'=2 is not valid)
|
||||
*--------------------------------------------------------*/
|
||||
n_tmp = s_max(n_tmp, 3);
|
||||
|
||||
/*--------------------------------------------------------*
|
||||
* save current values into ka, n, k and c
|
||||
*--------------------------------------------------------*/
|
||||
*ka = ka_tmp;
|
||||
move16();
|
||||
*n = add(n_tmp, shl(r, 1));
|
||||
move16();
|
||||
Copy( k_tmp, k, 8 );
|
||||
Copy( c_tmp, c, 8 );
|
||||
|
||||
/*--------------------------------------------------------*
|
||||
* try m = 2^(r-1) instead of 2^r to be sure that m is minimal
|
||||
*--------------------------------------------------------*/
|
||||
r = sub(r, 1);
|
||||
mask = shr(mask, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* re8_k2y_fx()
|
||||
*
|
||||
* VORONOI INDEXING (INDEX DECODING) k -> y
|
||||
-------------------------------------------------------------------------*/
|
||||
void re8_k2y_fx(
|
||||
const Word16 *k, /* i : Voronoi index k[0..7] */
|
||||
const Word16 m, /* i : Voronoi modulo (m = 2^r = 1<<r, where r is integer >=2) */
|
||||
Word16 *y /* o : 8-dimensional point y[0..7] in RE8 */
|
||||
)
|
||||
{
|
||||
Word16 i, v[8], *ptr1, *ptr2, m_tmp, mm;
|
||||
Word32 ytp[8], z[8], Ltmp, Lsum ;
|
||||
|
||||
/*---------------------------------------------------------------*
|
||||
* compute y = k M and z=(y-a)/m, where
|
||||
* M = [4 ]
|
||||
* [2 2 ]
|
||||
* [| \ ]
|
||||
* [2 2 ]
|
||||
* [1 1 _ 1 1]
|
||||
* a=(2,0,...,0)
|
||||
*---------------------------------------------------------------*/
|
||||
m_tmp = sub(15, m);
|
||||
|
||||
Lsum = L_deposit_l(k[7]);
|
||||
ytp[7] = Lsum;
|
||||
move32();
|
||||
z[7] = L_shl(Lsum, m_tmp);
|
||||
move32(); /* (int)(floor(y[7]*QR+0.5))>>m */
|
||||
|
||||
FOR( i=6; i>=1; i-- )
|
||||
{
|
||||
Ltmp = L_deposit_l( shl(k[i],1) );
|
||||
Lsum = L_add (Lsum, Ltmp);
|
||||
ytp[i] = L_add(ytp[7], Ltmp);
|
||||
move32();
|
||||
z[i] = L_shl(ytp[i], m_tmp);
|
||||
move32(); /* (int)(floor(y[7]*QR+0.5))>>m */
|
||||
}
|
||||
|
||||
Lsum = L_add( Lsum, L_deposit_l(shl(k[0],2) ));
|
||||
ytp[0] = Lsum;
|
||||
move32();
|
||||
z[0] = L_shl(L_sub(Lsum, 2), m_tmp);
|
||||
move32(); /* (int)(floor(y[7]*QR+0.5))>>m */
|
||||
|
||||
/*---------------------------------------------------------------*
|
||||
* find nearest neighbor v of z in infinite RE8
|
||||
*---------------------------------------------------------------*/
|
||||
re8_PPV_fx( z, v );
|
||||
|
||||
/*---------------------------------------------------------------*
|
||||
* compute y -= m v
|
||||
*---------------------------------------------------------------*/
|
||||
ptr1=y;
|
||||
ptr2=v;
|
||||
|
||||
mm = shr(shl(1, m), 1); /* shr to remove effect of L_mult in L_msu */
|
||||
|
||||
FOR( i=0; i<8; i++ )
|
||||
{
|
||||
Ltmp = L_msu(ytp[i], *ptr2++, mm);
|
||||
*ptr1++ = extract_l(Ltmp);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*
|
||||
* re8_identify_absolute_leader:
|
||||
*
|
||||
* IDENTIFY THE ABSOLUTE LEADER RELATED TO y USING A PRE-DEFINED TABLE WHICH
|
||||
* SPECIFIES THE CODEBOOKS Q0, Q2, Q3 and Q4
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
static Word16 re8_identify_absolute_leader_fx( /* o : integer indicating if y if in Q0, Q2, Q3 or Q4 (or if y is an outlier) */
|
||||
const Word16 y[] /* i : point in RE8 (8-dimensional integer vector) */
|
||||
)
|
||||
{
|
||||
Word16 i,s,id,nb,pos,ka, tmp16;
|
||||
Word32 Ltmp, Ls;
|
||||
Word32 C;
|
||||
const Word16 *ptr;
|
||||
|
||||
/*-----------------------------------------------------------------------*
|
||||
* compute the RE8 shell number s = (y1^2+...+y8^2)/8 and C=(y1^2, ..., y8^2)
|
||||
*-----------------------------------------------------------------------*/
|
||||
Ls = L_mult(y[0], y[0]);
|
||||
FOR( i = 1; i < 8; i++ )
|
||||
{
|
||||
Ls = L_mac( Ls, y[i], y[i]);
|
||||
}
|
||||
s = extract_h(L_shl(Ls, 16-(3+1))); /* s can saturate here */
|
||||
|
||||
/*-----------------------------------------------------------------------*
|
||||
* compute the index 0 <= ka <= NB_LEADER+1 which identifies an absolute leader of Q0, Q2, Q3 or Q4
|
||||
*
|
||||
* by default, ka=index of last element of the table (to indicate an outlier)
|
||||
*-----------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------*
|
||||
* if s=0, y=0 i.e. y is in Q0 -> ka=index of element indicating Q0
|
||||
*-------------------------------------------------------------------*/
|
||||
ka = NB_LEADER;
|
||||
move16();
|
||||
IF( s != 0 )
|
||||
{
|
||||
ka = NB_LEADER+1;
|
||||
move16();
|
||||
/*-------------------------------------------------------------------*
|
||||
* the maximal value of s for y in Q0, Q2, Q3 or Q4 is NB_SPHERE
|
||||
* if s> NB_SPHERE, y is an outlier (the value of ka is set correctly)
|
||||
*-------------------------------------------------------------------*/
|
||||
IF( sub(s, NB_SPHERE) <= 0 )
|
||||
{
|
||||
/*---------------------------------------------------------------*
|
||||
* compute the unique identifier id of the absolute leader related to y:
|
||||
* s = (y1^4 + ... + y8^4)/8
|
||||
*---------------------------------------------------------------*/
|
||||
C = L_mult(y[0], y[0]);
|
||||
tmp16 = extract_h(L_shl(C, 16-1));
|
||||
Ltmp = L_mult(tmp16, tmp16);
|
||||
FOR( i=1; i<8; i++ )
|
||||
{
|
||||
C = L_mult(y[i], y[i]);
|
||||
tmp16 = extract_h(L_shl(C, 16-1));
|
||||
Ltmp = L_mac(Ltmp, tmp16, tmp16);
|
||||
}
|
||||
id = extract_h(L_shl(Ltmp, 16-(3+1))); /* id can saturate to 8192 */
|
||||
|
||||
/*---------------------------------------------------------------*
|
||||
* search for id in table Da_id
|
||||
* (containing all possible values of id if y is in Q2, Q3 or Q4)
|
||||
* this search is focused based on the shell number s so that
|
||||
* only the id's related to the shell of number s are checked
|
||||
*---------------------------------------------------------------*/
|
||||
|
||||
nb = Da_nb_fx[s - 1]; /* get the number of absolute leaders used on the shell of number s */
|
||||
pos = Da_pos_fx[s - 1]; /* get the position of the first absolute leader of shell s in Da_id */
|
||||
move16();
|
||||
move16();
|
||||
|
||||
ptr = &Da_id_fx[pos];
|
||||
move16();
|
||||
FOR( i=0; i<nb; i++ )
|
||||
{
|
||||
IF( sub(id, *ptr) == 0 )
|
||||
{
|
||||
ka = pos;
|
||||
move16(); /* get ka */
|
||||
BREAK;
|
||||
}
|
||||
ptr++;
|
||||
pos = add(pos,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return( ka );
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Re8_coord:
|
||||
*
|
||||
* COMPUTATION OF RE8 COORDINATES
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
static void re8_coord_fx(
|
||||
const Word16 *y, /* i : 8-dimensional point y[0..7] in RE8 */
|
||||
Word16 *k /* o : coordinates k[0..7] */
|
||||
)
|
||||
{
|
||||
Word16 i, tmp, sum;
|
||||
|
||||
/*---------------------------------------------------------------*
|
||||
* compute k = y M^-1
|
||||
* M = 1/4 [ 1 ]
|
||||
* [-1 2 ]
|
||||
* [ | \ ]
|
||||
* [-1 2 ]
|
||||
* [ 5 -2 _ -2 4]
|
||||
*
|
||||
*---------------------------------------------------------------*/
|
||||
k[7] = y[7];
|
||||
move16();
|
||||
tmp = y[7];
|
||||
move16();
|
||||
sum = add(y[7], shl(y[7], 2));
|
||||
|
||||
FOR( i=6; i>=1; i-- )
|
||||
{
|
||||
/* apply factor 2/4 from M^-1 */
|
||||
k[i] = shr(sub(y[i], tmp), 1);
|
||||
move16();
|
||||
sum = sub(sum, y[i]);
|
||||
}
|
||||
/* apply factor 1/4 from M^-1 */
|
||||
k[0]= shr(add(y[0], sum), 2);
|
||||
move16();
|
||||
|
||||
return;
|
||||
}
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* recovernorm_fx()
|
||||
*
|
||||
* Recover reordered quantization indices and norms
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void recovernorm_fx(
|
||||
Word16 *idxbuf, /* i : reordered quantization indices */
|
||||
Word16 *ynrm, /* o : recovered quantization indices */
|
||||
Word16 *normqlg2, /* o : recovered quantized norms */
|
||||
Word16 nb_sfm /* i : number of SFMs */
|
||||
)
|
||||
{
|
||||
Word16 i,j,k;
|
||||
const Word16 *order = NULL;
|
||||
move16();
|
||||
|
||||
SWITCH (nb_sfm)
|
||||
{
|
||||
case NB_SFM:
|
||||
order = norm_order_48;
|
||||
move16();
|
||||
BREAK;
|
||||
case SFM_N_SWB:
|
||||
order = norm_order_32;
|
||||
move16();
|
||||
BREAK;
|
||||
case SFM_N_WB:
|
||||
order = norm_order_16;
|
||||
move16();
|
||||
BREAK;
|
||||
default:
|
||||
order = norm_order_48;
|
||||
move16();
|
||||
BREAK;
|
||||
}
|
||||
|
||||
FOR (i = 0; i < nb_sfm; i++)
|
||||
{
|
||||
j = order[i];
|
||||
move16();
|
||||
k = idxbuf[i];
|
||||
move16();
|
||||
ynrm[j] = k;
|
||||
move16();
|
||||
normqlg2[j] = dicnlg2[k];
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* reordvct()
|
||||
*
|
||||
* Rearrange a vector in decreasing order
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void reordvct_fx(
|
||||
Word16 *y, /* i/o: vector to rearrange */
|
||||
const Word16 N, /* i : dimensions */
|
||||
Word16 *idx /* o : reordered vector index */
|
||||
)
|
||||
{
|
||||
Word16 i, j, k, n, im, temp;
|
||||
|
||||
n = sub(N, 1);
|
||||
move16();
|
||||
FOR (i=0; i<n; i++)
|
||||
{
|
||||
im = i;
|
||||
move16();
|
||||
k = add(i, 1);
|
||||
move16();
|
||||
FOR (j=k; j<N; j++)
|
||||
{
|
||||
if ( sub(y[im], y[j]) < 0 )
|
||||
{
|
||||
im = j;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
temp = y[i];
|
||||
move16();
|
||||
y[i] = y[im];
|
||||
move16();
|
||||
y[im] = temp;
|
||||
move16();
|
||||
j = idx[i];
|
||||
move16();
|
||||
idx[i] = idx[im];
|
||||
move16();
|
||||
idx[im] = j;
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Executable
+228
@@ -0,0 +1,228 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Function prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* Residu3_lc_fx:
|
||||
*
|
||||
* Compute the LP residual by filtering the input speech through A(z)
|
||||
* Output is in Qx
|
||||
*
|
||||
* Optimized Version: Use when Past[0..m-1] is 0 & a[0] is 1 (in Q12)
|
||||
*--------------------------------------------------------------------*/
|
||||
void Residu3_lc_fx(
|
||||
const Word16 a[], /* i : prediction coefficients Q12 */
|
||||
const Word16 m, /* i : order of LP filter Q0 */
|
||||
const Word16 x[], /* i : input signal (usually speech) Qx */
|
||||
Word16 y[], /* o : output signal (usually residual) Qx */
|
||||
const Word16 lg, /* i : vector size Q0 */
|
||||
const Word16 shift
|
||||
)
|
||||
{
|
||||
Word16 i, j;
|
||||
Word32 s;
|
||||
Word16 q;
|
||||
|
||||
q = add( norm_s(a[0]), 1 );
|
||||
if (shift > 0)
|
||||
q = add(q, shift);
|
||||
*y++ = shl(x[0], shift);
|
||||
move16();
|
||||
|
||||
FOR (i = 1; i < m; i++)
|
||||
{
|
||||
s = L_mult(x[i], a[0]);
|
||||
/* Stop at i to Avoid Mults with Zeros */
|
||||
FOR (j = 1; j <= i; j++)
|
||||
{
|
||||
s = L_mac(s, x[i-j], a[j]);
|
||||
}
|
||||
|
||||
s = L_shl(s, q);
|
||||
*y++ = round_fx(s);
|
||||
}
|
||||
|
||||
FOR (; i < lg; i++)
|
||||
{
|
||||
s = L_mult(x[i], a[0]);
|
||||
FOR (j = 1; j <= m; j++)
|
||||
{
|
||||
s = L_mac(s, x[i-j], a[j]);
|
||||
}
|
||||
|
||||
s = L_shl(s, q);
|
||||
*y++ = round_fx(s);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* Residu3_10_fx:
|
||||
*
|
||||
* Compute the LP residual by filtering the input speech through A(z)
|
||||
* Output is in Qx
|
||||
*--------------------------------------------------------------------*/
|
||||
void Residu3_10_fx(
|
||||
const Word16 a[], /* i : prediction coefficients Q12 */
|
||||
const Word16 x[], /* i : input signal (usually speech) Qx */
|
||||
/* (note that values x[-10..-1] are needed) */
|
||||
Word16 y[], /* o : output signal (usually residual) Qx */
|
||||
const Word16 lg, /* i : vector size Q0 */
|
||||
const Word16 shift
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 s;
|
||||
Word16 q;
|
||||
|
||||
q = add( norm_s(a[0]), 1 );
|
||||
if (shift != 0)
|
||||
q = add(q, shift);
|
||||
FOR (i = 0; i < lg; i++)
|
||||
{
|
||||
s = L_mult(x[i], a[0]);
|
||||
s = L_mac(s, x[i-1], a[1]);
|
||||
s = L_mac(s, x[i-2], a[2]);
|
||||
s = L_mac(s, x[i-3], a[3]);
|
||||
s = L_mac(s, x[i-4], a[4]);
|
||||
s = L_mac(s, x[i-5], a[5]);
|
||||
s = L_mac(s, x[i-6], a[6]);
|
||||
s = L_mac(s, x[i-7], a[7]);
|
||||
s = L_mac(s, x[i-8], a[8]);
|
||||
s = L_mac(s, x[i-9], a[9]);
|
||||
s = L_mac(s, x[i-10], a[10]);
|
||||
|
||||
s = L_shl(s, q);
|
||||
y[i] = round_fx(s);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* Residu3_fx:
|
||||
*
|
||||
* Compute the LP residual by filtering the input speech through A(z)
|
||||
* Output is in Qx
|
||||
*--------------------------------------------------------------------*/
|
||||
void Residu3_fx(
|
||||
const Word16 a[], /* i : prediction coefficients Q12 */
|
||||
const Word16 x[], /* i : input signal (usually speech) Qx */
|
||||
/* (note that values x[-M..-1] are needed) */
|
||||
Word16 y[], /* o : output signal (usually residual) Qx */
|
||||
const Word16 lg, /* i : vector size Q0 */
|
||||
const Word16 shift
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 s;
|
||||
Word16 q;
|
||||
|
||||
q = add( norm_s(a[0]), 1 );
|
||||
if (shift != 0)
|
||||
q = add(q, shift);
|
||||
FOR (i = 0; i < lg; i++)
|
||||
{
|
||||
s = L_mult(x[i], a[0]);
|
||||
s = L_mac(s, x[i-1], a[1]);
|
||||
s = L_mac(s, x[i-2], a[2]);
|
||||
s = L_mac(s, x[i-3], a[3]);
|
||||
s = L_mac(s, x[i-4], a[4]);
|
||||
s = L_mac(s, x[i-5], a[5]);
|
||||
s = L_mac(s, x[i-6], a[6]);
|
||||
s = L_mac(s, x[i-7], a[7]);
|
||||
s = L_mac(s, x[i-8], a[8]);
|
||||
s = L_mac(s, x[i-9], a[9]);
|
||||
s = L_mac(s, x[i-10], a[10]);
|
||||
s = L_mac(s, x[i-11], a[11]);
|
||||
s = L_mac(s, x[i-12], a[12]);
|
||||
s = L_mac(s, x[i-13], a[13]);
|
||||
s = L_mac(s, x[i-14], a[14]);
|
||||
s = L_mac(s, x[i-15], a[15]);
|
||||
s = L_mac(s, x[i-16], a[16]);
|
||||
|
||||
s = L_shl(s, q);
|
||||
y[i] = round_fx(s);
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
/* FUNCTION : void calc_residu() */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* PURPOSE : Compute the LP residual by filtering the input through */
|
||||
/* A(z) in all subframes */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* Word16 *speech i : weighted speech signal Qx */
|
||||
/* Word16 L_frame i : order of LP filter Q0 */
|
||||
/* Word16 *p_Aq i : quantized LP filter coefficients Q12 */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* Word16 *res o : residual signal Qx+1 */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* CALLED FROM : */
|
||||
/*==========================================================================*/
|
||||
|
||||
void calc_residu_fx(
|
||||
Encoder_State_fx *st, /* i/o: state structure */
|
||||
const Word16 *speech, /* i : weighted speech signal */
|
||||
Word16 *res, /* o : residual signal */
|
||||
const Word16 *p_Aq, /* i : quantized LP filter coefficients */
|
||||
const Word16 vad_hover_flag
|
||||
)
|
||||
{
|
||||
Word16 i_subfr;
|
||||
Word16 i;
|
||||
Word16 att;
|
||||
Word16 offset;
|
||||
|
||||
FOR( i_subfr = 0; i_subfr < st->L_frame_fx; i_subfr += L_SUBFR )
|
||||
{
|
||||
/* calculate the residual signal */
|
||||
Residu3_fx( p_Aq, &speech[i_subfr], &res[i_subfr], L_SUBFR, 1 );
|
||||
|
||||
/* next subframe */
|
||||
p_Aq += (M+1);
|
||||
}
|
||||
/* smoothing in case of CNG */
|
||||
test();
|
||||
IF( (st->Opt_DTX_ON_fx != 0 ) && (vad_hover_flag != 0) ) /* corresponds to line 504 in FLT acelp_core_enc.c */
|
||||
{
|
||||
st->burst_ho_cnt_fx = add(st->burst_ho_cnt_fx,1);
|
||||
st->burst_ho_cnt_fx = s_min(st->burst_ho_cnt_fx, HO_HIST_SIZE);
|
||||
IF( sub(st->bwidth_fx, NB) != 0)
|
||||
{
|
||||
offset = 5;
|
||||
test();
|
||||
if( sub(st->bwidth_fx, WB) == 0 && st->CNG_mode_fx >= 0 )
|
||||
{
|
||||
offset = st->CNG_mode_fx;
|
||||
move16();
|
||||
}
|
||||
|
||||
att = CNG_burst_att_fx[offset][sub(st->burst_ho_cnt_fx,1)]; /*Q15*/
|
||||
|
||||
FOR( i = 0; i < st->L_frame_fx; i++ )
|
||||
{
|
||||
res[i] = mult_r(res[i], att);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
st->burst_ho_cnt_fx = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Executable
+991
@@ -0,0 +1,991 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "rom_basop_util.h"
|
||||
#include "stl.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "options.h"
|
||||
|
||||
|
||||
/**
|
||||
* \brief Lookup-Table for binary logarithm
|
||||
*/
|
||||
const Word16 ldCoeff[7] =
|
||||
{
|
||||
-32768, -16384, -10923, -8192, -6554, -5461, -4681
|
||||
/* -4096, -3641, -3277 */
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Lookup-Table for binary power algorithm
|
||||
|
||||
This table is used for lookup 2^x with
|
||||
x in range [0...1.0[ in steps of 1/32
|
||||
*/
|
||||
const UWord32 exp2_tab_long[32] =
|
||||
{
|
||||
0x40000000,0x4166C34C,0x42D561B4,0x444C0740,
|
||||
0x45CAE0F2,0x47521CC6,0x48E1E9BA,0x4A7A77D4,
|
||||
0x4C1BF829,0x4DC69CDD,0x4F7A9930,0x51382182,
|
||||
0x52FF6B55,0x54D0AD5A,0x56AC1F75,0x5891FAC1,
|
||||
0x5A82799A,0x5C7DD7A4,0x5E8451D0,0x60962665,
|
||||
0x62B39509,0x64DCDEC3,0x6712460B,0x69540EC9,
|
||||
0x6BA27E65,0x6DFDDBCC,0x70666F76,0x72DC8374,
|
||||
0x75606374,0x77F25CCE,0x7A92BE8B,0x7D41D96E
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Lookup-Table for binary power algorithm
|
||||
|
||||
This table is used for lookup 2^x with
|
||||
x in range [0...1/32[ in steps of 1/1024
|
||||
*/
|
||||
const UWord32 exp2w_tab_long[32] =
|
||||
{
|
||||
0x40000000,0x400B1818,0x4016321B,0x40214E0C,
|
||||
0x402C6BE9,0x40378BB4,0x4042AD6D,0x404DD113,
|
||||
0x4058F6A8,0x40641E2B,0x406F479E,0x407A7300,
|
||||
0x4085A051,0x4090CF92,0x409C00C4,0x40A733E6,
|
||||
0x40B268FA,0x40BD9FFF,0x40C8D8F5,0x40D413DD,
|
||||
0x40DF50B8,0x40EA8F86,0x40F5D046,0x410112FA,
|
||||
0x410C57A2,0x41179E3D,0x4122E6CD,0x412E3152,
|
||||
0x41397DCC,0x4144CC3B,0x41501CA0,0x415B6EFB
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Lookup-Table for binary power algorithm
|
||||
|
||||
This table is used for lookup 2^x with
|
||||
x in range [0...1/1024[ in steps of 1/32768
|
||||
*/
|
||||
const UWord32 exp2x_tab_long[32] =
|
||||
{
|
||||
0x40000000,0x400058B9,0x4000B173,0x40010A2D,
|
||||
0x400162E8,0x4001BBA3,0x4002145F,0x40026D1B,
|
||||
0x4002C5D8,0x40031E95,0x40037752,0x4003D011,
|
||||
0x400428CF,0x4004818E,0x4004DA4E,0x4005330E,
|
||||
0x40058BCE,0x4005E48F,0x40063D51,0x40069613,
|
||||
0x4006EED5,0x40074798,0x4007A05B,0x4007F91F,
|
||||
0x400851E4,0x4008AAA8,0x4009036E,0x40095C33,
|
||||
0x4009B4FA,0x400A0DC0,0x400A6688,0x400ABF4F
|
||||
};
|
||||
|
||||
/* square root tables */
|
||||
const Word32 SqrtTable[32] = /* Q31 */
|
||||
{
|
||||
0x5A82D429, 0x5BEA10FE, 0x5D4BE6E5, 0x5EA89270, 0x60004BE2, 0x615347A1, 0x62A1B68C, 0x63EBC651,
|
||||
0x6531A1B5, 0x667370D4, 0x67B1595F, 0x68EB7EC8, 0x6A220277, 0x6B5503F0, 0x6C84A0F9, 0x6DB0F5BD,
|
||||
0x6EDA1CE9, 0x70002FC7, 0x7123465A, 0x72437773, 0x7360D8C5, 0x747B7EFA, 0x75937DC4, 0x76A8E7EB,
|
||||
0x77BBCF60, 0x78CC4545, 0x79DA5A00, 0x7AE61D3E, 0x7BEF9E07, 0x7CF6EAC2, 0x7DFC113F, 0x7EFF1EC0
|
||||
};
|
||||
|
||||
const Word16 SqrtDiffTable[32] = /* Q21 */
|
||||
{
|
||||
0x59CF, 0x5875, 0x572B, 0x55EE, 0x54BF, 0x539C, 0x5284, 0x5177,
|
||||
0x5074, 0x4F7A, 0x4E89, 0x4DA1, 0x4CC0, 0x4BE7, 0x4B15, 0x4A4A,
|
||||
0x4985, 0x48C6, 0x480C, 0x4758, 0x46AA, 0x4600, 0x455B, 0x44BA,
|
||||
0x441D, 0x4385, 0x42F1, 0x4260, 0x41D3, 0x414A, 0x40C3, 0x4040
|
||||
};
|
||||
|
||||
|
||||
const Word32 ISqrtTable[32] = /* Q31 */
|
||||
{
|
||||
0x7FFE7F85, 0x7E0A4E25, 0x7C2C56C7, 0x7A63002C, 0x78ACD922, 0x7708939D, 0x75750088, 0x73F10C2D,
|
||||
0x727BBB1A, 0x71142774, 0x6FB97EA5, 0x6E6AFF54, 0x6D27F79D, 0x6BEFC388, 0x6AC1CBA4, 0x699D83DA,
|
||||
0x68826A53, 0x6770068E, 0x6665E882, 0x6563A7DF, 0x6468E364, 0x63754043, 0x62886999, 0x61A20FEE,
|
||||
0x60C1E8C8, 0x5FE7AE45, 0x5F131EBE, 0x5E43FC76, 0x5D7A0D4F, 0x5CB51A81, 0x5BF4F061, 0x5B395E26
|
||||
};
|
||||
|
||||
const Word16 ISqrtDiffTable[32] = /* Q21 */
|
||||
{
|
||||
0x7D0C, 0x777E, 0x7256, 0x6D8A, 0x6911, 0x64E5, 0x60FD, 0x5D54,
|
||||
0x59E5, 0x56AA, 0x53A0, 0x50C2, 0x4E0D, 0x4B7E, 0x4912, 0x46C6,
|
||||
0x4499, 0x4288, 0x4090, 0x3EB1, 0x3CE9, 0x3B36, 0x3996, 0x380A,
|
||||
0x368F, 0x3524, 0x33C9, 0x327C, 0x313D, 0x300B, 0x2EE5, 0x2DCA
|
||||
};
|
||||
|
||||
/* 1/x tables */
|
||||
const Word32 InvTable[32] = /* Q31 */
|
||||
{
|
||||
0x7FFBFE40, 0x7C1B608E, 0x78752176, 0x750440BA, 0x71C44C49, 0x6EB14D0A, 0x6BC7B6B4, 0x69045A19,
|
||||
0x6664598A, 0x63E51EE2, 0x61845308, 0x5F3FD698, 0x5D15BB8E, 0x5B043FD0, 0x5909C861, 0x5724DD3C,
|
||||
0x555425B2, 0x53966532, 0x51EA787F, 0x504F5331, 0x4EC3FD84, 0x4D479267, 0x4BD93DBE, 0x4A783ADC,
|
||||
0x4923D31D, 0x47DB5CAE, 0x469E3974, 0x456BD608, 0x4443A8D9, 0x43253159, 0x420FF746, 0x41038A01
|
||||
};
|
||||
|
||||
/* inverse integer (1/i) */
|
||||
const Word16 InvIntTable[65] =
|
||||
{
|
||||
0x7FFF,
|
||||
0x7FFF, 0x4000, 0x2AAB, 0x2000, 0x199A, 0x1555, 0x1249, 0x1000,
|
||||
0x0E39, 0x0CCD, 0x0BA3, 0x0AAB, 0x09D9, 0x0925, 0x0889, 0x0800,
|
||||
0x0788, 0x071C, 0x06BD, 0x0666, 0x0618, 0x05D1, 0x0591, 0x0555,
|
||||
0x051F, 0x04EC, 0x04BE, 0x0492, 0x046A, 0x0444, 0x0421, 0x0400,
|
||||
0x03E1, 0x03C4, 0x03A8, 0x038E, 0x0376, 0x035E, 0x0348, 0x0333,
|
||||
0x031F, 0x030C, 0x02FA, 0x02E9, 0x02D8, 0x02C8, 0x02B9, 0x02AB,
|
||||
0x029D, 0x028F, 0x0283, 0x0276, 0x026A, 0x025F, 0x0254, 0x0249,
|
||||
0x023F, 0x0235, 0x022B, 0x0222, 0x0219, 0x0211, 0x0208, 0x0200
|
||||
};
|
||||
|
||||
const Word16 InvDiffTable[32] = /* Q20 */
|
||||
{
|
||||
0x7C14, 0x74C8, 0x6E1C, 0x67FF, 0x6260, 0x5D33, 0x586C, 0x5400,
|
||||
0x4FE7, 0x4C19, 0x4890, 0x4543, 0x422F, 0x3F4F, 0x3C9D, 0x3A17,
|
||||
0x37B8, 0x357E, 0x3365, 0x316B, 0x2F8D, 0x2DCB, 0x2C20, 0x2A8D,
|
||||
0x290F, 0x27A4, 0x264C, 0x2506, 0x23CF, 0x22A7, 0x218E, 0x2081
|
||||
};
|
||||
|
||||
const Word32 BASOP_util_normReciprocal[CHEAP_NORM_SIZE] =
|
||||
{
|
||||
0l/*0.0 Q31*/, 2147483647l/*1.0000000000 Q31*/, 1073741824l/*0.5000000000 Q31*/, 715827883l/*0.3333333333 Q31*/, 536870912l/*0.2500000000 Q31*/, 429496730l/*0.2000000000 Q31*/,
|
||||
357913941l/*0.1666666667 Q31*/, 306783378l/*0.1428571429 Q31*/, 268435456l/*0.1250000000 Q31*/, 238609294l/*0.1111111111 Q31*/, 214748365l/*0.1000000000 Q31*/, 195225786l/*0.0909090909 Q31*/,
|
||||
178956971l/*0.0833333333 Q31*/, 165191050l/*0.0769230769 Q31*/, 153391689l/*0.0714285714 Q31*/, 143165577l/*0.0666666667 Q31*/, 134217728l/*0.0625000000 Q31*/, 126322568l/*0.0588235294 Q31*/,
|
||||
119304647l/*0.0555555556 Q31*/, 113025455l/*0.0526315789 Q31*/, 107374182l/*0.0500000000 Q31*/, 102261126l/*0.0476190476 Q31*/, 97612893l/*0.0454545455 Q31*/, 93368854l/*0.0434782609 Q31*/,
|
||||
89478485l/*0.0416666667 Q31*/, 85899346l/*0.0400000000 Q31*/, 82595525l/*0.0384615385 Q31*/, 79536431l/*0.0370370370 Q31*/, 76695845l/*0.0357142857 Q31*/, 74051160l/*0.0344827586 Q31*/,
|
||||
71582788l/*0.0333333333 Q31*/, 69273666l/*0.0322580645 Q31*/, 67108864l/*0.0312500000 Q31*/, 65075262l/*0.0303030303 Q31*/, 63161284l/*0.0294117647 Q31*/, 61356676l/*0.0285714286 Q31*/,
|
||||
59652324l/*0.0277777778 Q31*/, 58040099l/*0.0270270270 Q31*/, 56512728l/*0.0263157895 Q31*/, 55063683l/*0.0256410256 Q31*/, 53687091l/*0.0250000000 Q31*/, 52377650l/*0.0243902439 Q31*/,
|
||||
51130563l/*0.0238095238 Q31*/, 49941480l/*0.0232558140 Q31*/, 48806446l/*0.0227272727 Q31*/, 47721859l/*0.0222222222 Q31*/, 46684427l/*0.0217391304 Q31*/, 45691141l/*0.0212765957 Q31*/,
|
||||
44739243l/*0.0208333333 Q31*/, 43826197l/*0.0204081633 Q31*/, 42949673l/*0.0200000000 Q31*/, 42107522l/*0.0196078431 Q31*/, 41297762l/*0.0192307692 Q31*/, 40518559l/*0.0188679245 Q31*/,
|
||||
39768216l/*0.0185185185 Q31*/, 39045157l/*0.0181818182 Q31*/, 38347922l/*0.0178571429 Q31*/, 37675152l/*0.0175438596 Q31*/, 37025580l/*0.0172413793 Q31*/, 36398028l/*0.0169491525 Q31*/,
|
||||
35791394l/*0.0166666667 Q31*/, 35204650l/*0.0163934426 Q31*/, 34636833l/*0.0161290323 Q31*/, 34087042l/*0.0158730159 Q31*/, 33554432l/*0.0156250000 Q31*/, 33038210l/*0.0153846154 Q31*/,
|
||||
32537631l/*0.0151515152 Q31*/, 32051995l/*0.0149253731 Q31*/, 31580642l/*0.0147058824 Q31*/, 31122951l/*0.0144927536 Q31*/, 30678338l/*0.0142857143 Q31*/, 30246248l/*0.0140845070 Q31*/,
|
||||
29826162l/*0.0138888889 Q31*/, 29417584l/*0.0136986301 Q31*/, 29020049l/*0.0135135135 Q31*/, 28633115l/*0.0133333333 Q31*/, 28256364l/*0.0131578947 Q31*/, 27889398l/*0.0129870130 Q31*/,
|
||||
27531842l/*0.0128205128 Q31*/, 27183337l/*0.0126582278 Q31*/, 26843546l/*0.0125000000 Q31*/, 26512144l/*0.0123456790 Q31*/, 26188825l/*0.0121951220 Q31*/, 25873297l/*0.0120481928 Q31*/,
|
||||
25565282l/*0.0119047619 Q31*/, 25264514l/*0.0117647059 Q31*/, 24970740l/*0.0116279070 Q31*/, 24683720l/*0.0114942529 Q31*/, 24403223l/*0.0113636364 Q31*/, 24129030l/*0.0112359551 Q31*/,
|
||||
23860929l/*0.0111111111 Q31*/, 23598721l/*0.0109890110 Q31*/, 23342214l/*0.0108695652 Q31*/, 23091222l/*0.0107526882 Q31*/, 22845571l/*0.0106382979 Q31*/, 22605091l/*0.0105263158 Q31*/,
|
||||
22369621l/*0.0104166667 Q31*/, 22139007l/*0.0103092784 Q31*/, 21913098l/*0.0102040816 Q31*/, 21691754l/*0.0101010101 Q31*/, 21474836l/*0.0100000000 Q31*/, 21262214l/*0.0099009901 Q31*/,
|
||||
21053761l/*0.0098039216 Q31*/, 20849356l/*0.0097087379 Q31*/, 20648881l/*0.0096153846 Q31*/, 20452225l/*0.0095238095 Q31*/, 20259280l/*0.0094339623 Q31*/, 20069941l/*0.0093457944 Q31*/,
|
||||
19884108l/*0.0092592593 Q31*/, 19701685l/*0.0091743119 Q31*/, 19522579l/*0.0090909091 Q31*/, 19346700l/*0.0090090090 Q31*/, 19173961l/*0.0089285714 Q31*/, 19004280l/*0.0088495575 Q31*/,
|
||||
18837576l/*0.0087719298 Q31*/, 18673771l/*0.0086956522 Q31*/, 18512790l/*0.0086206897 Q31*/, 18354561l/*0.0085470085 Q31*/, 18199014l/*0.0084745763 Q31*/, 18046081l/*0.0084033613 Q31*/,
|
||||
17895697l/*0.0083333333 Q31*/, 17747799l/*0.0082644628 Q31*/, 17602325l/*0.0081967213 Q31*/, 17459217l/*0.0081300813 Q31*/, 17318416l/*0.0080645161 Q31*/, 17179869l/*0.0080000000 Q31*/,
|
||||
17043521l/*0.0079365079 Q31*/, 16909320l/*0.0078740157 Q31*/, 16777216l/*0.0078125000 Q31*/, 16647160l/*0.0077519380 Q31*/, 16519105l/*0.0076923077 Q31*/, 16393005l/*0.0076335878 Q31*/,
|
||||
16268816l/*0.0075757576 Q31*/, 16146494l/*0.0075187970 Q31*/, 16025997l/*0.0074626866 Q31*/, 15907286l/*0.0074074074 Q31*/, 15790321l/*0.0073529412 Q31*/, 15675063l/*0.0072992701 Q31*/,
|
||||
15561476l/*0.0072463768 Q31*/, 15449523l/*0.0071942446 Q31*/, 15339169l/*0.0071428571 Q31*/, 15230381l/*0.0070921986 Q31*/, 15123124l/*0.0070422535 Q31*/, 15017368l/*0.0069930070 Q31*/,
|
||||
14913081l/*0.0069444444 Q31*/, 14810232l/*0.0068965517 Q31*/, 14708792l/*0.0068493151 Q31*/, 14608732l/*0.0068027211 Q31*/, 14510025l/*0.0067567568 Q31*/, 14412642l/*0.0067114094 Q31*/,
|
||||
14316558l/*0.0066666667 Q31*/, 14221746l/*0.0066225166 Q31*/, 14128182l/*0.0065789474 Q31*/, 14035841l/*0.0065359477 Q31*/, 13944699l/*0.0064935065 Q31*/, 13854733l/*0.0064516129 Q31*/,
|
||||
13765921l/*0.0064102564 Q31*/, 13678240l/*0.0063694268 Q31*/, 13591669l/*0.0063291139 Q31*/, 13506187l/*0.0062893082 Q31*/, 13421773l/*0.0062500000 Q31*/
|
||||
};
|
||||
|
||||
const Word16 f_atan_expand_range[MAXSFTAB-(MINSFTAB-1)] =
|
||||
{
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Table holds fixp_atan() output values which are outside of input range
|
||||
* of fixp_atan() to improve SNR of fixp_atan2().
|
||||
*
|
||||
* This Table might also be used in fixp_atan() [todo] so there a wider input
|
||||
* range can be covered, too.
|
||||
*
|
||||
* Matlab (generate table):
|
||||
* for scl = 7:25 % MINSFTAB .. MAXSFTAB
|
||||
* at=atan(0.5 *(2^scl)); % 0.5 because get in 'middle' area of current scale level 'scl'
|
||||
* at/2 % div at by ATO_SCALE
|
||||
* end
|
||||
*
|
||||
* Table divided by 2=ATO_SCALE <-- SF=ATO_SF
|
||||
*****************************************************************************/
|
||||
25480/*7.775862990872099e-001 Q15*/, 25608/*7.814919928673978e-001 Q15*/, 25672/*7.834450483314648e-001 Q15*/,
|
||||
25704/*7.844216021392089e-001 Q15*/, 25720/*7.849098823026687e-001 Q15*/, 25728/*7.851540227918509e-001 Q15*/,
|
||||
25732/*7.852760930873737e-001 Q15*/, 25734/*7.853371282415015e-001 Q15*/, 25735/*7.853676458193612e-001 Q15*/,
|
||||
25735/*7.853829046083906e-001 Q15*/, 25736/*7.853905340029177e-001 Q15*/, 25736/*7.853943487001828e-001 Q15*/,
|
||||
25736/*7.853962560488155e-001 Q15*/, 25736/*7.853972097231319e-001 Q15*/, 25736/*7.853976865602901e-001 Q15*/,
|
||||
25736/*7.853979249788692e-001 Q15*/, 25736/*7.853980441881587e-001 Q15*/, 25736/*7.853981037928035e-001 Q15*/,
|
||||
25736/*7.853981335951259e-001 Q15*/
|
||||
/* pi/4 = 0.785398163397448 = pi/2/ATO_SCALE */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Sine tables
|
||||
*/
|
||||
#define STC(x) WORD322WORD16(x)
|
||||
|
||||
/* #define STCP(a,b) (((Word32)STC(b)<<16) | STC(a)) */
|
||||
#define STCP(a,b) { { STC(a), STC(b) } }
|
||||
|
||||
const PWord16 SineTable512[] =
|
||||
{
|
||||
STCP(0x7fffffff, 0x00000000), STCP(0x7fffd886, 0x006487e3), STCP(0x7fff6216, 0x00c90f88), STCP(0x7ffe9cb2, 0x012d96b1),
|
||||
STCP(0x7ffd885a, 0x01921d20), STCP(0x7ffc250f, 0x01f6a297), STCP(0x7ffa72d1, 0x025b26d7), STCP(0x7ff871a2, 0x02bfa9a4),
|
||||
STCP(0x7ff62182, 0x03242abf), STCP(0x7ff38274, 0x0388a9ea), STCP(0x7ff09478, 0x03ed26e6), STCP(0x7fed5791, 0x0451a177),
|
||||
STCP(0x7fe9cbc0, 0x04b6195d), STCP(0x7fe5f108, 0x051a8e5c), STCP(0x7fe1c76b, 0x057f0035), STCP(0x7fdd4eec, 0x05e36ea9),
|
||||
STCP(0x7fd8878e, 0x0647d97c), STCP(0x7fd37153, 0x06ac406f), STCP(0x7fce0c3e, 0x0710a345), STCP(0x7fc85854, 0x077501be),
|
||||
STCP(0x7fc25596, 0x07d95b9e), STCP(0x7fbc040a, 0x083db0a7), STCP(0x7fb563b3, 0x08a2009a), STCP(0x7fae7495, 0x09064b3a),
|
||||
STCP(0x7fa736b4, 0x096a9049), STCP(0x7f9faa15, 0x09cecf89), STCP(0x7f97cebd, 0x0a3308bd), STCP(0x7f8fa4b0, 0x0a973ba5),
|
||||
STCP(0x7f872bf3, 0x0afb6805), STCP(0x7f7e648c, 0x0b5f8d9f), STCP(0x7f754e80, 0x0bc3ac35), STCP(0x7f6be9d4, 0x0c27c389),
|
||||
STCP(0x7f62368f, 0x0c8bd35e), STCP(0x7f5834b7, 0x0cefdb76), STCP(0x7f4de451, 0x0d53db92), STCP(0x7f434563, 0x0db7d376),
|
||||
STCP(0x7f3857f6, 0x0e1bc2e4), STCP(0x7f2d1c0e, 0x0e7fa99e), STCP(0x7f2191b4, 0x0ee38766), STCP(0x7f15b8ee, 0x0f475bff),
|
||||
STCP(0x7f0991c4, 0x0fab272b), STCP(0x7efd1c3c, 0x100ee8ad), STCP(0x7ef05860, 0x1072a048), STCP(0x7ee34636, 0x10d64dbd),
|
||||
STCP(0x7ed5e5c6, 0x1139f0cf), STCP(0x7ec8371a, 0x119d8941), STCP(0x7eba3a39, 0x120116d5), STCP(0x7eabef2c, 0x1264994e),
|
||||
STCP(0x7e9d55fc, 0x12c8106f), STCP(0x7e8e6eb2, 0x132b7bf9), STCP(0x7e7f3957, 0x138edbb1), STCP(0x7e6fb5f4, 0x13f22f58),
|
||||
STCP(0x7e5fe493, 0x145576b1), STCP(0x7e4fc53e, 0x14b8b17f), STCP(0x7e3f57ff, 0x151bdf86), STCP(0x7e2e9cdf, 0x157f0086),
|
||||
STCP(0x7e1d93ea, 0x15e21445), STCP(0x7e0c3d29, 0x16451a83), STCP(0x7dfa98a8, 0x16a81305), STCP(0x7de8a670, 0x170afd8d),
|
||||
STCP(0x7dd6668f, 0x176dd9de), STCP(0x7dc3d90d, 0x17d0a7bc), STCP(0x7db0fdf8, 0x183366e9), STCP(0x7d9dd55a, 0x18961728),
|
||||
STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d769bb5, 0x195b49ea), STCP(0x7d628ac6, 0x19bdcbf3), STCP(0x7d4e2c7f, 0x1a203e1b),
|
||||
STCP(0x7d3980ec, 0x1a82a026), STCP(0x7d24881b, 0x1ae4f1d6), STCP(0x7d0f4218, 0x1b4732ef), STCP(0x7cf9aef0, 0x1ba96335),
|
||||
STCP(0x7ce3ceb2, 0x1c0b826a), STCP(0x7ccda169, 0x1c6d9053), STCP(0x7cb72724, 0x1ccf8cb3), STCP(0x7ca05ff1, 0x1d31774d),
|
||||
STCP(0x7c894bde, 0x1d934fe5), STCP(0x7c71eaf9, 0x1df5163f), STCP(0x7c5a3d50, 0x1e56ca1e), STCP(0x7c4242f2, 0x1eb86b46),
|
||||
STCP(0x7c29fbee, 0x1f19f97b), STCP(0x7c116853, 0x1f7b7481), STCP(0x7bf88830, 0x1fdcdc1b), STCP(0x7bdf5b94, 0x203e300d),
|
||||
STCP(0x7bc5e290, 0x209f701c), STCP(0x7bac1d31, 0x21009c0c), STCP(0x7b920b89, 0x2161b3a0), STCP(0x7b77ada8, 0x21c2b69c),
|
||||
STCP(0x7b5d039e, 0x2223a4c5), STCP(0x7b420d7a, 0x22847de0), STCP(0x7b26cb4f, 0x22e541af), STCP(0x7b0b3d2c, 0x2345eff8),
|
||||
STCP(0x7aef6323, 0x23a6887f), STCP(0x7ad33d45, 0x24070b08), STCP(0x7ab6cba4, 0x24677758), STCP(0x7a9a0e50, 0x24c7cd33),
|
||||
STCP(0x7a7d055b, 0x25280c5e), STCP(0x7a5fb0d8, 0x2588349d), STCP(0x7a4210d8, 0x25e845b6), STCP(0x7a24256f, 0x26483f6c),
|
||||
STCP(0x7a05eead, 0x26a82186), STCP(0x79e76ca7, 0x2707ebc7), STCP(0x79c89f6e, 0x27679df4), STCP(0x79a98715, 0x27c737d3),
|
||||
STCP(0x798a23b1, 0x2826b928), STCP(0x796a7554, 0x288621b9), STCP(0x794a7c12, 0x28e5714b), STCP(0x792a37fe, 0x2944a7a2),
|
||||
STCP(0x7909a92d, 0x29a3c485), STCP(0x78e8cfb2, 0x2a02c7b8), STCP(0x78c7aba2, 0x2a61b101), STCP(0x78a63d11, 0x2ac08026),
|
||||
STCP(0x78848414, 0x2b1f34eb), STCP(0x786280bf, 0x2b7dcf17), STCP(0x78403329, 0x2bdc4e6f), STCP(0x781d9b65, 0x2c3ab2b9),
|
||||
STCP(0x77fab989, 0x2c98fbba), STCP(0x77d78daa, 0x2cf72939), STCP(0x77b417df, 0x2d553afc), STCP(0x7790583e, 0x2db330c7),
|
||||
STCP(0x776c4edb, 0x2e110a62), STCP(0x7747fbce, 0x2e6ec792), STCP(0x77235f2d, 0x2ecc681e), STCP(0x76fe790e, 0x2f29ebcc),
|
||||
STCP(0x76d94989, 0x2f875262), STCP(0x76b3d0b4, 0x2fe49ba7), STCP(0x768e0ea6, 0x3041c761), STCP(0x76680376, 0x309ed556),
|
||||
STCP(0x7641af3d, 0x30fbc54d), STCP(0x761b1211, 0x3158970e), STCP(0x75f42c0b, 0x31b54a5e), STCP(0x75ccfd42, 0x3211df04),
|
||||
STCP(0x75a585cf, 0x326e54c7), STCP(0x757dc5ca, 0x32caab6f), STCP(0x7555bd4c, 0x3326e2c3), STCP(0x752d6c6c, 0x3382fa88),
|
||||
STCP(0x7504d345, 0x33def287), STCP(0x74dbf1ef, 0x343aca87), STCP(0x74b2c884, 0x34968250), STCP(0x7489571c, 0x34f219a8),
|
||||
STCP(0x745f9dd1, 0x354d9057), STCP(0x74359cbd, 0x35a8e625), STCP(0x740b53fb, 0x36041ad9), STCP(0x73e0c3a3, 0x365f2e3b),
|
||||
STCP(0x73b5ebd1, 0x36ba2014), STCP(0x738acc9e, 0x3714f02a), STCP(0x735f6626, 0x376f9e46), STCP(0x7333b883, 0x37ca2a30),
|
||||
STCP(0x7307c3d0, 0x382493b0), STCP(0x72db8828, 0x387eda8e), STCP(0x72af05a7, 0x38d8fe93), STCP(0x72823c67, 0x3932ff87),
|
||||
STCP(0x72552c85, 0x398cdd32), STCP(0x7227d61c, 0x39e6975e), STCP(0x71fa3949, 0x3a402dd2), STCP(0x71cc5626, 0x3a99a057),
|
||||
STCP(0x719e2cd2, 0x3af2eeb7), STCP(0x716fbd68, 0x3b4c18ba), STCP(0x71410805, 0x3ba51e29), STCP(0x71120cc5, 0x3bfdfecd),
|
||||
STCP(0x70e2cbc6, 0x3c56ba70), STCP(0x70b34525, 0x3caf50da), STCP(0x708378ff, 0x3d07c1d6), STCP(0x70536771, 0x3d600d2c),
|
||||
STCP(0x7023109a, 0x3db832a6), STCP(0x6ff27497, 0x3e10320d), STCP(0x6fc19385, 0x3e680b2c), STCP(0x6f906d84, 0x3ebfbdcd),
|
||||
STCP(0x6f5f02b2, 0x3f1749b8), STCP(0x6f2d532c, 0x3f6eaeb8), STCP(0x6efb5f12, 0x3fc5ec98), STCP(0x6ec92683, 0x401d0321),
|
||||
STCP(0x6e96a99d, 0x4073f21d), STCP(0x6e63e87f, 0x40cab958), STCP(0x6e30e34a, 0x4121589b), STCP(0x6dfd9a1c, 0x4177cfb1),
|
||||
STCP(0x6dca0d14, 0x41ce1e65), STCP(0x6d963c54, 0x42244481), STCP(0x6d6227fa, 0x427a41d0), STCP(0x6d2dd027, 0x42d0161e),
|
||||
STCP(0x6cf934fc, 0x4325c135), STCP(0x6cc45698, 0x437b42e1), STCP(0x6c8f351c, 0x43d09aed), STCP(0x6c59d0a9, 0x4425c923),
|
||||
STCP(0x6c242960, 0x447acd50), STCP(0x6bee3f62, 0x44cfa740), STCP(0x6bb812d1, 0x452456bd), STCP(0x6b81a3cd, 0x4578db93),
|
||||
STCP(0x6b4af279, 0x45cd358f), STCP(0x6b13fef5, 0x4621647d), STCP(0x6adcc964, 0x46756828), STCP(0x6aa551e9, 0x46c9405c),
|
||||
STCP(0x6a6d98a4, 0x471cece7), STCP(0x6a359db9, 0x47706d93), STCP(0x69fd614a, 0x47c3c22f), STCP(0x69c4e37a, 0x4816ea86),
|
||||
STCP(0x698c246c, 0x4869e665), STCP(0x69532442, 0x48bcb599), STCP(0x6919e320, 0x490f57ee), STCP(0x68e06129, 0x4961cd33),
|
||||
STCP(0x68a69e81, 0x49b41533), STCP(0x686c9b4b, 0x4a062fbd), STCP(0x683257ab, 0x4a581c9e), STCP(0x67f7d3c5, 0x4aa9dba2),
|
||||
STCP(0x67bd0fbd, 0x4afb6c98), STCP(0x67820bb7, 0x4b4ccf4d), STCP(0x6746c7d8, 0x4b9e0390), STCP(0x670b4444, 0x4bef092d),
|
||||
STCP(0x66cf8120, 0x4c3fdff4), STCP(0x66937e91, 0x4c9087b1), STCP(0x66573cbb, 0x4ce10034), STCP(0x661abbc5, 0x4d31494b),
|
||||
STCP(0x65ddfbd3, 0x4d8162c4), STCP(0x65a0fd0b, 0x4dd14c6e), STCP(0x6563bf92, 0x4e210617), STCP(0x6526438f, 0x4e708f8f),
|
||||
STCP(0x64e88926, 0x4ebfe8a5), STCP(0x64aa907f, 0x4f0f1126), STCP(0x646c59bf, 0x4f5e08e3), STCP(0x642de50d, 0x4faccfab),
|
||||
STCP(0x63ef3290, 0x4ffb654d), STCP(0x63b0426d, 0x5049c999), STCP(0x637114cc, 0x5097fc5e), STCP(0x6331a9d4, 0x50e5fd6d),
|
||||
STCP(0x62f201ac, 0x5133cc94), STCP(0x62b21c7b, 0x518169a5), STCP(0x6271fa69, 0x51ced46e), STCP(0x62319b9d, 0x521c0cc2),
|
||||
STCP(0x61f1003f, 0x5269126e), STCP(0x61b02876, 0x52b5e546), STCP(0x616f146c, 0x53028518), STCP(0x612dc447, 0x534ef1b5),
|
||||
STCP(0x60ec3830, 0x539b2af0), STCP(0x60aa7050, 0x53e73097), STCP(0x60686ccf, 0x5433027d), STCP(0x60262dd6, 0x547ea073),
|
||||
STCP(0x5fe3b38d, 0x54ca0a4b), STCP(0x5fa0fe1f, 0x55153fd4), STCP(0x5f5e0db3, 0x556040e2), STCP(0x5f1ae274, 0x55ab0d46),
|
||||
STCP(0x5ed77c8a, 0x55f5a4d2), STCP(0x5e93dc1f, 0x56400758), STCP(0x5e50015d, 0x568a34a9), STCP(0x5e0bec6e, 0x56d42c99),
|
||||
STCP(0x5dc79d7c, 0x571deefa), STCP(0x5d8314b1, 0x57677b9d), STCP(0x5d3e5237, 0x57b0d256), STCP(0x5cf95638, 0x57f9f2f8),
|
||||
STCP(0x5cb420e0, 0x5842dd54), STCP(0x5c6eb258, 0x588b9140), STCP(0x5c290acc, 0x58d40e8c), STCP(0x5be32a67, 0x591c550e),
|
||||
STCP(0x5b9d1154, 0x59646498), STCP(0x5b56bfbd, 0x59ac3cfd), STCP(0x5b1035cf, 0x59f3de12), STCP(0x5ac973b5, 0x5a3b47ab),
|
||||
STCP(0x5a82799a, 0x5a82799a),
|
||||
};
|
||||
|
||||
const PWord16 SineTable320[] =
|
||||
{
|
||||
STCP(0x7fffffff, 0x00000000), STCP(0x7fff9aef, 0x00a0d951),
|
||||
STCP(0x7ffe6bbf, 0x0141b1a5), STCP(0x7ffc726f, 0x01e287fc),
|
||||
STCP(0x7ff9af04, 0x02835b5a), STCP(0x7ff62182, 0x03242abf),
|
||||
STCP(0x7ff1c9ef, 0x03c4f52f), STCP(0x7feca851, 0x0465b9aa),
|
||||
STCP(0x7fe6bcb0, 0x05067734), STCP(0x7fe00716, 0x05a72ccf),
|
||||
STCP(0x7fd8878e, 0x0647d97c), STCP(0x7fd03e23, 0x06e87c3f),
|
||||
STCP(0x7fc72ae2, 0x07891418), STCP(0x7fbd4dda, 0x0829a00c),
|
||||
STCP(0x7fb2a71b, 0x08ca1f1b), STCP(0x7fa736b4, 0x096a9049),
|
||||
STCP(0x7f9afcb9, 0x0a0af299), STCP(0x7f8df93c, 0x0aab450d),
|
||||
STCP(0x7f802c52, 0x0b4b86a8), STCP(0x7f719611, 0x0bebb66c),
|
||||
STCP(0x7f62368f, 0x0c8bd35e), STCP(0x7f520de6, 0x0d2bdc80),
|
||||
STCP(0x7f411c2f, 0x0dcbd0d5), STCP(0x7f2f6183, 0x0e6baf61),
|
||||
STCP(0x7f1cde01, 0x0f0b7727), STCP(0x7f0991c4, 0x0fab272b),
|
||||
STCP(0x7ef57cea, 0x104abe71), STCP(0x7ee09f95, 0x10ea3bfd),
|
||||
STCP(0x7ecaf9e5, 0x11899ed3), STCP(0x7eb48bfb, 0x1228e5f8),
|
||||
STCP(0x7e9d55fc, 0x12c8106f), STCP(0x7e85580c, 0x13671d3d),
|
||||
STCP(0x7e6c9251, 0x14060b68), STCP(0x7e5304f2, 0x14a4d9f4),
|
||||
STCP(0x7e38b017, 0x154387e6), STCP(0x7e1d93ea, 0x15e21445),
|
||||
STCP(0x7e01b096, 0x16807e15), STCP(0x7de50646, 0x171ec45c),
|
||||
STCP(0x7dc79529, 0x17bce621), STCP(0x7da95d6c, 0x185ae269),
|
||||
STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d6a9ad5, 0x199666a0),
|
||||
STCP(0x7d4a105d, 0x1a33ec9c), STCP(0x7d28c00c, 0x1ad14938),
|
||||
STCP(0x7d06aa16, 0x1b6e7b7a), STCP(0x7ce3ceb2, 0x1c0b826a),
|
||||
STCP(0x7cc02e15, 0x1ca85d12), STCP(0x7c9bc87a, 0x1d450a78),
|
||||
STCP(0x7c769e18, 0x1de189a6), STCP(0x7c50af2b, 0x1e7dd9a4),
|
||||
STCP(0x7c29fbee, 0x1f19f97b), STCP(0x7c02849f, 0x1fb5e836),
|
||||
STCP(0x7bda497d, 0x2051a4dd), STCP(0x7bb14ac5, 0x20ed2e7b),
|
||||
STCP(0x7b8788ba, 0x2188841a), STCP(0x7b5d039e, 0x2223a4c5),
|
||||
STCP(0x7b31bbb2, 0x22be8f87), STCP(0x7b05b13d, 0x2359436c),
|
||||
STCP(0x7ad8e482, 0x23f3bf7e), STCP(0x7aab55ca, 0x248e02cb),
|
||||
STCP(0x7a7d055b, 0x25280c5e), STCP(0x7a4df380, 0x25c1db44),
|
||||
STCP(0x7a1e2082, 0x265b6e8a), STCP(0x79ed8cad, 0x26f4c53e),
|
||||
STCP(0x79bc384d, 0x278dde6e), STCP(0x798a23b1, 0x2826b928),
|
||||
STCP(0x79574f28, 0x28bf547b), STCP(0x7923bb01, 0x2957af74),
|
||||
STCP(0x78ef678f, 0x29efc925), STCP(0x78ba5524, 0x2a87a09d),
|
||||
STCP(0x78848414, 0x2b1f34eb), STCP(0x784df4b3, 0x2bb68522),
|
||||
STCP(0x7816a759, 0x2c4d9050), STCP(0x77de9c5b, 0x2ce45589),
|
||||
STCP(0x77a5d413, 0x2d7ad3de), STCP(0x776c4edb, 0x2e110a62),
|
||||
STCP(0x77320d0d, 0x2ea6f827), STCP(0x76f70f05, 0x2f3c9c40),
|
||||
STCP(0x76bb5521, 0x2fd1f5c1), STCP(0x767edfbe, 0x306703bf),
|
||||
STCP(0x7641af3d, 0x30fbc54d), STCP(0x7603c3fd, 0x31903982),
|
||||
STCP(0x75c51e61, 0x32245f72), STCP(0x7585becb, 0x32b83634),
|
||||
STCP(0x7545a5a0, 0x334bbcde), STCP(0x7504d345, 0x33def287),
|
||||
STCP(0x74c34820, 0x3471d647), STCP(0x74810499, 0x35046736),
|
||||
STCP(0x743e0918, 0x3596a46c), STCP(0x73fa5607, 0x36288d03),
|
||||
STCP(0x73b5ebd1, 0x36ba2014), STCP(0x7370cae2, 0x374b5cb9),
|
||||
STCP(0x732af3a7, 0x37dc420c), STCP(0x72e4668f, 0x386ccf2a),
|
||||
STCP(0x729d2409, 0x38fd032d), STCP(0x72552c85, 0x398cdd32),
|
||||
STCP(0x720c8075, 0x3a1c5c57), STCP(0x71c3204c, 0x3aab7fb7),
|
||||
STCP(0x71790c7e, 0x3b3a4672), STCP(0x712e457f, 0x3bc8afa5),
|
||||
STCP(0x70e2cbc6, 0x3c56ba70), STCP(0x70969fca, 0x3ce465f3),
|
||||
STCP(0x7049c203, 0x3d71b14d), STCP(0x6ffc32eb, 0x3dfe9ba1),
|
||||
STCP(0x6fadf2fc, 0x3e8b240e), STCP(0x6f5f02b2, 0x3f1749b8),
|
||||
STCP(0x6f0f6289, 0x3fa30bc1), STCP(0x6ebf12ff, 0x402e694c),
|
||||
STCP(0x6e6e1492, 0x40b9617d), STCP(0x6e1c67c4, 0x4143f379),
|
||||
STCP(0x6dca0d14, 0x41ce1e65), STCP(0x6d770506, 0x4257e166),
|
||||
STCP(0x6d23501b, 0x42e13ba4), STCP(0x6cceeed8, 0x436a2c45),
|
||||
STCP(0x6c79e1c2, 0x43f2b271), STCP(0x6c242960, 0x447acd50),
|
||||
STCP(0x6bcdc639, 0x45027c0c), STCP(0x6b76b8d6, 0x4589bdcf),
|
||||
STCP(0x6b1f01c0, 0x461091c2), STCP(0x6ac6a180, 0x4696f710),
|
||||
STCP(0x6a6d98a4, 0x471cece7), STCP(0x6a13e7b8, 0x47a27271),
|
||||
STCP(0x69b98f48, 0x482786dc), STCP(0x695e8fe5, 0x48ac2957),
|
||||
STCP(0x6902ea1d, 0x4930590f), STCP(0x68a69e81, 0x49b41533),
|
||||
STCP(0x6849ada3, 0x4a375cf5), STCP(0x67ec1817, 0x4aba2f84),
|
||||
STCP(0x678dde6e, 0x4b3c8c12), STCP(0x672f013f, 0x4bbe71d1),
|
||||
STCP(0x66cf8120, 0x4c3fdff4), STCP(0x666f5ea6, 0x4cc0d5ae),
|
||||
STCP(0x660e9a6a, 0x4d415234), STCP(0x65ad3505, 0x4dc154bb),
|
||||
STCP(0x654b2f10, 0x4e40dc79), STCP(0x64e88926, 0x4ebfe8a5),
|
||||
STCP(0x648543e4, 0x4f3e7875), STCP(0x64215fe5, 0x4fbc8b22),
|
||||
STCP(0x63bcddc7, 0x503a1fe5), STCP(0x6357be2a, 0x50b735f8),
|
||||
STCP(0x62f201ac, 0x5133cc94), STCP(0x628ba8ef, 0x51afe2f6),
|
||||
STCP(0x6224b495, 0x522b7859), STCP(0x61bd253f, 0x52a68bfb),
|
||||
STCP(0x6154fb91, 0x53211d18), STCP(0x60ec3830, 0x539b2af0),
|
||||
STCP(0x6082dbc1, 0x5414b4c1), STCP(0x6018e6eb, 0x548db9cb),
|
||||
STCP(0x5fae5a55, 0x55063951), STCP(0x5f4336a7, 0x557e3292),
|
||||
STCP(0x5ed77c8a, 0x55f5a4d2), STCP(0x5e6b2ca8, 0x566c8f55),
|
||||
STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5d90ce45, 0x5758ca31),
|
||||
STCP(0x5d22c11c, 0x57ce1917), STCP(0x5cb420e0, 0x5842dd54),
|
||||
STCP(0x5c44ee40, 0x58b71632), STCP(0x5bd529eb, 0x592ac2f7),
|
||||
STCP(0x5b64d492, 0x599de2ee), STCP(0x5af3eee6, 0x5a107561),
|
||||
STCP(0x5a82799a, 0x5a82799a)
|
||||
};
|
||||
|
||||
/*
|
||||
Sine windows
|
||||
*/
|
||||
#define WTC(x) WORD322WORD16(x)
|
||||
|
||||
#define WTCP(a,b) { { WTC(a), WTC(b) } }
|
||||
|
||||
const PWord16 SineWindow10[5] =
|
||||
{
|
||||
WTCP(0x7f9afcb9, 0x0a0af299), WTCP(0x7c769e18, 0x1de189a6), WTCP(0x7641af3d, 0x30fbc54d), WTCP(0x6d23501b, 0x42e13ba4),
|
||||
WTCP(0x6154fb91, 0x53211d18),
|
||||
};
|
||||
|
||||
const PWord16 SineWindow16[8] =
|
||||
{
|
||||
WTCP(0x7fd8878e, 0x0647d97c), WTCP(0x7e9d55fc, 0x12c8106f), WTCP(0x7c29fbee, 0x1f19f97b), WTCP(0x78848414, 0x2b1f34eb),
|
||||
WTCP(0x73b5ebd1, 0x36ba2014), WTCP(0x6dca0d14, 0x41ce1e65), WTCP(0x66cf8120, 0x4c3fdff4), WTCP(0x5ed77c8a, 0x55f5a4d2),
|
||||
};
|
||||
|
||||
const PWord16 SineWindow20[10] =
|
||||
{
|
||||
WTCP(0x7fe6bcb0, 0x05067734), WTCP(0x7f1cde01, 0x0f0b7727), WTCP(0x7d8a5f40, 0x18f8b83c), WTCP(0x7b31bbb2, 0x22be8f87),
|
||||
WTCP(0x7816a759, 0x2c4d9050), WTCP(0x743e0918, 0x3596a46c), WTCP(0x6fadf2fc, 0x3e8b240e), WTCP(0x6a6d98a4, 0x471cece7),
|
||||
WTCP(0x648543e4, 0x4f3e7875), WTCP(0x5dfe47ad, 0x56e2f15d),
|
||||
};
|
||||
|
||||
const PWord16 SineWindow30[15] =
|
||||
{
|
||||
WTCP(0x7ff4c56f, 0x0359c428), WTCP(0x7f9afcb9, 0x0a0af299), WTCP(0x7ee7aa4c, 0x10b5150f), WTCP(0x7ddb4bfc, 0x17537e63),
|
||||
WTCP(0x7c769e18, 0x1de189a6), WTCP(0x7aba9ae6, 0x245a9d65), WTCP(0x78a879f4, 0x2aba2ee4), WTCP(0x7641af3d, 0x30fbc54d),
|
||||
WTCP(0x7387ea23, 0x371afcd5), WTCP(0x707d1443, 0x3d1389cb), WTCP(0x6d23501b, 0x42e13ba4), WTCP(0x697cf78a, 0x487fffe4),
|
||||
WTCP(0x658c9a2d, 0x4debe4fe), WTCP(0x6154fb91, 0x53211d18), WTCP(0x5cd91140, 0x581c00b3),
|
||||
};
|
||||
|
||||
const PWord16 SineWindow32[16] =
|
||||
{
|
||||
WTCP(0x7ff62182, 0x03242abf), WTCP(0x7fa736b4, 0x096a9049), WTCP(0x7f0991c4, 0x0fab272b), WTCP(0x7e1d93ea, 0x15e21445),
|
||||
WTCP(0x7ce3ceb2, 0x1c0b826a), WTCP(0x7b5d039e, 0x2223a4c5), WTCP(0x798a23b1, 0x2826b928), WTCP(0x776c4edb, 0x2e110a62),
|
||||
WTCP(0x7504d345, 0x33def287), WTCP(0x72552c85, 0x398cdd32), WTCP(0x6f5f02b2, 0x3f1749b8), WTCP(0x6c242960, 0x447acd50),
|
||||
WTCP(0x68a69e81, 0x49b41533), WTCP(0x64e88926, 0x4ebfe8a5), WTCP(0x60ec3830, 0x539b2af0), WTCP(0x5cb420e0, 0x5842dd54)
|
||||
};
|
||||
|
||||
const PWord16 SineWindow40[20] =
|
||||
{
|
||||
WTCP(0x7ff9af04, 0x02835b5a), WTCP(0x7fc72ae2, 0x07891418), WTCP(0x7f62368f, 0x0c8bd35e), WTCP(0x7ecaf9e5, 0x11899ed3),
|
||||
WTCP(0x7e01b096, 0x16807e15), WTCP(0x7d06aa16, 0x1b6e7b7a), WTCP(0x7bda497d, 0x2051a4dd), WTCP(0x7a7d055b, 0x25280c5e),
|
||||
WTCP(0x78ef678f, 0x29efc925), WTCP(0x77320d0d, 0x2ea6f827), WTCP(0x7545a5a0, 0x334bbcde), WTCP(0x732af3a7, 0x37dc420c),
|
||||
WTCP(0x70e2cbc6, 0x3c56ba70), WTCP(0x6e6e1492, 0x40b9617d), WTCP(0x6bcdc639, 0x45027c0c), WTCP(0x6902ea1d, 0x4930590f),
|
||||
WTCP(0x660e9a6a, 0x4d415234), WTCP(0x62f201ac, 0x5133cc94), WTCP(0x5fae5a55, 0x55063951), WTCP(0x5c44ee40, 0x58b71632),
|
||||
};
|
||||
|
||||
const PWord16 SineWindow48[24] =
|
||||
{
|
||||
WTCP(0x7ffb9d15, 0x02182427), WTCP(0x7fd8878e, 0x0647d97c), WTCP(0x7f92661d, 0x0a75d60e), WTCP(0x7f294bfd, 0x0ea0f48c),
|
||||
WTCP(0x7e9d55fc, 0x12c8106f), WTCP(0x7deeaa7a, 0x16ea0646), WTCP(0x7d1d7958, 0x1b05b40f), WTCP(0x7c29fbee, 0x1f19f97b),
|
||||
WTCP(0x7b1474fd, 0x2325b847), WTCP(0x79dd3098, 0x2727d486), WTCP(0x78848414, 0x2b1f34eb), WTCP(0x770acdec, 0x2f0ac320),
|
||||
WTCP(0x757075ac, 0x32e96c09), WTCP(0x73b5ebd1, 0x36ba2014), WTCP(0x71dba9ab, 0x3a7bd382), WTCP(0x6fe2313c, 0x3e2d7eb1),
|
||||
WTCP(0x6dca0d14, 0x41ce1e65), WTCP(0x6b93d02e, 0x455cb40c), WTCP(0x694015c3, 0x48d84609), WTCP(0x66cf8120, 0x4c3fdff4),
|
||||
WTCP(0x6442bd7e, 0x4f9292dc), WTCP(0x619a7dce, 0x52cf758f), WTCP(0x5ed77c8a, 0x55f5a4d2), WTCP(0x5bfa7b82, 0x590443a7)
|
||||
};
|
||||
|
||||
const PWord16 SineWindow60[60] =
|
||||
{
|
||||
WTCP(0x7ffd3154, 0x01aceb7c), WTCP(0x7fe6bcb0, 0x05067734), WTCP(0x7fb9d759, 0x085f2137), WTCP(0x7f76892f, 0x0bb65336),
|
||||
WTCP(0x7f1cde01, 0x0f0b7727), WTCP(0x7eace58a, 0x125df75b), WTCP(0x7e26b371, 0x15ad3e9a), WTCP(0x7d8a5f40, 0x18f8b83c),
|
||||
WTCP(0x7cd80464, 0x1c3fd045), WTCP(0x7c0fc22a, 0x1f81f37c), WTCP(0x7b31bbb2, 0x22be8f87), WTCP(0x7a3e17f2, 0x25f51307),
|
||||
WTCP(0x793501a9, 0x2924edac), WTCP(0x7816a759, 0x2c4d9050), WTCP(0x76e33b3f, 0x2f6e6d16), WTCP(0x759af34c, 0x3286f779),
|
||||
WTCP(0x743e0918, 0x3596a46c), WTCP(0x72ccb9db, 0x389cea72), WTCP(0x71474660, 0x3b9941b1), WTCP(0x6fadf2fc, 0x3e8b240e),
|
||||
WTCP(0x6e010780, 0x41720d46), WTCP(0x6c40cf2c, 0x444d7aff), WTCP(0x6a6d98a4, 0x471cece7), WTCP(0x6887b5e2, 0x49dfe4c2),
|
||||
WTCP(0x668f7c25, 0x4c95e688), WTCP(0x648543e4, 0x4f3e7875), WTCP(0x626968be, 0x51d92321), WTCP(0x603c496c, 0x54657194),
|
||||
WTCP(0x5dfe47ad, 0x56e2f15d), WTCP(0x5bafc837, 0x595132a2),
|
||||
};
|
||||
|
||||
const PWord16 SineWindow64[32] =
|
||||
{
|
||||
WTCP(0x7ffd885a, 0x01921d20), WTCP(0x7fe9cbc0, 0x04b6195d), WTCP(0x7fc25596, 0x07d95b9e), WTCP(0x7f872bf3, 0x0afb6805),
|
||||
WTCP(0x7f3857f6, 0x0e1bc2e4), WTCP(0x7ed5e5c6, 0x1139f0cf), WTCP(0x7e5fe493, 0x145576b1), WTCP(0x7dd6668f, 0x176dd9de),
|
||||
WTCP(0x7d3980ec, 0x1a82a026), WTCP(0x7c894bde, 0x1d934fe5), WTCP(0x7bc5e290, 0x209f701c), WTCP(0x7aef6323, 0x23a6887f),
|
||||
WTCP(0x7a05eead, 0x26a82186), WTCP(0x7909a92d, 0x29a3c485), WTCP(0x77fab989, 0x2c98fbba), WTCP(0x76d94989, 0x2f875262),
|
||||
WTCP(0x75a585cf, 0x326e54c7), WTCP(0x745f9dd1, 0x354d9057), WTCP(0x7307c3d0, 0x382493b0), WTCP(0x719e2cd2, 0x3af2eeb7),
|
||||
WTCP(0x7023109a, 0x3db832a6), WTCP(0x6e96a99d, 0x4073f21d), WTCP(0x6cf934fc, 0x4325c135), WTCP(0x6b4af279, 0x45cd358f),
|
||||
WTCP(0x698c246c, 0x4869e665), WTCP(0x67bd0fbd, 0x4afb6c98), WTCP(0x65ddfbd3, 0x4d8162c4), WTCP(0x63ef3290, 0x4ffb654d),
|
||||
WTCP(0x61f1003f, 0x5269126e), WTCP(0x5fe3b38d, 0x54ca0a4b), WTCP(0x5dc79d7c, 0x571deefa), WTCP(0x5b9d1154, 0x59646498),
|
||||
};
|
||||
|
||||
const PWord16 SineWindow80[40] =
|
||||
{
|
||||
WTCP(0x7ffe6bbf, 0x0141b1a5), WTCP(0x7ff1c9ef, 0x03c4f52f), WTCP(0x7fd8878e, 0x0647d97c), WTCP(0x7fb2a71b, 0x08ca1f1b),
|
||||
WTCP(0x7f802c52, 0x0b4b86a8), WTCP(0x7f411c2f, 0x0dcbd0d5), WTCP(0x7ef57cea, 0x104abe71), WTCP(0x7e9d55fc, 0x12c8106f),
|
||||
WTCP(0x7e38b017, 0x154387e6), WTCP(0x7dc79529, 0x17bce621), WTCP(0x7d4a105d, 0x1a33ec9c), WTCP(0x7cc02e15, 0x1ca85d12),
|
||||
WTCP(0x7c29fbee, 0x1f19f97b), WTCP(0x7b8788ba, 0x2188841a), WTCP(0x7ad8e482, 0x23f3bf7e), WTCP(0x7a1e2082, 0x265b6e8a),
|
||||
WTCP(0x79574f28, 0x28bf547b), WTCP(0x78848414, 0x2b1f34eb), WTCP(0x77a5d413, 0x2d7ad3de), WTCP(0x76bb5521, 0x2fd1f5c1),
|
||||
WTCP(0x75c51e61, 0x32245f72), WTCP(0x74c34820, 0x3471d647), WTCP(0x73b5ebd1, 0x36ba2014), WTCP(0x729d2409, 0x38fd032d),
|
||||
WTCP(0x71790c7e, 0x3b3a4672), WTCP(0x7049c203, 0x3d71b14d), WTCP(0x6f0f6289, 0x3fa30bc1), WTCP(0x6dca0d14, 0x41ce1e65),
|
||||
WTCP(0x6c79e1c2, 0x43f2b271), WTCP(0x6b1f01c0, 0x461091c2), WTCP(0x69b98f48, 0x482786dc), WTCP(0x6849ada3, 0x4a375cf5),
|
||||
WTCP(0x66cf8120, 0x4c3fdff4), WTCP(0x654b2f10, 0x4e40dc79), WTCP(0x63bcddc7, 0x503a1fe5), WTCP(0x6224b495, 0x522b7859),
|
||||
WTCP(0x6082dbc1, 0x5414b4c1), WTCP(0x5ed77c8a, 0x55f5a4d2), WTCP(0x5d22c11c, 0x57ce1917), WTCP(0x5b64d492, 0x599de2ee),
|
||||
};
|
||||
|
||||
const PWord16 SineWindow70[35] =
|
||||
{
|
||||
WTCP(0x7ffdeffe, 0x016fa5fd), WTCP(0x7fed7058, 0x044ec292), WTCP(0x7fcc732b, 0x072d5101), WTCP(0x7f9afcb9, 0x0a0af299),
|
||||
WTCP(0x7f591361, 0x0ce748ca), WTCP(0x7f06bfa3, 0x0fc1f52d), WTCP(0x7ea40c1b, 0x129a9991), WTCP(0x7e310583, 0x1570d80b),
|
||||
WTCP(0x7dadbaaf, 0x184452fd), WTCP(0x7d1a3c8a, 0x1b14ad24), WTCP(0x7c769e18, 0x1de189a6), WTCP(0x7bc2f470, 0x20aa8c19),
|
||||
WTCP(0x7aff56bc, 0x236f5896), WTCP(0x7a2bde32, 0x262f93be), WTCP(0x7948a614, 0x28eae2cb), WTCP(0x7855cbae, 0x2ba0eb97),
|
||||
WTCP(0x77536e4c, 0x2e5154ac), WTCP(0x7641af3d, 0x30fbc54d), WTCP(0x7520b1ca, 0x339fe582), WTCP(0x73f09b33, 0x363d5e23),
|
||||
WTCP(0x72b192ac, 0x38d3d8e3), WTCP(0x7163c154, 0x3b63005e), WTCP(0x70075233, 0x3dea8020), WTCP(0x6e9c7233, 0x406a04b2),
|
||||
WTCP(0x6d23501b, 0x42e13ba4), WTCP(0x6b9c1c87, 0x454fd398), WTCP(0x6a0709e6, 0x47b57c4e), WTCP(0x68644c6e, 0x4a11e6aa),
|
||||
WTCP(0x66b41a1a, 0x4c64c4c4), WTCP(0x64f6aa9f, 0x4eadc9ee), WTCP(0x632c3769, 0x50ecaabd), WTCP(0x6154fb91, 0x53211d18),
|
||||
WTCP(0x5f7133d4, 0x554ad83c), WTCP(0x5d811e90, 0x576994c8), WTCP(0x5b84fbb6, 0x597d0cc7)
|
||||
};
|
||||
|
||||
const PWord16 SineWindow96[48] =
|
||||
{
|
||||
WTCP(0x7ffee744, 0x010c1460), WTCP(0x7ff62182, 0x03242abf), WTCP(0x7fe49698, 0x053c0a01), WTCP(0x7fca47b9, 0x07538d6b),
|
||||
WTCP(0x7fa736b4, 0x096a9049), WTCP(0x7f7b65ef, 0x0b80edf1), WTCP(0x7f46d86c, 0x0d9681c2), WTCP(0x7f0991c4, 0x0fab272b),
|
||||
WTCP(0x7ec3962a, 0x11beb9aa), WTCP(0x7e74ea6a, 0x13d114d0), WTCP(0x7e1d93ea, 0x15e21445), WTCP(0x7dbd98a4, 0x17f193c5),
|
||||
WTCP(0x7d54ff2e, 0x19ff6f2a), WTCP(0x7ce3ceb2, 0x1c0b826a), WTCP(0x7c6a0ef2, 0x1e15a99a), WTCP(0x7be7c847, 0x201dc0ef),
|
||||
WTCP(0x7b5d039e, 0x2223a4c5), WTCP(0x7ac9ca7a, 0x2427319d), WTCP(0x7a2e26f2, 0x26284422), WTCP(0x798a23b1, 0x2826b928),
|
||||
WTCP(0x78ddcbf5, 0x2a226db5), WTCP(0x78292b8d, 0x2c1b3efb), WTCP(0x776c4edb, 0x2e110a62), WTCP(0x76a742d1, 0x3003ad85),
|
||||
WTCP(0x75da14ef, 0x31f30638), WTCP(0x7504d345, 0x33def287), WTCP(0x74278c72, 0x35c750bc), WTCP(0x73424fa0, 0x37abff5d),
|
||||
WTCP(0x72552c85, 0x398cdd32), WTCP(0x71603361, 0x3b69c947), WTCP(0x706374ff, 0x3d42a2ec), WTCP(0x6f5f02b2, 0x3f1749b8),
|
||||
WTCP(0x6e52ee52, 0x40e79d8c), WTCP(0x6d3f4a40, 0x42b37e96), WTCP(0x6c242960, 0x447acd50), WTCP(0x6b019f1a, 0x463d6a87),
|
||||
WTCP(0x69d7bf57, 0x47fb3757), WTCP(0x68a69e81, 0x49b41533), WTCP(0x676e5183, 0x4b67e5e4), WTCP(0x662eedc3, 0x4d168b8b),
|
||||
WTCP(0x64e88926, 0x4ebfe8a5), WTCP(0x639b3a0b, 0x5063e008), WTCP(0x62471749, 0x520254ef), WTCP(0x60ec3830, 0x539b2af0),
|
||||
WTCP(0x5f8ab487, 0x552e4605), WTCP(0x5e22a487, 0x56bb8a90), WTCP(0x5cb420e0, 0x5842dd54), WTCP(0x5b3f42ae, 0x59c42381)
|
||||
};
|
||||
|
||||
const PWord16 SineWindow112[56] =
|
||||
{
|
||||
WTCP(0x7fff31bf, 0x00e5c87e), WTCP(0x7ff8bfc7, 0x02b14de9), WTCP(0x7febdc2a, 0x047cb09e), WTCP(0x7fd8878e, 0x0647d97c),
|
||||
WTCP(0x7fbec2ec, 0x0812b164), WTCP(0x7f9e8f91, 0x09dd213a), WTCP(0x7f77ef1c, 0x0ba711ea), WTCP(0x7f4ae37e, 0x0d706c64),
|
||||
WTCP(0x7f176efc, 0x0f3919a0), WTCP(0x7edd942d, 0x110102a0), WTCP(0x7e9d55fc, 0x12c8106f), WTCP(0x7e56b7a4, 0x148e2c22),
|
||||
WTCP(0x7e09bcb4, 0x16533edc), WTCP(0x7db6690c, 0x181731cd), WTCP(0x7d5cc0df, 0x19d9ee32), WTCP(0x7cfcc8af, 0x1b9b5d5a),
|
||||
WTCP(0x7c968552, 0x1d5b68a2), WTCP(0x7c29fbee, 0x1f19f97b), WTCP(0x7bb731fb, 0x20d6f969), WTCP(0x7b3e2d40, 0x22925203),
|
||||
WTCP(0x7abef3d5, 0x244becf6), WTCP(0x7a398c22, 0x2603b406), WTCP(0x79adfcdf, 0x27b9910e), WTCP(0x791c4d13, 0x296d6e00),
|
||||
WTCP(0x78848414, 0x2b1f34eb), WTCP(0x77e6a986, 0x2ccecff7), WTCP(0x7742c55c, 0x2e7c2969), WTCP(0x7698dfd8, 0x30272ba0),
|
||||
WTCP(0x75e90186, 0x31cfc11e), WTCP(0x75333343, 0x3375d481), WTCP(0x74777e35, 0x35195088), WTCP(0x73b5ebd1, 0x36ba2014),
|
||||
WTCP(0x72ee85d5, 0x38582e27), WTCP(0x7221564d, 0x39f365e9), WTCP(0x714e678c, 0x3b8bb2a3), WTCP(0x7075c433, 0x3d20ffc8),
|
||||
WTCP(0x6f977729, 0x3eb338ef), WTCP(0x6eb38ba1, 0x404249d5), WTCP(0x6dca0d14, 0x41ce1e65), WTCP(0x6cdb0745, 0x4356a2ad),
|
||||
WTCP(0x6be6863c, 0x44dbc2ec), WTCP(0x6aec9649, 0x465d6b89), WTCP(0x69ed4403, 0x47db8918), WTCP(0x68e89c43, 0x4956085b),
|
||||
WTCP(0x67deac2c, 0x4accd644), WTCP(0x66cf8120, 0x4c3fdff4), WTCP(0x65bb28c7, 0x4daf12ba), WTCP(0x64a1b10b, 0x4f1a5c1a),
|
||||
WTCP(0x6383281a, 0x5081a9c9), WTCP(0x625f9c5f, 0x51e4e9ae), WTCP(0x61371c8b, 0x534409e8), WTCP(0x6009b78a, 0x549ef8c6),
|
||||
WTCP(0x5ed77c8a, 0x55f5a4d2), WTCP(0x5da07af6, 0x5747fcca), WTCP(0x5c64c278, 0x5895efa4), WTCP(0x5b2462f5, 0x59df6c8f)
|
||||
};
|
||||
|
||||
const PWord16 SineWindow120[60] =
|
||||
{
|
||||
WTCP(0x7fff4c54, 0x00d676eb), WTCP(0x7ff9af04, 0x02835b5a), WTCP(0x7fee74a2, 0x0430238f), WTCP(0x7fdd9dad, 0x05dcbcbe),
|
||||
WTCP(0x7fc72ae2, 0x07891418), WTCP(0x7fab1d3d, 0x093516d4), WTCP(0x7f8975f9, 0x0ae0b22c), WTCP(0x7f62368f, 0x0c8bd35e),
|
||||
WTCP(0x7f3560b9, 0x0e3667ad), WTCP(0x7f02f66f, 0x0fe05c64), WTCP(0x7ecaf9e5, 0x11899ed3), WTCP(0x7e8d6d91, 0x13321c53),
|
||||
WTCP(0x7e4a5426, 0x14d9c245), WTCP(0x7e01b096, 0x16807e15), WTCP(0x7db3860f, 0x18263d36), WTCP(0x7d5fd801, 0x19caed29),
|
||||
WTCP(0x7d06aa16, 0x1b6e7b7a), WTCP(0x7ca80038, 0x1d10d5c2), WTCP(0x7c43de8e, 0x1eb1e9a7), WTCP(0x7bda497d, 0x2051a4dd),
|
||||
WTCP(0x7b6b45a5, 0x21eff528), WTCP(0x7af6d7e6, 0x238cc85d), WTCP(0x7a7d055b, 0x25280c5e), WTCP(0x79fdd35c, 0x26c1af22),
|
||||
WTCP(0x7979477d, 0x28599eb0), WTCP(0x78ef678f, 0x29efc925), WTCP(0x7860399e, 0x2b841caf), WTCP(0x77cbc3f2, 0x2d168792),
|
||||
WTCP(0x77320d0d, 0x2ea6f827), WTCP(0x76931bae, 0x30355cdd), WTCP(0x75eef6ce, 0x31c1a43b), WTCP(0x7545a5a0, 0x334bbcde),
|
||||
WTCP(0x74972f92, 0x34d3957e), WTCP(0x73e39c49, 0x36591cea), WTCP(0x732af3a7, 0x37dc420c), WTCP(0x726d3dc6, 0x395cf3e9),
|
||||
WTCP(0x71aa82f7, 0x3adb21a1), WTCP(0x70e2cbc6, 0x3c56ba70), WTCP(0x701620f5, 0x3dcfadb0), WTCP(0x6f448b7e, 0x3f45ead8),
|
||||
WTCP(0x6e6e1492, 0x40b9617d), WTCP(0x6d92c59b, 0x422a0154), WTCP(0x6cb2a837, 0x4397ba32), WTCP(0x6bcdc639, 0x45027c0c),
|
||||
WTCP(0x6ae429ae, 0x466a36f9), WTCP(0x69f5dcd3, 0x47cedb31), WTCP(0x6902ea1d, 0x4930590f), WTCP(0x680b5c33, 0x4a8ea111),
|
||||
WTCP(0x670f3df3, 0x4be9a3db), WTCP(0x660e9a6a, 0x4d415234), WTCP(0x65097cdb, 0x4e959d08), WTCP(0x63fff0ba, 0x4fe6756a),
|
||||
WTCP(0x62f201ac, 0x5133cc94), WTCP(0x61dfbb8a, 0x527d93e6), WTCP(0x60c92a5a, 0x53c3bcea), WTCP(0x5fae5a55, 0x55063951),
|
||||
WTCP(0x5e8f57e2, 0x5644faf4), WTCP(0x5d6c2f99, 0x577ff3da), WTCP(0x5c44ee40, 0x58b71632), WTCP(0x5b19a0c8, 0x59ea5454),
|
||||
};
|
||||
|
||||
const PWord16 SineWindow128[64] =
|
||||
{
|
||||
WTCP(0x7fff6216, 0x00c90f88), WTCP(0x7ffa72d1, 0x025b26d7), WTCP(0x7ff09478, 0x03ed26e6), WTCP(0x7fe1c76b, 0x057f0035),
|
||||
WTCP(0x7fce0c3e, 0x0710a345), WTCP(0x7fb563b3, 0x08a2009a), WTCP(0x7f97cebd, 0x0a3308bd), WTCP(0x7f754e80, 0x0bc3ac35),
|
||||
WTCP(0x7f4de451, 0x0d53db92), WTCP(0x7f2191b4, 0x0ee38766), WTCP(0x7ef05860, 0x1072a048), WTCP(0x7eba3a39, 0x120116d5),
|
||||
WTCP(0x7e7f3957, 0x138edbb1), WTCP(0x7e3f57ff, 0x151bdf86), WTCP(0x7dfa98a8, 0x16a81305), WTCP(0x7db0fdf8, 0x183366e9),
|
||||
WTCP(0x7d628ac6, 0x19bdcbf3), WTCP(0x7d0f4218, 0x1b4732ef), WTCP(0x7cb72724, 0x1ccf8cb3), WTCP(0x7c5a3d50, 0x1e56ca1e),
|
||||
WTCP(0x7bf88830, 0x1fdcdc1b), WTCP(0x7b920b89, 0x2161b3a0), WTCP(0x7b26cb4f, 0x22e541af), WTCP(0x7ab6cba4, 0x24677758),
|
||||
WTCP(0x7a4210d8, 0x25e845b6), WTCP(0x79c89f6e, 0x27679df4), WTCP(0x794a7c12, 0x28e5714b), WTCP(0x78c7aba2, 0x2a61b101),
|
||||
WTCP(0x78403329, 0x2bdc4e6f), WTCP(0x77b417df, 0x2d553afc), WTCP(0x77235f2d, 0x2ecc681e), WTCP(0x768e0ea6, 0x3041c761),
|
||||
WTCP(0x75f42c0b, 0x31b54a5e), WTCP(0x7555bd4c, 0x3326e2c3), WTCP(0x74b2c884, 0x34968250), WTCP(0x740b53fb, 0x36041ad9),
|
||||
WTCP(0x735f6626, 0x376f9e46), WTCP(0x72af05a7, 0x38d8fe93), WTCP(0x71fa3949, 0x3a402dd2), WTCP(0x71410805, 0x3ba51e29),
|
||||
WTCP(0x708378ff, 0x3d07c1d6), WTCP(0x6fc19385, 0x3e680b2c), WTCP(0x6efb5f12, 0x3fc5ec98), WTCP(0x6e30e34a, 0x4121589b),
|
||||
WTCP(0x6d6227fa, 0x427a41d0), WTCP(0x6c8f351c, 0x43d09aed), WTCP(0x6bb812d1, 0x452456bd), WTCP(0x6adcc964, 0x46756828),
|
||||
WTCP(0x69fd614a, 0x47c3c22f), WTCP(0x6919e320, 0x490f57ee), WTCP(0x683257ab, 0x4a581c9e), WTCP(0x6746c7d8, 0x4b9e0390),
|
||||
WTCP(0x66573cbb, 0x4ce10034), WTCP(0x6563bf92, 0x4e210617), WTCP(0x646c59bf, 0x4f5e08e3), WTCP(0x637114cc, 0x5097fc5e),
|
||||
WTCP(0x6271fa69, 0x51ced46e), WTCP(0x616f146c, 0x53028518), WTCP(0x60686ccf, 0x5433027d), WTCP(0x5f5e0db3, 0x556040e2),
|
||||
WTCP(0x5e50015d, 0x568a34a9), WTCP(0x5d3e5237, 0x57b0d256), WTCP(0x5c290acc, 0x58d40e8c), WTCP(0x5b1035cf, 0x59f3de12),
|
||||
};
|
||||
|
||||
const PWord16 SineWindow140[70] =
|
||||
{
|
||||
WTCP(0x7fff7bff, 0x00b7d3bc), WTCP(0x7ffb5c00, 0x02277547), WTCP(0x7ff31c25, 0x0397050d), WTCP(0x7fe6bcb0, 0x05067734),
|
||||
WTCP(0x7fd63e09, 0x0675bfe7), WTCP(0x7fc1a0b6, 0x07e4d34d), WTCP(0x7fa8e564, 0x0953a594), WTCP(0x7f8c0cdc, 0x0ac22ae8),
|
||||
WTCP(0x7f6b180f, 0x0c30577a), WTCP(0x7f46080a, 0x0d9e1f7d), WTCP(0x7f1cde01, 0x0f0b7727), WTCP(0x7eef9b46, 0x107852b2),
|
||||
WTCP(0x7ebe414f, 0x11e4a65c), WTCP(0x7e88d1b4, 0x13506668), WTCP(0x7e4f4e2c, 0x14bb871b), WTCP(0x7e11b894, 0x1625fcc3),
|
||||
WTCP(0x7dd012e6, 0x178fbbb1), WTCP(0x7d8a5f40, 0x18f8b83c), WTCP(0x7d409fe1, 0x1a60e6c3), WTCP(0x7cf2d72b, 0x1bc83baa),
|
||||
WTCP(0x7ca1079d, 0x1d2eab5d), WTCP(0x7c4b33dc, 0x1e942a4d), WTCP(0x7bf15eac, 0x1ff8acf7), WTCP(0x7b938af1, 0x215c27dc),
|
||||
WTCP(0x7b31bbb2, 0x22be8f87), WTCP(0x7acbf416, 0x241fd88e), WTCP(0x7a623764, 0x257ff78e), WTCP(0x79f48904, 0x26dee12c),
|
||||
WTCP(0x7982ec80, 0x283c8a1b), WTCP(0x790d6581, 0x2998e716), WTCP(0x7893f7d1, 0x2af3ece2), WTCP(0x7816a759, 0x2c4d9050),
|
||||
WTCP(0x77957822, 0x2da5c63e), WTCP(0x77106e58, 0x2efc8393), WTCP(0x76878e43, 0x3051bd43), WTCP(0x75fadc4d, 0x31a56850),
|
||||
WTCP(0x756a5cff, 0x32f779c7), WTCP(0x74d61500, 0x3447e6c3), WTCP(0x743e0918, 0x3596a46c), WTCP(0x73a23e2d, 0x36e3a7fa),
|
||||
WTCP(0x7302b945, 0x382ee6b0), WTCP(0x725f7f84, 0x397855e1), WTCP(0x71b8962b, 0x3abfeaf1), WTCP(0x710e029e, 0x3c059b4f),
|
||||
WTCP(0x705fca59, 0x3d495c7e), WTCP(0x6fadf2fc, 0x3e8b240e), WTCP(0x6ef88241, 0x3fcae7a1), WTCP(0x6e3f7e01, 0x41089ce8),
|
||||
WTCP(0x6d82ec32, 0x424439a6), WTCP(0x6cc2d2e9, 0x437db3b0), WTCP(0x6bff3855, 0x44b500eb), WTCP(0x6b3822c6, 0x45ea1750),
|
||||
WTCP(0x6a6d98a4, 0x471cece7), WTCP(0x699fa078, 0x484d77ce), WTCP(0x68ce40e4, 0x497bae33), WTCP(0x67f980a8, 0x4aa7865b),
|
||||
WTCP(0x6721669f, 0x4bd0f69b), WTCP(0x6645f9c0, 0x4cf7f55d), WTCP(0x6567411d, 0x4e1c791f), WTCP(0x648543e4, 0x4f3e7875),
|
||||
WTCP(0x63a0095c, 0x505dea05), WTCP(0x62b798ea, 0x517ac48c), WTCP(0x61cbfa0b, 0x5294fedd), WTCP(0x60dd3457, 0x53ac8fde),
|
||||
WTCP(0x5feb4f7f, 0x54c16e8e), WTCP(0x5ef6534f, 0x55d391ff), WTCP(0x5dfe47ad, 0x56e2f15d), WTCP(0x5d033497, 0x57ef83e9),
|
||||
WTCP(0x5c052224, 0x58f940fa), WTCP(0x5b041885, 0x5a002001)
|
||||
};
|
||||
|
||||
const PWord16 SineWindow160[80] =
|
||||
{
|
||||
WTCP(0x7fff9aef, 0x00a0d951), WTCP(0x7ffc726f, 0x01e287fc), WTCP(0x7ff62182, 0x03242abf), WTCP(0x7feca851, 0x0465b9aa),
|
||||
WTCP(0x7fe00716, 0x05a72ccf), WTCP(0x7fd03e23, 0x06e87c3f), WTCP(0x7fbd4dda, 0x0829a00c), WTCP(0x7fa736b4, 0x096a9049),
|
||||
WTCP(0x7f8df93c, 0x0aab450d), WTCP(0x7f719611, 0x0bebb66c), WTCP(0x7f520de6, 0x0d2bdc80), WTCP(0x7f2f6183, 0x0e6baf61),
|
||||
WTCP(0x7f0991c4, 0x0fab272b), WTCP(0x7ee09f95, 0x10ea3bfd), WTCP(0x7eb48bfb, 0x1228e5f8), WTCP(0x7e85580c, 0x13671d3d),
|
||||
WTCP(0x7e5304f2, 0x14a4d9f4), WTCP(0x7e1d93ea, 0x15e21445), WTCP(0x7de50646, 0x171ec45c), WTCP(0x7da95d6c, 0x185ae269),
|
||||
WTCP(0x7d6a9ad5, 0x199666a0), WTCP(0x7d28c00c, 0x1ad14938), WTCP(0x7ce3ceb2, 0x1c0b826a), WTCP(0x7c9bc87a, 0x1d450a78),
|
||||
WTCP(0x7c50af2b, 0x1e7dd9a4), WTCP(0x7c02849f, 0x1fb5e836), WTCP(0x7bb14ac5, 0x20ed2e7b), WTCP(0x7b5d039e, 0x2223a4c5),
|
||||
WTCP(0x7b05b13d, 0x2359436c), WTCP(0x7aab55ca, 0x248e02cb), WTCP(0x7a4df380, 0x25c1db44), WTCP(0x79ed8cad, 0x26f4c53e),
|
||||
WTCP(0x798a23b1, 0x2826b928), WTCP(0x7923bb01, 0x2957af74), WTCP(0x78ba5524, 0x2a87a09d), WTCP(0x784df4b3, 0x2bb68522),
|
||||
WTCP(0x77de9c5b, 0x2ce45589), WTCP(0x776c4edb, 0x2e110a62), WTCP(0x76f70f05, 0x2f3c9c40), WTCP(0x767edfbe, 0x306703bf),
|
||||
WTCP(0x7603c3fd, 0x31903982), WTCP(0x7585becb, 0x32b83634), WTCP(0x7504d345, 0x33def287), WTCP(0x74810499, 0x35046736),
|
||||
WTCP(0x73fa5607, 0x36288d03), WTCP(0x7370cae2, 0x374b5cb9), WTCP(0x72e4668f, 0x386ccf2a), WTCP(0x72552c85, 0x398cdd32),
|
||||
WTCP(0x71c3204c, 0x3aab7fb7), WTCP(0x712e457f, 0x3bc8afa5), WTCP(0x70969fca, 0x3ce465f3), WTCP(0x6ffc32eb, 0x3dfe9ba1),
|
||||
WTCP(0x6f5f02b2, 0x3f1749b8), WTCP(0x6ebf12ff, 0x402e694c), WTCP(0x6e1c67c4, 0x4143f379), WTCP(0x6d770506, 0x4257e166),
|
||||
WTCP(0x6cceeed8, 0x436a2c45), WTCP(0x6c242960, 0x447acd50), WTCP(0x6b76b8d6, 0x4589bdcf), WTCP(0x6ac6a180, 0x4696f710),
|
||||
WTCP(0x6a13e7b8, 0x47a27271), WTCP(0x695e8fe5, 0x48ac2957), WTCP(0x68a69e81, 0x49b41533), WTCP(0x67ec1817, 0x4aba2f84),
|
||||
WTCP(0x672f013f, 0x4bbe71d1), WTCP(0x666f5ea6, 0x4cc0d5ae), WTCP(0x65ad3505, 0x4dc154bb), WTCP(0x64e88926, 0x4ebfe8a5),
|
||||
WTCP(0x64215fe5, 0x4fbc8b22), WTCP(0x6357be2a, 0x50b735f8), WTCP(0x628ba8ef, 0x51afe2f6), WTCP(0x61bd253f, 0x52a68bfb),
|
||||
WTCP(0x60ec3830, 0x539b2af0), WTCP(0x6018e6eb, 0x548db9cb), WTCP(0x5f4336a7, 0x557e3292), WTCP(0x5e6b2ca8, 0x566c8f55),
|
||||
WTCP(0x5d90ce45, 0x5758ca31), WTCP(0x5cb420e0, 0x5842dd54), WTCP(0x5bd529eb, 0x592ac2f7), WTCP(0x5af3eee6, 0x5a107561),
|
||||
};
|
||||
|
||||
const PWord16 SineWindow180[90] =
|
||||
{
|
||||
WTCP(0x7fffb026, 0x008efa17), WTCP(0x7ffd3154, 0x01aceb7c), WTCP(0x7ff833bd, 0x02cad485), WTCP(0x7ff0b77a, 0x03e8af9e),
|
||||
WTCP(0x7fe6bcb0, 0x05067734), WTCP(0x7fda4391, 0x062425b6), WTCP(0x7fcb4c5b, 0x0741b592), WTCP(0x7fb9d759, 0x085f2137),
|
||||
WTCP(0x7fa5e4e1, 0x097c6313), WTCP(0x7f8f7559, 0x0a997598), WTCP(0x7f76892f, 0x0bb65336), WTCP(0x7f5b20df, 0x0cd2f660),
|
||||
WTCP(0x7f3d3cf4, 0x0def598a), WTCP(0x7f1cde01, 0x0f0b7727), WTCP(0x7efa04a8, 0x102749af), WTCP(0x7ed4b198, 0x1142cb98),
|
||||
WTCP(0x7eace58a, 0x125df75b), WTCP(0x7e82a146, 0x1378c774), WTCP(0x7e55e59e, 0x1493365f), WTCP(0x7e26b371, 0x15ad3e9a),
|
||||
WTCP(0x7df50bab, 0x16c6daa6), WTCP(0x7dc0ef44, 0x17e00505), WTCP(0x7d8a5f40, 0x18f8b83c), WTCP(0x7d515caf, 0x1a10eed3),
|
||||
WTCP(0x7d15e8ad, 0x1b28a351), WTCP(0x7cd80464, 0x1c3fd045), WTCP(0x7c97b109, 0x1d56703c), WTCP(0x7c54efdc, 0x1e6c7dc7),
|
||||
WTCP(0x7c0fc22a, 0x1f81f37c), WTCP(0x7bc8294d, 0x2096cbf1), WTCP(0x7b7e26aa, 0x21ab01c0), WTCP(0x7b31bbb2, 0x22be8f87),
|
||||
WTCP(0x7ae2e9e4, 0x23d16fe8), WTCP(0x7a91b2c7, 0x24e39d85), WTCP(0x7a3e17f2, 0x25f51307), WTCP(0x79e81b06, 0x2705cb19),
|
||||
WTCP(0x798fbdb0, 0x2815c06a), WTCP(0x793501a9, 0x2924edac), WTCP(0x78d7e8b6, 0x2a334d96), WTCP(0x787874a7, 0x2b40dae2),
|
||||
WTCP(0x7816a759, 0x2c4d9050), WTCP(0x77b282b3, 0x2d5968a3), WTCP(0x774c08ab, 0x2e645ea1), WTCP(0x76e33b3f, 0x2f6e6d16),
|
||||
WTCP(0x76781c7a, 0x30778ed2), WTCP(0x760aae73, 0x317fbeab), WTCP(0x759af34c, 0x3286f779), WTCP(0x7528ed32, 0x338d341b),
|
||||
WTCP(0x74b49e5f, 0x34926f74), WTCP(0x743e0918, 0x3596a46c), WTCP(0x73c52fab, 0x3699cdf2), WTCP(0x734a1475, 0x379be6f6),
|
||||
WTCP(0x72ccb9db, 0x389cea72), WTCP(0x724d224f, 0x399cd362), WTCP(0x71cb504e, 0x3a9b9cca), WTCP(0x71474660, 0x3b9941b1),
|
||||
WTCP(0x70c10718, 0x3c95bd26), WTCP(0x70389514, 0x3d910a3c), WTCP(0x6fadf2fc, 0x3e8b240e), WTCP(0x6f212385, 0x3f8405bc),
|
||||
WTCP(0x6e92296e, 0x407baa6a), WTCP(0x6e010780, 0x41720d46), WTCP(0x6d6dc08f, 0x42672981), WTCP(0x6cd8577a, 0x435afa54),
|
||||
WTCP(0x6c40cf2c, 0x444d7aff), WTCP(0x6ba72a98, 0x453ea6c7), WTCP(0x6b0b6cbd, 0x462e78f9), WTCP(0x6a6d98a4, 0x471cece7),
|
||||
WTCP(0x69cdb162, 0x4809fdeb), WTCP(0x692bba14, 0x48f5a767), WTCP(0x6887b5e2, 0x49dfe4c2), WTCP(0x67e1a7ff, 0x4ac8b16b),
|
||||
WTCP(0x673993a9, 0x4bb008d9), WTCP(0x668f7c25, 0x4c95e688), WTCP(0x65e364c4, 0x4d7a45fe), WTCP(0x653550e2, 0x4e5d22c6),
|
||||
WTCP(0x648543e4, 0x4f3e7875), WTCP(0x63d34137, 0x501e42a5), WTCP(0x631f4c54, 0x50fc7cfb), WTCP(0x626968be, 0x51d92321),
|
||||
WTCP(0x61b19a00, 0x52b430c9), WTCP(0x60f7e3b0, 0x538da1ae), WTCP(0x603c496c, 0x54657194), WTCP(0x5f7ecedd, 0x553b9c45),
|
||||
WTCP(0x5ebf77b5, 0x56101d94), WTCP(0x5dfe47ad, 0x56e2f15d), WTCP(0x5d3b428c, 0x57b41384), WTCP(0x5c766c1c, 0x58837ff4),
|
||||
WTCP(0x5bafc837, 0x595132a2), WTCP(0x5ae75ab9, 0x5a1d278d),
|
||||
};
|
||||
|
||||
|
||||
const PWord16 SineWindow224[112] =
|
||||
{
|
||||
WTCP(0x7fffcc70, 0x0072e46e), WTCP(0x7ffe2fee, 0x0158abd6), WTCP(0x7ffaf6f1, 0x023e6ee8), WTCP(0x7ff62182, 0x03242abf),
|
||||
WTCP(0x7fefafb1, 0x0409dc76), WTCP(0x7fe7a192, 0x04ef8129), WTCP(0x7fddf741, 0x05d515f5), WTCP(0x7fd2b0da, 0x06ba97f4),
|
||||
WTCP(0x7fc5ce84, 0x07a00445), WTCP(0x7fb75068, 0x08855802), WTCP(0x7fa736b4, 0x096a9049), WTCP(0x7f95819c, 0x0a4faa38),
|
||||
WTCP(0x7f82315a, 0x0b34a2ec), WTCP(0x7f6d462b, 0x0c197784), WTCP(0x7f56c053, 0x0cfe251d), WTCP(0x7f3ea01a, 0x0de2a8d7),
|
||||
WTCP(0x7f24e5cf, 0x0ec6ffd1), WTCP(0x7f0991c4, 0x0fab272b), WTCP(0x7eeca451, 0x108f1c07), WTCP(0x7ece1dd3, 0x1172db86),
|
||||
WTCP(0x7eadfeae, 0x125662c9), WTCP(0x7e8c4748, 0x1339aef3), WTCP(0x7e68f80e, 0x141cbd28), WTCP(0x7e441171, 0x14ff8a8c),
|
||||
WTCP(0x7e1d93ea, 0x15e21445), WTCP(0x7df57ff3, 0x16c45777), WTCP(0x7dcbd60e, 0x17a6514a), WTCP(0x7da096c2, 0x1887fee6),
|
||||
WTCP(0x7d73c299, 0x19695d74), WTCP(0x7d455a24, 0x1a4a6a1c), WTCP(0x7d155df9, 0x1b2b220b), WTCP(0x7ce3ceb2, 0x1c0b826a),
|
||||
WTCP(0x7cb0acef, 0x1ceb8869), WTCP(0x7c7bf954, 0x1dcb3134), WTCP(0x7c45b48d, 0x1eaa79fa), WTCP(0x7c0ddf47, 0x1f895fed),
|
||||
WTCP(0x7bd47a36, 0x2067e03e), WTCP(0x7b998614, 0x2145f81f), WTCP(0x7b5d039e, 0x2223a4c5), WTCP(0x7b1ef397, 0x2300e366),
|
||||
WTCP(0x7adf56c8, 0x23ddb139), WTCP(0x7a9e2dfd, 0x24ba0b76), WTCP(0x7a5b7a09, 0x2595ef56), WTCP(0x7a173bc2, 0x26715a16),
|
||||
WTCP(0x79d17405, 0x274c48f2), WTCP(0x798a23b1, 0x2826b928), WTCP(0x79414bae, 0x2900a7f9), WTCP(0x78f6ece5, 0x29da12a7),
|
||||
WTCP(0x78ab0847, 0x2ab2f674), WTCP(0x785d9ec8, 0x2b8b50a5), WTCP(0x780eb161, 0x2c631e82), WTCP(0x77be4111, 0x2d3a5d53),
|
||||
WTCP(0x776c4edb, 0x2e110a62), WTCP(0x7718dbc8, 0x2ee722fb), WTCP(0x76c3e8e3, 0x2fbca46d), WTCP(0x766d773f, 0x30918c08),
|
||||
WTCP(0x761587f3, 0x3165d71c), WTCP(0x75bc1c1a, 0x323982ff), WTCP(0x756134d4, 0x330c8d05), WTCP(0x7504d345, 0x33def287),
|
||||
WTCP(0x74a6f899, 0x34b0b0df), WTCP(0x7447a5fc, 0x3581c569), WTCP(0x73e6dca3, 0x36522d83), WTCP(0x73849dc5, 0x3721e68d),
|
||||
WTCP(0x7320ea9f, 0x37f0edea), WTCP(0x72bbc472, 0x38bf40ff), WTCP(0x72552c85, 0x398cdd32), WTCP(0x71ed2421, 0x3a59bfee),
|
||||
WTCP(0x7183ac96, 0x3b25e69e), WTCP(0x7118c739, 0x3bf14eaf), WTCP(0x70ac7560, 0x3cbbf594), WTCP(0x703eb86a, 0x3d85d8bd),
|
||||
WTCP(0x6fcf91b9, 0x3e4ef5a1), WTCP(0x6f5f02b2, 0x3f1749b8), WTCP(0x6eed0cc0, 0x3fded27c), WTCP(0x6e79b152, 0x40a58d69),
|
||||
WTCP(0x6e04f1dd, 0x416b7801), WTCP(0x6d8ecfd8, 0x42308fc4), WTCP(0x6d174cc0, 0x42f4d237), WTCP(0x6c9e6a16, 0x43b83ce3),
|
||||
WTCP(0x6c242960, 0x447acd50), WTCP(0x6ba88c28, 0x453c810d), WTCP(0x6b2b93fd, 0x45fd55a9), WTCP(0x6aad4270, 0x46bd48b7),
|
||||
WTCP(0x6a2d9919, 0x477c57cb), WTCP(0x69ac9994, 0x483a807f), WTCP(0x692a4580, 0x48f7c06d), WTCP(0x68a69e81, 0x49b41533),
|
||||
WTCP(0x6821a640, 0x4a6f7c74), WTCP(0x679b5e68, 0x4b29f3d1), WTCP(0x6713c8ac, 0x4be378f4), WTCP(0x668ae6bf, 0x4c9c0985),
|
||||
WTCP(0x6600ba5b, 0x4d53a332), WTCP(0x6575453d, 0x4e0a43ab), WTCP(0x64e88926, 0x4ebfe8a5), WTCP(0x645a87dd, 0x4f748fd4),
|
||||
WTCP(0x63cb432a, 0x502836f4), WTCP(0x633abcdc, 0x50dadbc1), WTCP(0x62a8f6c4, 0x518c7bfb), WTCP(0x6215f2b9, 0x523d1567),
|
||||
WTCP(0x6181b292, 0x52eca5ca), WTCP(0x60ec3830, 0x539b2af0), WTCP(0x60558573, 0x5448a2a5), WTCP(0x5fbd9c41, 0x54f50abb),
|
||||
WTCP(0x5f247e83, 0x55a06106), WTCP(0x5e8a2e27, 0x564aa35d), WTCP(0x5deead1f, 0x56f3cf9d), WTCP(0x5d51fd5e, 0x579be3a4),
|
||||
WTCP(0x5cb420e0, 0x5842dd54), WTCP(0x5c15199f, 0x58e8ba94), WTCP(0x5b74e99d, 0x598d794c), WTCP(0x5ad392de, 0x5a31176a)
|
||||
};
|
||||
|
||||
|
||||
const PWord16 SineWindow256[128] =
|
||||
{
|
||||
WTCP(0x7fffd886, 0x006487e3), WTCP(0x7ffe9cb2, 0x012d96b1), WTCP(0x7ffc250f, 0x01f6a297), WTCP(0x7ff871a2, 0x02bfa9a4),
|
||||
WTCP(0x7ff38274, 0x0388a9ea), WTCP(0x7fed5791, 0x0451a177), WTCP(0x7fe5f108, 0x051a8e5c), WTCP(0x7fdd4eec, 0x05e36ea9),
|
||||
WTCP(0x7fd37153, 0x06ac406f), WTCP(0x7fc85854, 0x077501be), WTCP(0x7fbc040a, 0x083db0a7), WTCP(0x7fae7495, 0x09064b3a),
|
||||
WTCP(0x7f9faa15, 0x09cecf89), WTCP(0x7f8fa4b0, 0x0a973ba5), WTCP(0x7f7e648c, 0x0b5f8d9f), WTCP(0x7f6be9d4, 0x0c27c389),
|
||||
WTCP(0x7f5834b7, 0x0cefdb76), WTCP(0x7f434563, 0x0db7d376), WTCP(0x7f2d1c0e, 0x0e7fa99e), WTCP(0x7f15b8ee, 0x0f475bff),
|
||||
WTCP(0x7efd1c3c, 0x100ee8ad), WTCP(0x7ee34636, 0x10d64dbd), WTCP(0x7ec8371a, 0x119d8941), WTCP(0x7eabef2c, 0x1264994e),
|
||||
WTCP(0x7e8e6eb2, 0x132b7bf9), WTCP(0x7e6fb5f4, 0x13f22f58), WTCP(0x7e4fc53e, 0x14b8b17f), WTCP(0x7e2e9cdf, 0x157f0086),
|
||||
WTCP(0x7e0c3d29, 0x16451a83), WTCP(0x7de8a670, 0x170afd8d), WTCP(0x7dc3d90d, 0x17d0a7bc), WTCP(0x7d9dd55a, 0x18961728),
|
||||
WTCP(0x7d769bb5, 0x195b49ea), WTCP(0x7d4e2c7f, 0x1a203e1b), WTCP(0x7d24881b, 0x1ae4f1d6), WTCP(0x7cf9aef0, 0x1ba96335),
|
||||
WTCP(0x7ccda169, 0x1c6d9053), WTCP(0x7ca05ff1, 0x1d31774d), WTCP(0x7c71eaf9, 0x1df5163f), WTCP(0x7c4242f2, 0x1eb86b46),
|
||||
WTCP(0x7c116853, 0x1f7b7481), WTCP(0x7bdf5b94, 0x203e300d), WTCP(0x7bac1d31, 0x21009c0c), WTCP(0x7b77ada8, 0x21c2b69c),
|
||||
WTCP(0x7b420d7a, 0x22847de0), WTCP(0x7b0b3d2c, 0x2345eff8), WTCP(0x7ad33d45, 0x24070b08), WTCP(0x7a9a0e50, 0x24c7cd33),
|
||||
WTCP(0x7a5fb0d8, 0x2588349d), WTCP(0x7a24256f, 0x26483f6c), WTCP(0x79e76ca7, 0x2707ebc7), WTCP(0x79a98715, 0x27c737d3),
|
||||
WTCP(0x796a7554, 0x288621b9), WTCP(0x792a37fe, 0x2944a7a2), WTCP(0x78e8cfb2, 0x2a02c7b8), WTCP(0x78a63d11, 0x2ac08026),
|
||||
WTCP(0x786280bf, 0x2b7dcf17), WTCP(0x781d9b65, 0x2c3ab2b9), WTCP(0x77d78daa, 0x2cf72939), WTCP(0x7790583e, 0x2db330c7),
|
||||
WTCP(0x7747fbce, 0x2e6ec792), WTCP(0x76fe790e, 0x2f29ebcc), WTCP(0x76b3d0b4, 0x2fe49ba7), WTCP(0x76680376, 0x309ed556),
|
||||
WTCP(0x761b1211, 0x3158970e), WTCP(0x75ccfd42, 0x3211df04), WTCP(0x757dc5ca, 0x32caab6f), WTCP(0x752d6c6c, 0x3382fa88),
|
||||
WTCP(0x74dbf1ef, 0x343aca87), WTCP(0x7489571c, 0x34f219a8), WTCP(0x74359cbd, 0x35a8e625), WTCP(0x73e0c3a3, 0x365f2e3b),
|
||||
WTCP(0x738acc9e, 0x3714f02a), WTCP(0x7333b883, 0x37ca2a30), WTCP(0x72db8828, 0x387eda8e), WTCP(0x72823c67, 0x3932ff87),
|
||||
WTCP(0x7227d61c, 0x39e6975e), WTCP(0x71cc5626, 0x3a99a057), WTCP(0x716fbd68, 0x3b4c18ba), WTCP(0x71120cc5, 0x3bfdfecd),
|
||||
WTCP(0x70b34525, 0x3caf50da), WTCP(0x70536771, 0x3d600d2c), WTCP(0x6ff27497, 0x3e10320d), WTCP(0x6f906d84, 0x3ebfbdcd),
|
||||
WTCP(0x6f2d532c, 0x3f6eaeb8), WTCP(0x6ec92683, 0x401d0321), WTCP(0x6e63e87f, 0x40cab958), WTCP(0x6dfd9a1c, 0x4177cfb1),
|
||||
WTCP(0x6d963c54, 0x42244481), WTCP(0x6d2dd027, 0x42d0161e), WTCP(0x6cc45698, 0x437b42e1), WTCP(0x6c59d0a9, 0x4425c923),
|
||||
WTCP(0x6bee3f62, 0x44cfa740), WTCP(0x6b81a3cd, 0x4578db93), WTCP(0x6b13fef5, 0x4621647d), WTCP(0x6aa551e9, 0x46c9405c),
|
||||
WTCP(0x6a359db9, 0x47706d93), WTCP(0x69c4e37a, 0x4816ea86), WTCP(0x69532442, 0x48bcb599), WTCP(0x68e06129, 0x4961cd33),
|
||||
WTCP(0x686c9b4b, 0x4a062fbd), WTCP(0x67f7d3c5, 0x4aa9dba2), WTCP(0x67820bb7, 0x4b4ccf4d), WTCP(0x670b4444, 0x4bef092d),
|
||||
WTCP(0x66937e91, 0x4c9087b1), WTCP(0x661abbc5, 0x4d31494b), WTCP(0x65a0fd0b, 0x4dd14c6e), WTCP(0x6526438f, 0x4e708f8f),
|
||||
WTCP(0x64aa907f, 0x4f0f1126), WTCP(0x642de50d, 0x4faccfab), WTCP(0x63b0426d, 0x5049c999), WTCP(0x6331a9d4, 0x50e5fd6d),
|
||||
WTCP(0x62b21c7b, 0x518169a5), WTCP(0x62319b9d, 0x521c0cc2), WTCP(0x61b02876, 0x52b5e546), WTCP(0x612dc447, 0x534ef1b5),
|
||||
WTCP(0x60aa7050, 0x53e73097), WTCP(0x60262dd6, 0x547ea073), WTCP(0x5fa0fe1f, 0x55153fd4), WTCP(0x5f1ae274, 0x55ab0d46),
|
||||
WTCP(0x5e93dc1f, 0x56400758), WTCP(0x5e0bec6e, 0x56d42c99), WTCP(0x5d8314b1, 0x57677b9d), WTCP(0x5cf95638, 0x57f9f2f8),
|
||||
WTCP(0x5c6eb258, 0x588b9140), WTCP(0x5be32a67, 0x591c550e), WTCP(0x5b56bfbd, 0x59ac3cfd), WTCP(0x5ac973b5, 0x5a3b47ab),
|
||||
};
|
||||
|
||||
const PWord16 SineWindow280[140] =
|
||||
{
|
||||
WTCP(0x7fffdf00, 0x005be9f6), WTCP(0x7ffed6ff, 0x0113bd23), WTCP(0x7ffcc6ff, 0x01cb8e18), WTCP(0x7ff9af04, 0x02835b5a),
|
||||
WTCP(0x7ff58f15, 0x033b236c), WTCP(0x7ff0673a, 0x03f2e4d4), WTCP(0x7fea377e, 0x04aa9e17), WTCP(0x7fe2ffee, 0x05624dba),
|
||||
WTCP(0x7fdac098, 0x0619f243), WTCP(0x7fd1798e, 0x06d18a36), WTCP(0x7fc72ae2, 0x07891418), WTCP(0x7fbbd4aa, 0x08408e70),
|
||||
WTCP(0x7faf76fe, 0x08f7f7c3), WTCP(0x7fa211f6, 0x09af4e96), WTCP(0x7f93a5af, 0x0a66916f), WTCP(0x7f843246, 0x0b1dbed5),
|
||||
WTCP(0x7f73b7da, 0x0bd4d54d), WTCP(0x7f62368f, 0x0c8bd35e), WTCP(0x7f4fae88, 0x0d42b78f), WTCP(0x7f3c1fec, 0x0df98066),
|
||||
WTCP(0x7f278ae1, 0x0eb02c6a), WTCP(0x7f11ef95, 0x0f66ba22), WTCP(0x7efb4e31, 0x101d2817), WTCP(0x7ee3a6e7, 0x10d374cf),
|
||||
WTCP(0x7ecaf9e5, 0x11899ed3), WTCP(0x7eb1475f, 0x123fa4ab), WTCP(0x7e968f8b, 0x12f584e0), WTCP(0x7e7ad29e, 0x13ab3dfa),
|
||||
WTCP(0x7e5e10d3, 0x1460ce82), WTCP(0x7e404a65, 0x15163503), WTCP(0x7e217f90, 0x15cb7006), WTCP(0x7e01b096, 0x16807e15),
|
||||
WTCP(0x7de0ddb6, 0x17355dba), WTCP(0x7dbf0736, 0x17ea0d81), WTCP(0x7d9c2d5a, 0x189e8bf6), WTCP(0x7d78506a, 0x1952d7a3),
|
||||
WTCP(0x7d5370b2, 0x1a06ef15), WTCP(0x7d2d8e7b, 0x1abad0d8), WTCP(0x7d06aa16, 0x1b6e7b7a), WTCP(0x7cdec3d2, 0x1c21ed87),
|
||||
WTCP(0x7cb5dc00, 0x1cd5258f), WTCP(0x7c8bf2f7, 0x1d88221e), WTCP(0x7c61090b, 0x1e3ae1c5), WTCP(0x7c351e96, 0x1eed6311),
|
||||
WTCP(0x7c0833f3, 0x1f9fa494), WTCP(0x7bda497d, 0x2051a4dd), WTCP(0x7bab5f93, 0x2103627d), WTCP(0x7b7b7697, 0x21b4dc06),
|
||||
WTCP(0x7b4a8eeb, 0x2266100a), WTCP(0x7b18a8f4, 0x2316fd1b), WTCP(0x7ae5c518, 0x23c7a1cc), WTCP(0x7ab1e3c2, 0x2477fcb1),
|
||||
WTCP(0x7a7d055b, 0x25280c5e), WTCP(0x7a472a51, 0x25d7cf68), WTCP(0x7a105313, 0x26874464), WTCP(0x79d88013, 0x273669e9),
|
||||
WTCP(0x799fb1c2, 0x27e53e8e), WTCP(0x7965e897, 0x2893c0e9), WTCP(0x792b2508, 0x2941ef93), WTCP(0x78ef678f, 0x29efc925),
|
||||
WTCP(0x78b2b0a7, 0x2a9d4c38), WTCP(0x787500ce, 0x2b4a7766), WTCP(0x78365881, 0x2bf7494a), WTCP(0x77f6b844, 0x2ca3c07f),
|
||||
WTCP(0x77b62098, 0x2d4fdba2), WTCP(0x77749203, 0x2dfb9950), WTCP(0x77320d0d, 0x2ea6f827), WTCP(0x76ee923e, 0x2f51f6c4),
|
||||
WTCP(0x76aa2222, 0x2ffc93c9), WTCP(0x7664bd46, 0x30a6cdd3), WTCP(0x761e6439, 0x3150a385), WTCP(0x75d7178c, 0x31fa1381),
|
||||
WTCP(0x758ed7d2, 0x32a31c68), WTCP(0x7545a5a0, 0x334bbcde), WTCP(0x74fb818e, 0x33f3f387), WTCP(0x74b06c33, 0x349bbf09),
|
||||
WTCP(0x7464662c, 0x35431e09), WTCP(0x74177014, 0x35ea0f2e), WTCP(0x73c98a8a, 0x36909120), WTCP(0x737ab630, 0x3736a287),
|
||||
WTCP(0x732af3a7, 0x37dc420c), WTCP(0x72da4395, 0x38816e5b), WTCP(0x7288a69f, 0x3926261e), WTCP(0x72361d6e, 0x39ca6802),
|
||||
WTCP(0x71e2a8ad, 0x3a6e32b4), WTCP(0x718e4907, 0x3b1184e2), WTCP(0x7138ff2a, 0x3bb45d3b), WTCP(0x70e2cbc6, 0x3c56ba70),
|
||||
WTCP(0x708baf8d, 0x3cf89b31), WTCP(0x7033ab34, 0x3d99fe31), WTCP(0x6fdabf6e, 0x3e3ae223), WTCP(0x6f80ecf4, 0x3edb45ba),
|
||||
WTCP(0x6f26347f, 0x3f7b27ac), WTCP(0x6eca96ca, 0x401a86b0), WTCP(0x6e6e1492, 0x40b9617d), WTCP(0x6e10ae96, 0x4157b6ca),
|
||||
WTCP(0x6db26597, 0x41f58552), WTCP(0x6d533a56, 0x4292cbcf), WTCP(0x6cf32d99, 0x432f88fc), WTCP(0x6c924024, 0x43cbbb97),
|
||||
WTCP(0x6c3072c1, 0x4467625d), WTCP(0x6bcdc639, 0x45027c0c), WTCP(0x6b6a3b58, 0x459d0766), WTCP(0x6b05d2ea, 0x4637032c),
|
||||
WTCP(0x6aa08dbf, 0x46d06e1f), WTCP(0x6a3a6ca8, 0x47694703), WTCP(0x69d37078, 0x48018c9e), WTCP(0x696b9a02, 0x48993db5),
|
||||
WTCP(0x6902ea1d, 0x4930590f), WTCP(0x689961a1, 0x49c6dd74), WTCP(0x682f0167, 0x4a5cc9af), WTCP(0x67c3ca4c, 0x4af21c89),
|
||||
WTCP(0x6757bd2b, 0x4b86d4cf), WTCP(0x66eadae5, 0x4c1af14f), WTCP(0x667d2459, 0x4cae70d6), WTCP(0x660e9a6a, 0x4d415234),
|
||||
WTCP(0x659f3dfc, 0x4dd3943b), WTCP(0x652f0ff4, 0x4e6535bd), WTCP(0x64be113a, 0x4ef6358d), WTCP(0x644c42b8, 0x4f869280),
|
||||
WTCP(0x63d9a556, 0x50164b6d), WTCP(0x63663a03, 0x50a55f2c), WTCP(0x62f201ac, 0x5133cc94), WTCP(0x627cfd41, 0x51c19281),
|
||||
WTCP(0x62072db3, 0x524eafce), WTCP(0x619093f5, 0x52db2357), WTCP(0x611930fc, 0x5366ebfc), WTCP(0x60a105be, 0x53f2089b),
|
||||
WTCP(0x60281333, 0x547c7817), WTCP(0x5fae5a55, 0x55063951), WTCP(0x5f33dc1d, 0x558f4b2d), WTCP(0x5eb8998a, 0x5617ac90),
|
||||
WTCP(0x5e3c9399, 0x569f5c62), WTCP(0x5dbfcb4a, 0x5726598b), WTCP(0x5d42419f, 0x57aca2f3), WTCP(0x5cc3f79a, 0x58323787),
|
||||
WTCP(0x5c44ee40, 0x58b71632), WTCP(0x5bc52696, 0x593b3de2), WTCP(0x5b44a1a5, 0x59bead87), WTCP(0x5ac36076, 0x5a416413)
|
||||
};
|
||||
|
||||
const PWord16 SineWindow320[160] =
|
||||
{
|
||||
WTCP(0x7fffe6bc, 0x00506cb9), WTCP(0x7fff1c9b, 0x00f145ab), WTCP(0x7ffd885a, 0x01921d20), WTCP(0x7ffb29fd, 0x0232f21a),
|
||||
WTCP(0x7ff80186, 0x02d3c39b), WTCP(0x7ff40efa, 0x037490a5), WTCP(0x7fef5260, 0x0415583b), WTCP(0x7fe9cbc0, 0x04b6195d),
|
||||
WTCP(0x7fe37b22, 0x0556d30f), WTCP(0x7fdc608f, 0x05f78453), WTCP(0x7fd47c14, 0x06982c2b), WTCP(0x7fcbcdbc, 0x0738c998),
|
||||
WTCP(0x7fc25596, 0x07d95b9e), WTCP(0x7fb813b0, 0x0879e140), WTCP(0x7fad081b, 0x091a597e), WTCP(0x7fa132e8, 0x09bac35d),
|
||||
WTCP(0x7f949429, 0x0a5b1dde), WTCP(0x7f872bf3, 0x0afb6805), WTCP(0x7f78fa5b, 0x0b9ba0d5), WTCP(0x7f69ff76, 0x0c3bc74f),
|
||||
WTCP(0x7f5a3b5e, 0x0cdbda79), WTCP(0x7f49ae2a, 0x0d7bd954), WTCP(0x7f3857f6, 0x0e1bc2e4), WTCP(0x7f2638db, 0x0ebb962c),
|
||||
WTCP(0x7f1350f8, 0x0f5b5231), WTCP(0x7effa069, 0x0ffaf5f6), WTCP(0x7eeb274d, 0x109a807e), WTCP(0x7ed5e5c6, 0x1139f0cf),
|
||||
WTCP(0x7ebfdbf5, 0x11d945eb), WTCP(0x7ea909fc, 0x12787ed8), WTCP(0x7e917000, 0x13179a9b), WTCP(0x7e790e25, 0x13b69836),
|
||||
WTCP(0x7e5fe493, 0x145576b1), WTCP(0x7e45f371, 0x14f43510), WTCP(0x7e2b3ae8, 0x1592d257), WTCP(0x7e0fbb22, 0x16314d8e),
|
||||
WTCP(0x7df3744b, 0x16cfa5b9), WTCP(0x7dd6668f, 0x176dd9de), WTCP(0x7db8921c, 0x180be904), WTCP(0x7d99f721, 0x18a9d231),
|
||||
WTCP(0x7d7a95cf, 0x1947946c), WTCP(0x7d5a6e57, 0x19e52ebb), WTCP(0x7d3980ec, 0x1a82a026), WTCP(0x7d17cdc2, 0x1b1fe7b3),
|
||||
WTCP(0x7cf5550e, 0x1bbd046c), WTCP(0x7cd21707, 0x1c59f557), WTCP(0x7cae13e4, 0x1cf6b97c), WTCP(0x7c894bde, 0x1d934fe5),
|
||||
WTCP(0x7c63bf2f, 0x1e2fb79a), WTCP(0x7c3d6e13, 0x1ecbefa4), WTCP(0x7c1658c5, 0x1f67f70b), WTCP(0x7bee7f85, 0x2003ccdb),
|
||||
WTCP(0x7bc5e290, 0x209f701c), WTCP(0x7b9c8226, 0x213adfda), WTCP(0x7b725e8a, 0x21d61b1e), WTCP(0x7b4777fe, 0x227120f3),
|
||||
WTCP(0x7b1bcec4, 0x230bf065), WTCP(0x7aef6323, 0x23a6887f), WTCP(0x7ac23561, 0x2440e84d), WTCP(0x7a9445c5, 0x24db0edb),
|
||||
WTCP(0x7a659496, 0x2574fb36), WTCP(0x7a362220, 0x260eac6a), WTCP(0x7a05eead, 0x26a82186), WTCP(0x79d4fa89, 0x27415996),
|
||||
WTCP(0x79a34602, 0x27da53a9), WTCP(0x7970d165, 0x28730ecd), WTCP(0x793d9d03, 0x290b8a12), WTCP(0x7909a92d, 0x29a3c485),
|
||||
WTCP(0x78d4f634, 0x2a3bbd37), WTCP(0x789f846b, 0x2ad37338), WTCP(0x78695428, 0x2b6ae598), WTCP(0x783265c0, 0x2c021369),
|
||||
WTCP(0x77fab989, 0x2c98fbba), WTCP(0x77c24fdb, 0x2d2f9d9f), WTCP(0x77892910, 0x2dc5f829), WTCP(0x774f4581, 0x2e5c0a6b),
|
||||
WTCP(0x7714a58b, 0x2ef1d377), WTCP(0x76d94989, 0x2f875262), WTCP(0x769d31d9, 0x301c863f), WTCP(0x76605edb, 0x30b16e23),
|
||||
WTCP(0x7622d0ef, 0x31460922), WTCP(0x75e48874, 0x31da5651), WTCP(0x75a585cf, 0x326e54c7), WTCP(0x7565c962, 0x3302039b),
|
||||
WTCP(0x75255392, 0x339561e1), WTCP(0x74e424c5, 0x34286eb3), WTCP(0x74a23d62, 0x34bb2927), WTCP(0x745f9dd1, 0x354d9057),
|
||||
WTCP(0x741c467b, 0x35dfa35a), WTCP(0x73d837ca, 0x3671614b), WTCP(0x7393722a, 0x3702c942), WTCP(0x734df607, 0x3793da5b),
|
||||
WTCP(0x7307c3d0, 0x382493b0), WTCP(0x72c0dbf3, 0x38b4f45d), WTCP(0x72793edf, 0x3944fb7e), WTCP(0x7230ed07, 0x39d4a82f),
|
||||
WTCP(0x71e7e6dc, 0x3a63f98d), WTCP(0x719e2cd2, 0x3af2eeb7), WTCP(0x7153bf5d, 0x3b8186ca), WTCP(0x71089ef2, 0x3c0fc0e6),
|
||||
WTCP(0x70bccc09, 0x3c9d9c28), WTCP(0x70704718, 0x3d2b17b3), WTCP(0x7023109a, 0x3db832a6), WTCP(0x6fd52907, 0x3e44ec22),
|
||||
WTCP(0x6f8690db, 0x3ed14349), WTCP(0x6f374891, 0x3f5d373e), WTCP(0x6ee750a8, 0x3fe8c724), WTCP(0x6e96a99d, 0x4073f21d),
|
||||
WTCP(0x6e4553ef, 0x40feb74f), WTCP(0x6df35020, 0x418915de), WTCP(0x6da09eb1, 0x42130cf0), WTCP(0x6d4d4023, 0x429c9bab),
|
||||
WTCP(0x6cf934fc, 0x4325c135), WTCP(0x6ca47dbf, 0x43ae7cb7), WTCP(0x6c4f1af2, 0x4436cd58), WTCP(0x6bf90d1d, 0x44beb240),
|
||||
WTCP(0x6ba254c7, 0x45462a9a), WTCP(0x6b4af279, 0x45cd358f), WTCP(0x6af2e6bc, 0x4653d24b), WTCP(0x6a9a321d, 0x46d9fff8),
|
||||
WTCP(0x6a40d527, 0x475fbdc3), WTCP(0x69e6d067, 0x47e50ad8), WTCP(0x698c246c, 0x4869e665), WTCP(0x6930d1c4, 0x48ee4f98),
|
||||
WTCP(0x68d4d900, 0x497245a1), WTCP(0x68783ab1, 0x49f5c7ae), WTCP(0x681af76a, 0x4a78d4f0), WTCP(0x67bd0fbd, 0x4afb6c98),
|
||||
WTCP(0x675e843e, 0x4b7d8dd8), WTCP(0x66ff5584, 0x4bff37e2), WTCP(0x669f8425, 0x4c8069ea), WTCP(0x663f10b7, 0x4d012324),
|
||||
WTCP(0x65ddfbd3, 0x4d8162c4), WTCP(0x657c4613, 0x4e012800), WTCP(0x6519f010, 0x4e80720e), WTCP(0x64b6fa66, 0x4eff4025),
|
||||
WTCP(0x645365b2, 0x4f7d917c), WTCP(0x63ef3290, 0x4ffb654d), WTCP(0x638a619e, 0x5078bad1), WTCP(0x6324f37d, 0x50f59141),
|
||||
WTCP(0x62bee8cc, 0x5171e7d9), WTCP(0x6258422c, 0x51edbdd4), WTCP(0x61f1003f, 0x5269126e), WTCP(0x618923a9, 0x52e3e4e6),
|
||||
WTCP(0x6120ad0d, 0x535e3479), WTCP(0x60b79d10, 0x53d80065), WTCP(0x604df459, 0x545147eb), WTCP(0x5fe3b38d, 0x54ca0a4b),
|
||||
WTCP(0x5f78db56, 0x554246c6), WTCP(0x5f0d6c5b, 0x55b9fc9e), WTCP(0x5ea16747, 0x56312b17), WTCP(0x5e34ccc3, 0x56a7d174),
|
||||
WTCP(0x5dc79d7c, 0x571deefa), WTCP(0x5d59da1e, 0x579382ee), WTCP(0x5ceb8355, 0x58088c96), WTCP(0x5c7c99d1, 0x587d0b3b),
|
||||
WTCP(0x5c0d1e41, 0x58f0fe23), WTCP(0x5b9d1154, 0x59646498), WTCP(0x5b2c73bb, 0x59d73de3), WTCP(0x5abb4629, 0x5a498950),
|
||||
};
|
||||
|
||||
|
||||
const PWord16 SineWindow420[210] =
|
||||
{
|
||||
WTCP(0x7ffff155, 0x003d46a7), WTCP(0x7fff7bff, 0x00b7d3bc), WTCP(0x7ffe9154, 0x01326029), WTCP(0x7ffd3154, 0x01aceb7c),
|
||||
WTCP(0x7ffb5c00, 0x02277547), WTCP(0x7ff9115b, 0x02a1fd18), WTCP(0x7ff65166, 0x031c8280), WTCP(0x7ff31c25, 0x0397050d),
|
||||
WTCP(0x7fef7199, 0x0411844f), WTCP(0x7feb51c6, 0x048bffd7), WTCP(0x7fe6bcb0, 0x05067734), WTCP(0x7fe1b25b, 0x0580e9f6),
|
||||
WTCP(0x7fdc32cc, 0x05fb57ac), WTCP(0x7fd63e09, 0x0675bfe7), WTCP(0x7fcfd415, 0x06f02235), WTCP(0x7fc8f4f7, 0x076a7e27),
|
||||
WTCP(0x7fc1a0b6, 0x07e4d34d), WTCP(0x7fb9d759, 0x085f2137), WTCP(0x7fb198e5, 0x08d96773), WTCP(0x7fa8e564, 0x0953a594),
|
||||
WTCP(0x7f9fbcdc, 0x09cddb27), WTCP(0x7f961f57, 0x0a4807be), WTCP(0x7f8c0cdc, 0x0ac22ae8), WTCP(0x7f818577, 0x0b3c4435),
|
||||
WTCP(0x7f76892f, 0x0bb65336), WTCP(0x7f6b180f, 0x0c30577a), WTCP(0x7f5f3221, 0x0caa5092), WTCP(0x7f52d771, 0x0d243e0d),
|
||||
WTCP(0x7f46080a, 0x0d9e1f7d), WTCP(0x7f38c3f7, 0x0e17f471), WTCP(0x7f2b0b45, 0x0e91bc79), WTCP(0x7f1cde01, 0x0f0b7727),
|
||||
WTCP(0x7f0e3c36, 0x0f85240a), WTCP(0x7eff25f3, 0x0ffec2b3), WTCP(0x7eef9b46, 0x107852b2), WTCP(0x7edf9c3c, 0x10f1d398),
|
||||
WTCP(0x7ecf28e5, 0x116b44f6), WTCP(0x7ebe414f, 0x11e4a65c), WTCP(0x7eace58a, 0x125df75b), WTCP(0x7e9b15a6, 0x12d73784),
|
||||
WTCP(0x7e88d1b4, 0x13506668), WTCP(0x7e7619c3, 0x13c98397), WTCP(0x7e62ede5, 0x14428ea2), WTCP(0x7e4f4e2c, 0x14bb871b),
|
||||
WTCP(0x7e3b3aaa, 0x15346c93), WTCP(0x7e26b371, 0x15ad3e9a), WTCP(0x7e11b894, 0x1625fcc3), WTCP(0x7dfc4a26, 0x169ea69e),
|
||||
WTCP(0x7de6683a, 0x17173bbd), WTCP(0x7dd012e6, 0x178fbbb1), WTCP(0x7db94a3c, 0x1808260c), WTCP(0x7da20e53, 0x18807a5f),
|
||||
WTCP(0x7d8a5f40, 0x18f8b83c), WTCP(0x7d723d18, 0x1970df36), WTCP(0x7d59a7f1, 0x19e8eedd), WTCP(0x7d409fe1, 0x1a60e6c3),
|
||||
WTCP(0x7d272501, 0x1ad8c67c), WTCP(0x7d0d3767, 0x1b508d98), WTCP(0x7cf2d72b, 0x1bc83baa), WTCP(0x7cd80464, 0x1c3fd045),
|
||||
WTCP(0x7cbcbf2d, 0x1cb74afa), WTCP(0x7ca1079d, 0x1d2eab5d), WTCP(0x7c84ddcf, 0x1da5f0ff), WTCP(0x7c6841db, 0x1e1d1b73),
|
||||
WTCP(0x7c4b33dc, 0x1e942a4d), WTCP(0x7c2db3ee, 0x1f0b1d1f), WTCP(0x7c0fc22a, 0x1f81f37c), WTCP(0x7bf15eac, 0x1ff8acf7),
|
||||
WTCP(0x7bd28991, 0x206f4923), WTCP(0x7bb342f3, 0x20e5c793), WTCP(0x7b938af1, 0x215c27dc), WTCP(0x7b7361a7, 0x21d2698f),
|
||||
WTCP(0x7b52c733, 0x22488c42), WTCP(0x7b31bbb2, 0x22be8f87), WTCP(0x7b103f43, 0x233472f3), WTCP(0x7aee5205, 0x23aa361a),
|
||||
WTCP(0x7acbf416, 0x241fd88e), WTCP(0x7aa92596, 0x249559e6), WTCP(0x7a85e6a5, 0x250ab9b4), WTCP(0x7a623764, 0x257ff78e),
|
||||
WTCP(0x7a3e17f2, 0x25f51307), WTCP(0x7a198872, 0x266a0bb5), WTCP(0x79f48904, 0x26dee12c), WTCP(0x79cf19cb, 0x27539302),
|
||||
WTCP(0x79a93ae9, 0x27c820ca), WTCP(0x7982ec80, 0x283c8a1b), WTCP(0x795c2eb5, 0x28b0ce8a), WTCP(0x793501a9, 0x2924edac),
|
||||
WTCP(0x790d6581, 0x2998e716), WTCP(0x78e55a62, 0x2a0cba5e), WTCP(0x78bce070, 0x2a80671b), WTCP(0x7893f7d1, 0x2af3ece2),
|
||||
WTCP(0x786aa0a9, 0x2b674b49), WTCP(0x7840db1f, 0x2bda81e6), WTCP(0x7816a759, 0x2c4d9050), WTCP(0x77ec057d, 0x2cc0761e),
|
||||
WTCP(0x77c0f5b3, 0x2d3332e5), WTCP(0x77957822, 0x2da5c63e), WTCP(0x77698cf3, 0x2e182fbe), WTCP(0x773d344d, 0x2e8a6efd),
|
||||
WTCP(0x77106e58, 0x2efc8393), WTCP(0x76e33b3f, 0x2f6e6d16), WTCP(0x76b59b2a, 0x2fe02b1e), WTCP(0x76878e43, 0x3051bd43),
|
||||
WTCP(0x765914b5, 0x30c3231d), WTCP(0x762a2eaa, 0x31345c44), WTCP(0x75fadc4d, 0x31a56850), WTCP(0x75cb1dca, 0x321646d9),
|
||||
WTCP(0x759af34c, 0x3286f779), WTCP(0x756a5cff, 0x32f779c7), WTCP(0x75395b10, 0x3367cd5d), WTCP(0x7507edac, 0x33d7f1d3),
|
||||
WTCP(0x74d61500, 0x3447e6c3), WTCP(0x74a3d13a, 0x34b7abc6), WTCP(0x74712288, 0x35274076), WTCP(0x743e0918, 0x3596a46c),
|
||||
WTCP(0x740a8519, 0x3605d743), WTCP(0x73d696bb, 0x3674d894), WTCP(0x73a23e2d, 0x36e3a7fa), WTCP(0x736d7b9f, 0x3752450f),
|
||||
WTCP(0x73384f41, 0x37c0af6d), WTCP(0x7302b945, 0x382ee6b0), WTCP(0x72ccb9db, 0x389cea72), WTCP(0x72965134, 0x390aba4f),
|
||||
WTCP(0x725f7f84, 0x397855e1), WTCP(0x722844fb, 0x39e5bcc5), WTCP(0x71f0a1cc, 0x3a52ee96), WTCP(0x71b8962b, 0x3abfeaf1),
|
||||
WTCP(0x7180224b, 0x3b2cb170), WTCP(0x71474660, 0x3b9941b1), WTCP(0x710e029e, 0x3c059b4f), WTCP(0x70d45738, 0x3c71bde8),
|
||||
WTCP(0x709a4465, 0x3cdda919), WTCP(0x705fca59, 0x3d495c7e), WTCP(0x7024e94b, 0x3db4d7b5), WTCP(0x6fe9a16f, 0x3e201a5b),
|
||||
WTCP(0x6fadf2fc, 0x3e8b240e), WTCP(0x6f71de2a, 0x3ef5f46c), WTCP(0x6f35632e, 0x3f608b13), WTCP(0x6ef88241, 0x3fcae7a1),
|
||||
WTCP(0x6ebb3b9a, 0x403509b4), WTCP(0x6e7d8f72, 0x409ef0ed), WTCP(0x6e3f7e01, 0x41089ce8), WTCP(0x6e010780, 0x41720d46),
|
||||
WTCP(0x6dc22c28, 0x41db41a5), WTCP(0x6d82ec32, 0x424439a6), WTCP(0x6d4347da, 0x42acf4e8), WTCP(0x6d033f58, 0x4315730c),
|
||||
WTCP(0x6cc2d2e9, 0x437db3b0), WTCP(0x6c8202c6, 0x43e5b676), WTCP(0x6c40cf2c, 0x444d7aff), WTCP(0x6bff3855, 0x44b500eb),
|
||||
WTCP(0x6bbd3e7f, 0x451c47dc), WTCP(0x6b7ae1e6, 0x45834f72), WTCP(0x6b3822c6, 0x45ea1750), WTCP(0x6af5015c, 0x46509f16),
|
||||
WTCP(0x6ab17de7, 0x46b6e668), WTCP(0x6a6d98a4, 0x471cece7), WTCP(0x6a2951d2, 0x4782b236), WTCP(0x69e4a9ae, 0x47e835f7),
|
||||
WTCP(0x699fa078, 0x484d77ce), WTCP(0x695a366f, 0x48b2775d), WTCP(0x69146bd3, 0x49173448), WTCP(0x68ce40e4, 0x497bae33),
|
||||
WTCP(0x6887b5e2, 0x49dfe4c2), WTCP(0x6840cb0e, 0x4a43d799), WTCP(0x67f980a8, 0x4aa7865b), WTCP(0x67b1d6f3, 0x4b0af0ae),
|
||||
WTCP(0x6769ce2f, 0x4b6e1637), WTCP(0x6721669f, 0x4bd0f69b), WTCP(0x66d8a085, 0x4c33917f), WTCP(0x668f7c25, 0x4c95e688),
|
||||
WTCP(0x6645f9c0, 0x4cf7f55d), WTCP(0x65fc199a, 0x4d59bda3), WTCP(0x65b1dbf8, 0x4dbb3f02), WTCP(0x6567411d, 0x4e1c791f),
|
||||
WTCP(0x651c494d, 0x4e7d6ba2), WTCP(0x64d0f4ce, 0x4ede1631), WTCP(0x648543e4, 0x4f3e7875), WTCP(0x643936d4, 0x4f9e9214),
|
||||
WTCP(0x63eccde5, 0x4ffe62b6), WTCP(0x63a0095c, 0x505dea05), WTCP(0x6352e980, 0x50bd27a7), WTCP(0x63056e98, 0x511c1b47),
|
||||
WTCP(0x62b798ea, 0x517ac48c), WTCP(0x626968be, 0x51d92321), WTCP(0x621ade5c, 0x523736ae), WTCP(0x61cbfa0b, 0x5294fedd),
|
||||
WTCP(0x617cbc14, 0x52f27b58), WTCP(0x612d24c0, 0x534fabcb), WTCP(0x60dd3457, 0x53ac8fde), WTCP(0x608ceb22, 0x5409273e),
|
||||
WTCP(0x603c496c, 0x54657194), WTCP(0x5feb4f7f, 0x54c16e8e), WTCP(0x5f99fda4, 0x551d1dd5), WTCP(0x5f485426, 0x55787f17),
|
||||
WTCP(0x5ef6534f, 0x55d391ff), WTCP(0x5ea3fb6c, 0x562e563a), WTCP(0x5e514cc8, 0x5688cb75), WTCP(0x5dfe47ad, 0x56e2f15d),
|
||||
WTCP(0x5daaec6a, 0x573cc79f), WTCP(0x5d573b49, 0x57964de9), WTCP(0x5d033497, 0x57ef83e9), WTCP(0x5caed8a2, 0x5848694d),
|
||||
WTCP(0x5c5a27b8, 0x58a0fdc3), WTCP(0x5c052224, 0x58f940fa), WTCP(0x5bafc837, 0x595132a2), WTCP(0x5b5a1a3d, 0x59a8d26a),
|
||||
WTCP(0x5b041885, 0x5a002001), WTCP(0x5aadc35e, 0x5a571b18)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \brief Helper table containing the length, rasterand shape mapping to individual window slope tables.
|
||||
* [0: sine ][0: radix2 raster ][ceil(log2(length)) length 4 .. 1024 ]
|
||||
* [1: 640 raster
|
||||
*/
|
||||
const PWord16 *const windowSlopes[1][2][8] =
|
||||
{
|
||||
{ /* Sine */
|
||||
{ /* Radix 2 */
|
||||
NULL,
|
||||
NULL,
|
||||
SineWindow16,
|
||||
SineWindow32,
|
||||
SineWindow64,
|
||||
SineWindow128,
|
||||
SineWindow256,
|
||||
NULL
|
||||
},
|
||||
{ /* 640 raster */
|
||||
NULL, /* 2.5 */
|
||||
NULL, /* 5 */
|
||||
SineWindow10,
|
||||
SineWindow20,
|
||||
SineWindow40,
|
||||
SineWindow80,
|
||||
SineWindow160,
|
||||
SineWindow320
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
#define DCTIV_SINETABLE SineTable512
|
||||
#define DCTIV_SINETABLE_SIZE_LD 9
|
||||
|
||||
#define DCTIV_SINETABLE320 SineTable320
|
||||
#define DCTIV_SINETABLE320_SIZE_LD 8
|
||||
|
||||
void BASOP_getTables(const PWord16 **ptwiddle, const PWord16 **sin_twiddle, Word16 *psin_step, Word16 length)
|
||||
{
|
||||
const PWord16 *twiddle;
|
||||
const PWord16 *sine;
|
||||
Word16 ld2_length, sin_step;
|
||||
|
||||
/* Get ld2 of length - 2 + 1
|
||||
-2: because first table entry is window of size 4
|
||||
+1: because we already include +1 because of ceil(log2(length)) */
|
||||
ld2_length = sub(16 -1 -1, norm_s(length));
|
||||
|
||||
/* Extract sort of "eigenvalue" (the 5 left most bits) of length. */
|
||||
SWITCH ( (unsigned short)lshl(length, sub(15, ld2_length) ) )
|
||||
{
|
||||
case 0xa000: /* 640 */
|
||||
move16();
|
||||
move16();
|
||||
sine = DCTIV_SINETABLE320;
|
||||
sin_step = shl(1, sub(DCTIV_SINETABLE320_SIZE_LD+1, ld2_length));
|
||||
twiddle = windowSlopes[0][1][sub(ld2_length,1)];
|
||||
BREAK;
|
||||
|
||||
case 0x8000: /* radix 2 */
|
||||
move16();
|
||||
move16();
|
||||
sine = DCTIV_SINETABLE;
|
||||
sin_step = shl(1, sub(DCTIV_SINETABLE_SIZE_LD+1, ld2_length));
|
||||
twiddle = windowSlopes[0][0][sub(ld2_length,2)];
|
||||
BREAK;
|
||||
|
||||
default: /* not instrumented, probably obsolete */
|
||||
sine = NULL;
|
||||
sin_step = 0;
|
||||
twiddle = NULL;
|
||||
BREAK;
|
||||
}
|
||||
|
||||
if (ptwiddle != NULL)
|
||||
{
|
||||
assert(twiddle != NULL || length == 0);
|
||||
move16();
|
||||
*ptwiddle = twiddle;
|
||||
}
|
||||
|
||||
if (sin_twiddle != NULL)
|
||||
{
|
||||
move16();
|
||||
*sin_twiddle = sine;
|
||||
}
|
||||
if ( psin_step != NULL )
|
||||
{
|
||||
assert(sin_step > 0 || length == 0);
|
||||
move16();
|
||||
*psin_step = sin_step;
|
||||
}
|
||||
}
|
||||
|
||||
const PWord16* getSineWindowTable(Word16 length)
|
||||
{
|
||||
const PWord16 *p = NULL;
|
||||
|
||||
switch (length)
|
||||
{
|
||||
case 10:
|
||||
p = SineWindow10;
|
||||
BREAK;
|
||||
case 16:
|
||||
p = SineWindow16;
|
||||
BREAK;
|
||||
case 20:
|
||||
p = SineWindow20;
|
||||
BREAK;
|
||||
case 30:
|
||||
p = SineWindow30;
|
||||
BREAK;
|
||||
case 32:
|
||||
p = SineWindow32;
|
||||
BREAK;
|
||||
case 40:
|
||||
p = SineWindow40;
|
||||
BREAK;
|
||||
case 48:
|
||||
p = SineWindow48;
|
||||
BREAK;
|
||||
case 60:
|
||||
p = SineWindow60;
|
||||
BREAK;
|
||||
case 70:
|
||||
p = SineWindow70;
|
||||
BREAK;
|
||||
case 96:
|
||||
p = SineWindow96;
|
||||
BREAK;
|
||||
case 112:
|
||||
p = SineWindow112;
|
||||
BREAK;
|
||||
case 120:
|
||||
p = SineWindow120;
|
||||
BREAK;
|
||||
case 140:
|
||||
p = SineWindow140;
|
||||
BREAK;
|
||||
case 180:
|
||||
p = SineWindow180;
|
||||
BREAK;
|
||||
case 224:
|
||||
p = SineWindow224;
|
||||
BREAK;
|
||||
case 280:
|
||||
p = SineWindow280;
|
||||
BREAK;
|
||||
case 420:
|
||||
p = SineWindow420;
|
||||
BREAK;
|
||||
}
|
||||
|
||||
assert(p != NULL);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __BASOP_UTIL_ROM_H__
|
||||
#define __BASOP_UTIL_ROM_H__
|
||||
|
||||
#include "typedef.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
#define LD_INT_TAB_LEN 120
|
||||
#define INV_TABLE_SIZE 256
|
||||
#define SQRT_TABLE_SIZE 256
|
||||
|
||||
#ifndef CHEAP_NORM_SIZE
|
||||
#define CHEAP_NORM_SIZE 161
|
||||
#endif
|
||||
|
||||
#define MINSFTAB 7
|
||||
#define MAXSFTAB 25
|
||||
|
||||
/**
|
||||
* \brief Lookup-Table for binary logarithm
|
||||
*/
|
||||
extern const Word16 ldCoeff[7];
|
||||
|
||||
/**
|
||||
\brief Lookup-Table for binary power algorithm
|
||||
*/
|
||||
extern const UWord32 exp2_tab_long[32];
|
||||
|
||||
/**
|
||||
\brief Lookup-Table for binary power algorithm
|
||||
*/
|
||||
extern const UWord32 exp2w_tab_long[32];
|
||||
|
||||
/**
|
||||
\brief Lookup-Table for binary power algorithm
|
||||
*/
|
||||
extern const UWord32 exp2x_tab_long[32];
|
||||
|
||||
/**
|
||||
\brief Lookup-Table for integer binary logarithm
|
||||
*/
|
||||
extern const Word32 ldIntCoeff[LD_INT_TAB_LEN];
|
||||
|
||||
/**
|
||||
* \brief Lookup-Table for 1/x
|
||||
*/
|
||||
extern const Word16 invTable[INV_TABLE_SIZE+1];
|
||||
|
||||
/**
|
||||
* \brief 1/x, x=[0,1,2,3...] table
|
||||
*/
|
||||
extern const Word16 InvIntTable[65];
|
||||
|
||||
/**
|
||||
* \brief Lookup-Table for Squareroot
|
||||
*/
|
||||
extern const Word16 sqrtTable[SQRT_TABLE_SIZE+1];
|
||||
extern const Word16 invSqrtTable[SQRT_TABLE_SIZE+1];
|
||||
|
||||
extern const Word32 BASOP_util_normReciprocal[CHEAP_NORM_SIZE];
|
||||
extern const Word16 f_atan_expand_range[MAXSFTAB-(MINSFTAB-1)];
|
||||
|
||||
/**
|
||||
* \ brief Sine table
|
||||
*/
|
||||
extern const PWord16 SineTable512[257];
|
||||
extern const PWord16 SineTable480[241];
|
||||
extern const PWord16 SineTable400[201];
|
||||
extern const PWord16 SineTable384[193];
|
||||
extern const PWord16 SineTable320[161];
|
||||
|
||||
/**
|
||||
* \ brief Lookup for sine tables and windows.
|
||||
*/
|
||||
void BASOP_getTables(const PWord16 **ptwiddle, const PWord16 **sin_twiddle, Word16 *sin_step, Word16 length);
|
||||
const PWord16* getSineWindowTable(Word16 length);
|
||||
|
||||
#endif
|
||||
Executable
+21498
File diff suppressed because it is too large
Load Diff
Executable
+1250
File diff suppressed because it is too large
Load Diff
Executable
+346
@@ -0,0 +1,346 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Common prototypes */
|
||||
#include "prot_fx.h" /* Common prototypes */
|
||||
#include "cnst_fx.h"
|
||||
#include "stl.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Rescale_exc:
|
||||
*
|
||||
* Find absolute maximum of excitation
|
||||
* Fin scaling factor to apply the excitation and its related memory
|
||||
* Scale excitation and total excitation (exc2)
|
||||
*-------------------------------------------------------------------*/
|
||||
Word16 Rescale_exc(
|
||||
Word16 dct_post_old_exc_fx[], /* i/o: Music post processing memory */
|
||||
Word16 exc[], /* i/o: excitation to rescale Q_exc */
|
||||
Word16 bwe_exc[],
|
||||
Word16 *last_exc_dct_in,
|
||||
Word16 lg, /* i : frame size */
|
||||
Word16 lg32,
|
||||
Word32 L_gain_code, /* i : decoded codebook gain Q16 */
|
||||
Word16 *sQ_exc, /* i/o: Excitation scaling factor */
|
||||
Word16 *sQsubfr, /* i/o: Past excitation scaling factors */
|
||||
Word16 exc2[], /* o : local excitation vector */
|
||||
Word16 i_subfr, /* i : subframe number */
|
||||
const Word16 coder_type
|
||||
)
|
||||
{
|
||||
Word16 i, tmp, max, new_Q;
|
||||
|
||||
/*-------------------------------------------
|
||||
* find maximum of absolute excitation
|
||||
*-------------------------------------------*/
|
||||
max = s_max(abs_s(exc[0]), 1);
|
||||
FOR (i = 1; i < lg; i++)
|
||||
{
|
||||
tmp = abs_s(exc[i]);
|
||||
max = s_max(max, tmp);
|
||||
}
|
||||
|
||||
/*----------------------------------------------
|
||||
* find scaling (tmp) to set max = [2048..4096[
|
||||
*----------------------------------------------*/
|
||||
tmp = sub(add(norm_s(max), *sQ_exc), 3);
|
||||
tmp = s_min(tmp, 12);
|
||||
|
||||
/*----------------------------------------------
|
||||
* find scaling (new_Q) to keep gain_code < 2048
|
||||
*----------------------------------------------*/
|
||||
|
||||
new_Q = add(tmp, 1);
|
||||
tmp = sub(norm_l(L_or(L_gain_code, 1)), 3); /* to get to 0x08000000L (L_or with 1 to avoid norm_l(0)) */
|
||||
tmp = s_min(tmp, new_Q);
|
||||
tmp = s_max(tmp, 0);
|
||||
tmp = sub(tmp, 1);
|
||||
|
||||
/*#define REMOVE_EXCITATION_PER_FRAME_SCALING */
|
||||
|
||||
/*----------------------------------------------
|
||||
* new_Q = smallest Q since 4 subframes (20ms)
|
||||
*----------------------------------------------*/
|
||||
IF( sub( coder_type, TRANSITION ) == 0 )
|
||||
{
|
||||
tmp = s_min(tmp, 7);
|
||||
}
|
||||
ELSE IF (sub(coder_type,INACTIVE)==0)
|
||||
{
|
||||
tmp = s_min(tmp, 13);
|
||||
}
|
||||
ELSE IF( sub(lg,L_SUBFR) > 0 )/* --> can only happen in AUDIO mode */
|
||||
{
|
||||
tmp = s_min(tmp, 4); /* Limitation of the scaling gain because the frequency domain will add much more energy to the excitation*/
|
||||
if( L_sub(L_abs(L_gain_code), 3276800) >= 0 ) /*(1-gain_pit)*past gain code*4 > 50 */
|
||||
{
|
||||
tmp = s_min(tmp, 2); /* Limitation of the scaling gain because the frequency domain might add much more energy to the excitation*/
|
||||
}
|
||||
}
|
||||
|
||||
new_Q = s_min(tmp, sQsubfr[0]);
|
||||
IF(sub(lg, L_SUBFR)==0)
|
||||
{
|
||||
FOR(i = L_Q_MEM-1; i >= 1; i--)
|
||||
{
|
||||
new_Q = s_min(new_Q, sQsubfr[i]);
|
||||
sQsubfr[i] = sQsubfr[i-1];
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
IF(sub(lg, 2*L_SUBFR)==0)
|
||||
{
|
||||
new_Q = s_min(new_Q, sQsubfr[L_Q_MEM-1]);
|
||||
FOR(i = L_Q_MEM-1; i >= 2; i--)
|
||||
{
|
||||
sQsubfr[i] = sQsubfr[1];
|
||||
move16();
|
||||
}
|
||||
sQsubfr[1] = tmp;
|
||||
move16();
|
||||
sQsubfr[0] = tmp;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
set16_fx(sQsubfr, tmp, L_Q_MEM);
|
||||
}
|
||||
}
|
||||
sQsubfr[0] = tmp;
|
||||
move16();
|
||||
|
||||
/*----------------------------------------------
|
||||
* rescale excitation and associated memories
|
||||
*----------------------------------------------*/
|
||||
|
||||
tmp = sub(new_Q, *sQ_exc);
|
||||
|
||||
IF (tmp != 0)
|
||||
{
|
||||
|
||||
Scale_sig(exc-L_EXC_MEM_DEC, add(L_EXC_MEM_DEC, lg), tmp);
|
||||
IF(last_exc_dct_in != NULL)
|
||||
{
|
||||
Scale_sig(last_exc_dct_in, L_FRAME, tmp);
|
||||
}
|
||||
IF(bwe_exc != NULL)
|
||||
{
|
||||
Scale_sig(bwe_exc-PIT16k_MAX*2, add(PIT16k_MAX*2, lg32), tmp);
|
||||
}
|
||||
IF(exc2 != NULL)
|
||||
{
|
||||
Scale_sig(exc2, i_subfr, tmp);
|
||||
}
|
||||
IF(dct_post_old_exc_fx != NULL)
|
||||
{
|
||||
Scale_sig(dct_post_old_exc_fx, DCT_L_POST-OFFSET2, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* scaling factor of excitation (-1..12) */
|
||||
*sQ_exc = new_Q;
|
||||
move16();
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Rescale_mem:
|
||||
*
|
||||
* this function should be called after excitation update (4 subfr) and before frame synthesis
|
||||
* Rescale excitation related memories
|
||||
*-------------------------------------------------------------------*/
|
||||
void Rescale_mem(
|
||||
const Word16 Q_exc, /* i : current excitation scaling (>=0) */
|
||||
Word16 *prev_Q_syn, /* i/o : scaling factor of previous frame */
|
||||
Word16 *Q_syn, /* i/o : scaling factor of frame */
|
||||
Word16 *mem_syn2, /* i/o : modified synthesis memory */
|
||||
Word16 *mem_syn_clas_estim_fx, /* i/o : old 12k8 core memory for classification */
|
||||
const Word16 MaxScaling, /* i: Minimal difference between excitation scaling and synthesis scaling */
|
||||
Word16 *mem_deemph, /* i/o: speech deemph filter memory */
|
||||
Word16 *pst_old_syn, /* i/o: psfiler */
|
||||
Word16 *pst_mem_deemp_err, /* i/o: psfiler */
|
||||
Word16 *mem_agc,
|
||||
PFSTAT *pf_stat, /* i/o: All memories related to NB post filter */
|
||||
const Word16 Vad_flag,
|
||||
const Word16 Cna_flag,
|
||||
const Word16 *tmp_buffer /* tmp_buffer in Q-1 */
|
||||
)
|
||||
{
|
||||
Word16 exp_scale, new_Q, tmp, i;
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* find scaling of synthesis (based on min of current frame and last frame)
|
||||
* scaling factor of synthesis (-1..6)
|
||||
*-------------------------------------------------------------------*/
|
||||
new_Q = sub(Q_exc, MaxScaling);
|
||||
tmp = 1;
|
||||
move16();
|
||||
IF(tmp_buffer != NULL)
|
||||
{
|
||||
/* use the temporary synthesis in Q-1 to estimate the scaling */
|
||||
FOR (i = 0; i < L_FRAME; i++)
|
||||
{
|
||||
tmp = s_max(abs_s(tmp_buffer[i]), tmp);
|
||||
}
|
||||
/* we add Q_syn which represents the actual scaling of the memories prev_Q_syn represents the last potential scaling */
|
||||
tmp = sub(add(norm_s(tmp), -1), 3); /* -2 ... 12 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
FOR (i = 0; i < M; i++)
|
||||
{
|
||||
tmp = s_max(abs_s(mem_syn2[i]), tmp);
|
||||
tmp = s_max(abs_s(pst_old_syn[i]), tmp);
|
||||
tmp = s_max(abs_s(mem_syn_clas_estim_fx[i]), tmp);
|
||||
}
|
||||
FOR (; i < L_SUBFR; i++)
|
||||
{
|
||||
tmp = s_max(abs_s(pst_old_syn[i]), tmp);
|
||||
tmp = s_max(abs_s(mem_syn_clas_estim_fx[i]), tmp);
|
||||
}
|
||||
FOR (; i < L_SYN_MEM_CLAS_ESTIM; i++)
|
||||
{
|
||||
tmp = s_max(abs_s(mem_syn_clas_estim_fx[i]), tmp);
|
||||
tmp = s_max(abs_s(pst_old_syn[i]), tmp);
|
||||
}
|
||||
FOR (; i < NBPSF_PIT_MAX; i++)
|
||||
{
|
||||
tmp = s_max(abs_s(pst_old_syn[i]), tmp);
|
||||
}
|
||||
/* we add Q_syn which represents the actual scaling of the memories prev_Q_syn represents the last potential scaling */
|
||||
tmp = sub(add(norm_s(tmp), *Q_syn), 2); /* -2 ... 12 */
|
||||
}
|
||||
|
||||
|
||||
IF(Vad_flag != 0)
|
||||
{
|
||||
new_Q = s_min(sub(Q_exc,2), tmp);
|
||||
}
|
||||
ELSE IF(Cna_flag != 0)
|
||||
{
|
||||
new_Q = s_min(Q_exc, sub(tmp, 2));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
new_Q = s_min(Q_exc, tmp);
|
||||
}
|
||||
new_Q = s_min(new_Q, 12); /* */
|
||||
new_Q = s_max(new_Q, -1); /* */
|
||||
|
||||
/*#define REMOVE_SYNTHESIS_PER_FRAME_SCALING */
|
||||
tmp = s_min(new_Q, *prev_Q_syn);
|
||||
*prev_Q_syn = new_Q;
|
||||
move16();
|
||||
|
||||
exp_scale = sub(tmp, *Q_syn);
|
||||
*Q_syn = tmp;
|
||||
move16();
|
||||
|
||||
/* rescale synthesis memory (mem_syn2) */
|
||||
Scale_sig(mem_syn2, M, exp_scale);
|
||||
Scale_sig(mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM, exp_scale);
|
||||
/*Scale_sig(core_old_syn, L_SYN_MEM, exp_scale);*/
|
||||
Scale_sig(mem_deemph, 1, exp_scale);
|
||||
Scale_sig(pst_old_syn, NBPSF_PIT_MAX, exp_scale);
|
||||
Scale_sig(pst_mem_deemp_err, 1, exp_scale);
|
||||
Scale_sig(pf_stat->mem_pf_in, L_SUBFR, exp_scale); /* NB post_filter mem */
|
||||
Scale_sig(pf_stat->mem_res2, DECMEM_RES2, exp_scale); /* NB post_filter mem */
|
||||
Scale_sig(pf_stat->mem_stp, L_SUBFR, exp_scale); /* NB post_filter mem */
|
||||
Scale_sig(mem_agc, 1, exp_scale); /* NB post_filter mem */
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Scale_sig32
|
||||
* Note: In order to save complexity, call function only, if exp0 != 0
|
||||
* Up/down scale a 32 bits vector
|
||||
*-------------------------------------------------------------------*/
|
||||
void scale_sig32(
|
||||
Word32 x[], /* i/o: signal to scale Qx */
|
||||
const Word16 lg, /* i : size of x[] Q0 */
|
||||
const Word16 exp0 /* i : exponent: x = round(x << exp) Qx exp */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
|
||||
FOR (i = 0; i < lg; i++)
|
||||
{
|
||||
/* saturation can occur here */
|
||||
x[i] = L_shl(x[i], exp0);
|
||||
move32();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Rescale_mem:
|
||||
*
|
||||
* this function should be called after excitation update (4 subfr) and before frame synthesis
|
||||
* Rescale excitation related memories
|
||||
*-------------------------------------------------------------------*/
|
||||
Word16 rescale_mem(
|
||||
const Word16 *Q_exc, /* i : current excitation scaling (>=0) */
|
||||
Word16 *prev_Q_syn, /* i/o : scaling factor of previous frame */
|
||||
Word16 *Q_syn, /* i/o : scaling factor of frame */
|
||||
Word16 *mem_syn2, /* i/o : modified synthesis memory */
|
||||
Word16 *syn, /* i/o : synthesis to rescale Q_syn */
|
||||
Word16 mem_len, /* i : lenght of modified synthesis memory */
|
||||
Word16 i_subfr /* i : subframe number */
|
||||
)
|
||||
{
|
||||
Word16 exp_scale, new_Q, tmp;
|
||||
Word16 i, max16, max_scale;
|
||||
|
||||
max16 = 0;
|
||||
move16();
|
||||
FOR (i = 0; i < mem_len; i++ )
|
||||
{
|
||||
max16 = s_max(max16, abs_s(mem_syn2[i]));
|
||||
}
|
||||
IF( syn != NULL )
|
||||
{
|
||||
FOR (i = 0; i < i_subfr; i++ )
|
||||
{
|
||||
max16 = s_max(max16, abs_s(syn[i]));
|
||||
}
|
||||
}
|
||||
max_scale = 15;
|
||||
move16();
|
||||
IF(max16 > 0)
|
||||
{
|
||||
max_scale = add(norm_s(max16), -3);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* find scaling of synthesis (based on min of current frame and last frame)
|
||||
* scaling factor of synthesis (-1..6)
|
||||
*-------------------------------------------------------------------*/
|
||||
new_Q = sub(*Q_exc, 3);
|
||||
new_Q = s_max(new_Q, -1);
|
||||
|
||||
tmp = add(max_scale, *Q_syn);
|
||||
if( sub(s_min(new_Q, *prev_Q_syn), tmp) > 0)
|
||||
{
|
||||
new_Q = s_max(tmp, -1);
|
||||
}
|
||||
|
||||
tmp = s_min(new_Q, *prev_Q_syn);
|
||||
*prev_Q_syn = new_Q;
|
||||
move16();
|
||||
|
||||
exp_scale = sub(tmp, *Q_syn);
|
||||
*Q_syn = tmp;
|
||||
move16();
|
||||
/* rescale synthesis memory (mem_syn2) */
|
||||
Scale_sig(mem_syn2, mem_len, exp_scale);
|
||||
IF(syn != NULL)
|
||||
{
|
||||
Scale_sig(syn, i_subfr, exp_scale);
|
||||
}
|
||||
|
||||
return exp_scale;
|
||||
}
|
||||
Executable
+245
@@ -0,0 +1,245 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
#include "basop_mpy.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
#define BIN_4000 80 /* The frequency bin corresponding to 4kHz */
|
||||
#define MAX_BANDEXC 20
|
||||
|
||||
#define NB_TH3_MIN 30
|
||||
#define NB_TH1_MIN 30
|
||||
|
||||
#define TH_0_MAX_FX 9600 /* Q11 -> 1.5*3.125 */
|
||||
#define TH_1_MAX_FX 8640 /* Q11 -> 1.5*2.8125 */
|
||||
#define TH_2_MAX_FX 6720 /* Q11 -> 1.5*2.1875 */
|
||||
#define TH_3_MAX_FX 5760 /* Q11 -> 1.5*1.875 */
|
||||
|
||||
#define TH_UP_FX 320 /* Q11 -> 0.15625 */
|
||||
#define TH_DW_FX 320 /* Q11 -> 0.15625 */
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* stab_est()
|
||||
*
|
||||
* Signal stability estimation based on energy variation
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
Word16 stab_est_fx(
|
||||
Word16 etot, /* i : Total energy of the current frame */
|
||||
Word16 *lt_diff_etot, /* i/o : Long term total energy variation */
|
||||
Word16 *mem_etot, /* i/o : Total energy memory */
|
||||
Word16 *nb_thr_3, /* i/o : Number of consecutives frames of level 3 */
|
||||
Word16 *nb_thr_1, /* i/o : Number of consecutives frames of level 1 */
|
||||
Word16 *thresh, /* i/o : Detection thresold */
|
||||
Word16 *last_music_flag,/* i/o : Previous music detection ouptut */
|
||||
Word16 vad_flag
|
||||
)
|
||||
{
|
||||
Word16 i, music_flag2, tmp16, exp1, exp2;
|
||||
Word16 mean_diff;
|
||||
Word16 dev;
|
||||
Word32 L_tmp;
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* Find mean of the past MAX_LT frames energy variation
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
L_tmp = L_deposit_l(0);
|
||||
FOR (i = 1; i<MAX_LT; i++)
|
||||
{
|
||||
/*mean_diff += lt_diff_etot[i-1] * INV_MAX_LT; divide by MAX_LT */
|
||||
L_tmp = L_mac(L_tmp, lt_diff_etot[i-1], INV_MAX_LT_FX);
|
||||
lt_diff_etot[i-1] = lt_diff_etot[i];
|
||||
move16();
|
||||
}
|
||||
/*mean_diff += lt_diff_etot[i-1] * INV_MAX_LT; */ /* divide by MAX_LT */
|
||||
L_tmp = L_mac(L_tmp, lt_diff_etot[i-1], INV_MAX_LT_FX);
|
||||
mean_diff = round_fx(L_tmp); /*Q8 */
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* Find statistical deviation of the energy variation history
|
||||
* against the last 15 frames
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
tmp16 = sub(lt_diff_etot[MAX_LT-15], mean_diff);
|
||||
L_tmp = L_mult0(tmp16, tmp16);
|
||||
FOR(i = MAX_LT-15+1; i<MAX_LT; i++)
|
||||
{
|
||||
/*fcorr += ftmp_c*ftmp_c;*/
|
||||
tmp16 = sub(lt_diff_etot[i], mean_diff);
|
||||
L_tmp = L_mac0(L_tmp, tmp16, tmp16);
|
||||
}
|
||||
/*------------------------------------------------------------------------*
|
||||
* Update
|
||||
*------------------------------------------------------------------------*/
|
||||
lt_diff_etot[i-1] = sub(etot, *mem_etot);
|
||||
move16();
|
||||
*mem_etot = etot;
|
||||
move16();
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* Compute statistical deviation
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
/* dev = (float)0.7745967f*sqrt(fcorr / 15); */
|
||||
L_tmp = Mpy_32_16_1(L_tmp, 1311); /*-> 1/25 (1/(MAX_LT-15))*/
|
||||
|
||||
exp1 = norm_l(L_tmp);
|
||||
L_tmp = L_shl(L_tmp, exp1);
|
||||
tmp16 = round_fx(L_tmp);
|
||||
|
||||
exp2 = sub(31, exp1);
|
||||
L_tmp = Isqrt_lc(L_tmp, &exp2);
|
||||
L_tmp = Mpy_32_16_1(L_tmp, tmp16); /* we now have sqrt(L_corr) Q24 (8+16)*/
|
||||
exp2 = sub(31-15, sub(exp1, exp2)); /* for Q8 (because of -8^2 from Etot)*/
|
||||
|
||||
L_tmp = L_shl(L_tmp, exp2); /* Q8 + Q16*/
|
||||
dev = extract_h(L_shl(L_tmp, 3)); /* Q(24+3-16) -> Q11 */
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* State machine to decide level of inter-harmonic noise reduction and
|
||||
* (only if this frame is GOOD or if we are already far from NB_BFI_THR)
|
||||
* (if music_flag2 is 0, the spectral modification is deactivated, otherwise, it is activated)
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
music_flag2 = 0;
|
||||
move16();/* deactivate spectral modification (if music_flag2 != 0 is activated) */
|
||||
test();
|
||||
/*--------------------------------------------------------------------*
|
||||
* statistical deviation < thresh3 and last signal category type >= 3
|
||||
* (last category was "tonal" and the new one is "very tonal")
|
||||
*--------------------------------------------------------------------*/
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF ((sub(dev, thresh[3])< 0 ) && (sub(*last_music_flag,3) >= 0) )
|
||||
{
|
||||
music_flag2 = 4;
|
||||
move16();
|
||||
*nb_thr_3 += 1;
|
||||
move16();
|
||||
*nb_thr_1 = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* statistical deviation < thresh2 and last signal category type >= 2
|
||||
* (last category was "moderatly tonal" and the new one is a "tonal" )
|
||||
*--------------------------------------------------------------------*/
|
||||
ELSE IF ((sub(dev, thresh[2])< 0 ) && (sub(*last_music_flag,2) >= 0) )
|
||||
{
|
||||
music_flag2 = 3;
|
||||
move16();
|
||||
*nb_thr_3 += 1;
|
||||
move16();
|
||||
*nb_thr_1 = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* statistical deviation < thresh1 and last signal category type >= 1
|
||||
* (last category was "slightly tonal" and the new one is a "moderatly tonal")
|
||||
*--------------------------------------------------------------------*/
|
||||
ELSE IF ((sub(dev, thresh[1])< 0 ) && (sub(*last_music_flag,1) >= 0) )
|
||||
{
|
||||
music_flag2 = 2;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* statistical deviation < thresh0
|
||||
* (last category was "not tonal" and the new one is "slightly tonal")
|
||||
*--------------------------------------------------------------------*/
|
||||
ELSE IF ((sub(dev, thresh[0]) < 0 ) )
|
||||
{
|
||||
music_flag2 = 1;
|
||||
move16();/* [2000, 4000] Hz */
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* statistical deviation > thresh0
|
||||
* (Statistical deviation is high: the new tonal category is not tonal)
|
||||
*--------------------------------------------------------------------*/
|
||||
ELSE
|
||||
{
|
||||
*nb_thr_1 = add(*nb_thr_1,1);
|
||||
*nb_thr_3 = 0;
|
||||
move16();
|
||||
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* Update the thresholds
|
||||
*------------------------------------------------------------------------*/
|
||||
IF (sub(*nb_thr_3,NB_TH3_MIN) > 0)
|
||||
{
|
||||
|
||||
/* the number of consecutive categories type 3 or 4 (most tonal and tonal) */
|
||||
/* is greater than 30 frames ->increase the deviations thresholds to allow more variation */
|
||||
thresh[0] = add(thresh[0], TH_UP_FX);
|
||||
move16(); /*Q11 */
|
||||
thresh[1] = add(thresh[1], TH_UP_FX);
|
||||
move16();
|
||||
thresh[2] = add(thresh[2], TH_UP_FX);
|
||||
move16();
|
||||
thresh[3] = add(thresh[3], TH_UP_FX);
|
||||
move16();
|
||||
|
||||
}
|
||||
ELSE IF (sub(*nb_thr_1,NB_TH1_MIN) > 0)
|
||||
{
|
||||
/* the number of consecutive categories type 0 (non tonal frames) */
|
||||
/* is greater than 30 frames -> decrease the deviations thresholds to allow less variation */
|
||||
thresh[0] = sub(thresh[0], TH_DW_FX);
|
||||
move16(); /*Q11 */
|
||||
thresh[1] = sub(thresh[1], TH_DW_FX);
|
||||
move16();
|
||||
thresh[2] = sub(thresh[2], TH_DW_FX);
|
||||
move16();
|
||||
thresh[3] = sub(thresh[3], TH_DW_FX);
|
||||
move16();
|
||||
}
|
||||
|
||||
/* limitation of the threshold (this local macro stores the highest of the two and it also
|
||||
counts the # of operations) */
|
||||
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
thresh[0] = s_max(thresh[0], TH_0_MIN2_FX);
|
||||
thresh[1] = s_max(thresh[1], TH_1_MIN2_FX);
|
||||
thresh[2] = s_max(thresh[2], TH_2_MIN2_FX);
|
||||
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
thresh[0] = s_min(thresh[0], TH_0_MAX_FX);
|
||||
thresh[1] = s_min(thresh[1], TH_1_MAX_FX);
|
||||
thresh[2] = s_min(thresh[2], TH_2_MAX_FX);
|
||||
move16();
|
||||
move16();
|
||||
thresh[3] = s_max(thresh[3], TH_3_MIN2_FX);
|
||||
thresh[3] = s_min(thresh[3], TH_3_MAX_FX);
|
||||
/*------------------------------------------------------------------------*
|
||||
* Final update
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
*last_music_flag = music_flag2;
|
||||
move16();
|
||||
if (vad_flag == 0)
|
||||
{
|
||||
|
||||
music_flag2 = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
return music_flag2;
|
||||
}
|
||||
Executable
+676
@@ -0,0 +1,676 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef STAT_COM_H
|
||||
#define STAT_COM_H
|
||||
|
||||
#include "options.h"
|
||||
#include "basop_util.h"
|
||||
#include "cnst_fx.h"
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* Declaration of structures
|
||||
*----------------------------------------------------------------------------------*/
|
||||
|
||||
/* Forward declaration of Decoder_State_fx */
|
||||
struct Decoder_State_fx;
|
||||
|
||||
/*-----------------------------------------------------------*
|
||||
* EV-VBR NB postfilter static variables
|
||||
*-----------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
Word16 on; /* On/off flag */
|
||||
Word16 reset; /* reset flag */
|
||||
Word16 mem_pf_in[L_SUBFR]; /* Input memory */
|
||||
Word16 mem_stp[L_SUBFR]; /* 1/A(gamma1) memory */
|
||||
Word16 mem_res2[DECMEM_RES2]; /* A(gamma2) residual */
|
||||
Word16 mem_zero[M]; /* null memory to compute i.r. of A(gamma2)/A(gamma1) */
|
||||
Word16 gain_prec; /* for gain adjustment */
|
||||
} PFSTAT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Word16 a_fx[MAXLAG_WI];
|
||||
Word16 b_fx[MAXLAG_WI];
|
||||
Word16 lag_fx;
|
||||
Word16 nH_fx;
|
||||
Word16 nH_4kHz_fx;
|
||||
Word16 upper_cut_off_freq_of_interest_fx;
|
||||
Word16 upper_cut_off_freq_fx;
|
||||
Word16 Fs_fx;
|
||||
Word16 Q;
|
||||
} DTFS_STRUCTURE_FX;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Word16 lead_sign_ind;
|
||||
UWord32 index, size;
|
||||
Word16 dim, k_val;
|
||||
} PvqEntry_fx;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UWord8 buf[MAX_SIZEBUF_PBITSTREAM];
|
||||
Word16 curPos;
|
||||
Word32 numByte;
|
||||
Word32 numbits;
|
||||
Word32 maxBytes;
|
||||
} BITSTREAM_FX, *PBITSTREAM_FX;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PBITSTREAM_FX bsInst;
|
||||
|
||||
Word32 low;
|
||||
Word32 high;
|
||||
|
||||
Word32 value;
|
||||
Word16 bits_to_follow;
|
||||
|
||||
Word32 num_bits;
|
||||
Word32 max_bits;
|
||||
|
||||
} ARCODEC_FX, *PARCODEC_FX;
|
||||
|
||||
/*---------------------------------------------------------------*
|
||||
* Encoder/Decoder Static RAM *
|
||||
*---------------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
/*Coding mode info*/
|
||||
Word16 mode_index;
|
||||
|
||||
/*LPC info*/
|
||||
Word8 midLpc; /*Flag for using or not mid LPC for the current frame*/
|
||||
Word8 midLpc_enable; /*Flag enabling or not the mid LPC for the current mode_index*/
|
||||
|
||||
/*ICB flags*/
|
||||
Word8 pre_emphasis;
|
||||
Word8 pitch_sharpening; /*Flag for triggering pitch sharpening*/
|
||||
Word8 phase_scrambling; /*Flag for triggering phase scrambling*/
|
||||
Word16 formant_enh; /*Flag for triggering formant enhancement: Q15 representing 0...1.0f */
|
||||
Word8 formant_tilt;
|
||||
|
||||
Word8 voice_tilt; /*Flag for triggering new voice factor tilt*/
|
||||
|
||||
Word16 formant_enh_num;
|
||||
Word16 formant_enh_den;
|
||||
|
||||
Word16 bpf_mode;
|
||||
|
||||
Word16 nrg_mode;
|
||||
Word16 nrg_bits;
|
||||
|
||||
Word16 ltp_mode;
|
||||
Word16 ltp_bits;
|
||||
|
||||
Word16 ltf_mode;
|
||||
Word16 ltf_bits;
|
||||
|
||||
Word16 gains_mode[NB_SUBFR16k];
|
||||
|
||||
Word16 fixed_cdk_index[NB_SUBFR16k];
|
||||
|
||||
} ACELP_config;
|
||||
|
||||
/*tns_base.h*/
|
||||
/** TNS configuration.
|
||||
* Use InitTnsConfiguration to initialize it.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Word16 maxOrder;
|
||||
|
||||
/** Maximum number of filters. */
|
||||
Word16 nMaxFilters;
|
||||
|
||||
/** Parameters for each TNS filter */
|
||||
struct TnsParameters const * pTnsParameters;
|
||||
|
||||
/** Lower borders for each filter.
|
||||
* Upper border for the first filter is nsbBorders-1.
|
||||
* Upper borders for other filters is the lower border of previous filter.
|
||||
*/
|
||||
Word16 iFilterBorders[TNS_MAX_NUM_OF_FILTERS+1];
|
||||
|
||||
} STnsConfig;
|
||||
|
||||
/** TNS filter.
|
||||
* Parameters that define a TNS filter.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** Number of subbands covered by the filter. */
|
||||
Word16 spectrumLength;
|
||||
/** Filter order. */
|
||||
Word16 order;
|
||||
/** Quantized filter coefficients. */
|
||||
Word16 coefIndex[TNS_MAX_FILTER_ORDER];
|
||||
/** Prediction gain. The ratio of a signal and TNS residual energy. */
|
||||
Word16 predictionGain; /* exponent = PRED_GAIN_E */
|
||||
/** Average squared filter coefficient. */
|
||||
Word16 avgSqrCoef; /* exponent = 0 */
|
||||
} STnsFilter;
|
||||
|
||||
/** TNS data.
|
||||
* TNS data describing all active filters.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** Number of active filters. */
|
||||
Word16 nFilters;
|
||||
/** Active filters. */
|
||||
STnsFilter filter[TNS_MAX_NUM_OF_FILTERS];
|
||||
} STnsData;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TNS_NO_ERROR = 0,
|
||||
TNS_FATAL_ERROR
|
||||
} TNS_ERROR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* TCX mdct window */
|
||||
const PWord16 *tcx_mdct_window;
|
||||
const PWord16 *tcx_mdct_window_half;
|
||||
const PWord16 *tcx_mdct_window_minimum;
|
||||
const PWord16 *tcx_mdct_window_trans;
|
||||
Word16 tcx_aldo_window_1[L_FRAME32k*9/32];
|
||||
PWord16 tcx_aldo_window_1_trunc[L_FRAME32k*7/32];
|
||||
PWord16 tcx_aldo_window_2[L_FRAME32k*7/32];
|
||||
Word16 last_aldo;
|
||||
|
||||
Word16 tcx5Size; /* Size of the TCX5 spectrum. Always 5ms. */
|
||||
|
||||
Word16 tcx_mdct_window_length;
|
||||
Word16 tcx_mdct_window_half_length; /*length of the "half" overlap window*/
|
||||
Word16 tcx_mdct_window_min_length; /* length of the "minimum" overlap */
|
||||
Word16 tcx_mdct_window_trans_length; /* length of the ACELP->TCX overlap */
|
||||
|
||||
Word16 tcx_mdct_window_delay; /*length of window delay*/
|
||||
|
||||
Word16 tcx_offset;
|
||||
Word16 tcx_mdct_window_length_old; /*for keeping old value for sample rate switching */
|
||||
|
||||
/* TCX mdct window */
|
||||
const PWord16 *tcx_mdct_windowFB;
|
||||
const PWord16 *tcx_mdct_window_halfFB;
|
||||
const PWord16 *tcx_mdct_window_minimumFB;
|
||||
const PWord16 *tcx_mdct_window_transFB;
|
||||
Word16 tcx_aldo_window_1_FB[L_FRAME_MAX*9/32];
|
||||
PWord16 tcx_aldo_window_1_FB_trunc[L_FRAME_MAX*7/32];
|
||||
PWord16 tcx_aldo_window_2_FB[L_FRAME_MAX*7/32];
|
||||
|
||||
Word16 tcx5SizeFB; /* Size of the TCX5 spectrum. Always 5ms. */
|
||||
|
||||
Word16 tcx_mdct_window_lengthFB;
|
||||
Word16 tcx_mdct_window_half_lengthFB; /*length of the "half" overlap window*/
|
||||
Word16 tcx_mdct_window_min_lengthFB; /* length of the "minimum" overlap */
|
||||
Word16 tcx_mdct_window_trans_lengthFB; /* length of the ACELP->TCX overlap */
|
||||
|
||||
Word16 tcx_mdct_window_delayFB; /*length of window delay*/
|
||||
Word16 tcx_offsetFB;
|
||||
|
||||
Word16 tcx_coded_lines; /* max number of coded lines, depending on bandwidth mode */
|
||||
|
||||
Word16 tcx_curr_overlap_mode; /* window overlap of current frame (0: full, 2: none, or 3: half) */
|
||||
Word16 tcx_last_overlap_mode; /* previous window overlap, i.e. left-side overlap of current frame */
|
||||
|
||||
/* FAC window */
|
||||
Word16 lfacNext;
|
||||
Word16 lfacNextFB;
|
||||
|
||||
/* TNS */
|
||||
Word8 fIsTNSAllowed;
|
||||
STnsConfig tnsConfig[2][2];
|
||||
STnsConfig const * pCurrentTnsConfig;
|
||||
|
||||
/*Quantization*/
|
||||
Word16 sq_rounding; /*set the sq deadzone (no deadzone=0.5f)*/
|
||||
Word8 tcxRateLoopOpt;
|
||||
|
||||
/*Bandwidth*/
|
||||
Word16 preemph_fac; /*preemphasis factor*/
|
||||
Word16 bandwidth;
|
||||
|
||||
/* Context HM - Residual Quantization*/
|
||||
Word8 ctx_hm; /*Flag for enabling Context HM*/
|
||||
Word8 resq; /*Flag for enabling Residual Quantization*/
|
||||
Word16 coder_type; /*INACTIVE, UNVOICED,VOICED,GENERIC*/
|
||||
|
||||
Word16 na_scale;
|
||||
|
||||
Word32 SFM2;
|
||||
} TCX_config;
|
||||
|
||||
/* prot.h */
|
||||
typedef struct
|
||||
{
|
||||
Word16 bits; /* bits per subframe */
|
||||
Word16 nbiter; /* number of iterations */
|
||||
Word16 alp; /* initial energy of all fixed pulses, exponent = ALP_E */
|
||||
Word8 nb_pulse; /* number of pulses */
|
||||
Word8 fixedpulses; /* number of pulses whose position is determined from correlation and not by iteration */
|
||||
Word8 nbpos[13]; /* number of positions tried in the pair-wise search */
|
||||
Word8 codetrackpos; /* ordering of tracks -mode */
|
||||
} PulseConfig;
|
||||
|
||||
/* fd_cng_common.h */
|
||||
/* CLDFB-based CNG setup */
|
||||
typedef struct
|
||||
{
|
||||
Word16 fftlen; /* FFT length */
|
||||
Word16 stopFFTbin; /* Number of FFT bins to be actually processed */
|
||||
Word16 numPartitions; /* Number of partitions */
|
||||
const Word16* sidPartitions; /* Upper boundaries for grouping the (sub)bands into partitions when transmitting SID frames (define as NULL pointer to avoid grouping) */
|
||||
|
||||
Word16 numShapingPartitions; /* Number of partitions */
|
||||
const Word16* shapingPartitions; /* Upper boundaries for grouping the (sub)bands into partitions for shaping at the decoder (define as NULL pointer to avoid grouping) */
|
||||
} FD_CNG_SETUP;
|
||||
|
||||
/* Scale setup */
|
||||
typedef struct
|
||||
{
|
||||
Word32 bitrateFrom;
|
||||
Word32 bitrateTo;
|
||||
|
||||
Word16 scale;
|
||||
|
||||
Word8 bwmode;
|
||||
|
||||
} SCALE_SETUP;
|
||||
|
||||
/* Arrays and variables common to encoder and decoder */
|
||||
typedef struct
|
||||
{
|
||||
FD_CNG_SETUP FdCngSetup;
|
||||
|
||||
Word16 numSlots; /* Number of time slots in CLDFB matrix */
|
||||
Word16 regularStopBand;/* Number of CLDFB bands to be considered */
|
||||
|
||||
Word16 numCoreBands; /* Number of core bands to be decomposed into FFT subbands */
|
||||
Word16 stopBand; /* Total number of (sub)bands to be considered */
|
||||
Word16 startBand; /* First (sub)band to be considered */
|
||||
Word16 stopFFTbin; /* Total number of FFT subbands */
|
||||
Word16 frameSize; /* Frame size in samples */
|
||||
Word16 fftlen; /* FFT length used for the decomposition */
|
||||
Word16 fftlenShift;
|
||||
Word16 fftlenFac;
|
||||
|
||||
Word16 timeDomainBuffer[L_FRAME16k];
|
||||
|
||||
Word32 fftBuffer[FFTLEN];
|
||||
Word16 *olapBufferAna; /* points to FD_CNG_DEC->olapBufferAna[320] in case of decoder */
|
||||
Word16 olapBufferSynth[FFTLEN];
|
||||
Word16 *olapBufferSynth2; /* points to FD_CNG_DEC->olapBufferSynth2[FFTLEN] in case of decoder */
|
||||
const PWord16 * olapWinAna;
|
||||
const PWord16 * olapWinSyn;
|
||||
|
||||
Word16 msM_win;
|
||||
Word16 msM_subwin;
|
||||
Word16 msFrCnt_init_counter; /* Frame counter at initialization */
|
||||
Word16 init_old;
|
||||
|
||||
Word16 msFrCnt_init_thresh;
|
||||
|
||||
Word16 msFrCnt; /* Frame counter */
|
||||
Word32 msAlphaCor[2]; /* Correction factor (smoothed) */
|
||||
Word16 msSlope[2];
|
||||
Word32 msQeqInvAv[2];
|
||||
Word16 msQeqInvAv_exp[2];
|
||||
Word16 msMinBufferPtr;
|
||||
|
||||
Word32 msPsdSum[2];
|
||||
Word32 msPeriodogSum[2];
|
||||
Word16 msPeriodogSum_exp[2];
|
||||
|
||||
Word16 offsetflag;
|
||||
|
||||
Word32 periodog[PERIODOGLEN]; /* Periodogram */
|
||||
Word16 periodog_exp;
|
||||
Word16 exp_cldfb_periodog;
|
||||
|
||||
Word32 cngNoiseLevel[FFTCLDFBLEN]; /* Noise level applied for the CNG in each (sub)band */
|
||||
Word16 cngNoiseLevelExp;
|
||||
Word16 seed; /* Seed memory (for random function) */
|
||||
|
||||
Word16 npart; /* Number of partitions */
|
||||
Word16 midband[NPART]; /* Central band of each partition */
|
||||
Word16 nFFTpart; /* Number of hybrid spectral partitions */
|
||||
Word16 part[NPART]; /* Partition upper boundaries (band indices starting from 0) */
|
||||
Word16 psize[NPART]; /* Partition sizes */
|
||||
Word16 psize_norm[NPART]; /* Partition sizes, fractional variable */
|
||||
Word16 psize_norm_exp; /* Partition sizes exponent for fractional variable */
|
||||
Word16 psize_inv[NPART]; /* Inverse of partition sizes */
|
||||
Word16 FFTscalingFactor; /* Squared ratio between core signal analysis FFT and noise estimator FFT */
|
||||
Word16 scalingFactor;
|
||||
Word16 invScalingFactor;
|
||||
Word16 nCLDFBpart; /* Number of CLDFB spectral partitions */
|
||||
Word16 CLDFBpart[NPARTCLDFB]; /* CLDFB Partition upper boundaries (band indices starting from 0 above the core coder bands) */
|
||||
Word16 CLDFBpsize_inv[NPARTCLDFB];/* Inverse of CLDFB partition sizes */
|
||||
|
||||
Word16 inactive_frame_counter;
|
||||
Word16 sid_frame_counter;
|
||||
Word16 active_frame_counter;
|
||||
|
||||
Word32 sidNoiseEst[NPART]; /* Transmitted noise level */
|
||||
Word16 sidNoiseEstExp;
|
||||
|
||||
Word16 frame_type_previous;
|
||||
|
||||
Word16 A_cng[M+1];
|
||||
Word16 exc_cng[L_FRAME16k];
|
||||
|
||||
Word32 CngBitrate;
|
||||
Word16 CngBandwidth;
|
||||
|
||||
Word16 flag_noisy_speech;
|
||||
Word16 likelihood_noisy_speech;
|
||||
}
|
||||
FD_CNG_COM;
|
||||
typedef FD_CNG_COM *HANDLE_FD_CNG_COM;
|
||||
|
||||
/*parameter_bitmaping.h*/
|
||||
/** Function that gets specific value from p.
|
||||
* @param p Pointer to a variable that can also be structure or array.
|
||||
* @param index Index of a variable when p is an array, otherwise 0.
|
||||
* @param pValue Pointer to the value.
|
||||
* @return Substructure associated with this value or NULL if there is none.
|
||||
*/
|
||||
typedef void const * (* TGetParamValue)(void const * p, Word16 index, Word16 * pValue);
|
||||
|
||||
/** Function that puts specific value to p.
|
||||
* @param p Pointer to a variable that can also be structure or array.
|
||||
* @param index Index of a variable when p is an array, otherwise 0.
|
||||
* @param value The value.
|
||||
* @return Substructure associated with this value or NULL if there is none.
|
||||
*/
|
||||
typedef void * (* TSetParamValue)(void * p, Word16 index, Word16 value);
|
||||
|
||||
/** Function that return required number of bits for a value when it is coded.
|
||||
* @param value The value.
|
||||
* @param index Index of a variable when it is an element of an array, otherwise 0.
|
||||
* @return Number of bits required to code the value.
|
||||
*/
|
||||
typedef Word16 (* TGetNumberOfBits)(Word16 value, Word16 index);
|
||||
|
||||
/** Function that encodes a value.
|
||||
* @param value The value.
|
||||
* @param index Index of a variable when it is an element of an array, otherwise 0.
|
||||
* @return Coded value.
|
||||
*/
|
||||
typedef Word16 (* TEncodeValue)(Word16 value, Word16 index);
|
||||
|
||||
/** Function that decodes a value.
|
||||
* @param st Decoder state.
|
||||
* @param index Index of a variable when it is an element of an array, otherwise 0.
|
||||
* @param pValue A pointer where the decoded value should be stored.
|
||||
* @return Number of bits read from the bitstream.
|
||||
*/
|
||||
typedef Word16 (* TDecodeValue)(struct Decoder_State_fx *st, Word16 index, Word16 * pValue);
|
||||
|
||||
/** Structure that defines mapping between a parameter and a bistream. */
|
||||
typedef struct ParamBitMap
|
||||
{
|
||||
/** Number of bits in a bitstream required for the parameter.
|
||||
* If nBits is equal to 0 then GetNumberOfBits is used.
|
||||
*/
|
||||
Word16 nBits;
|
||||
/** Function to get the number of bits required for a value of this parameter.
|
||||
* If nBits != 0 it is not used and can be set to NULL.
|
||||
* If fZeroAllowed == 0 then GetNumberOfBits must take care of this.
|
||||
*/
|
||||
TGetNumberOfBits GetNumberOfBits;
|
||||
/** If fZeroAllowed is 0 then the value can be zero.
|
||||
* If the value can't be zero then value-1 is stored in a bitstream.
|
||||
* If EncodeValue is not equal to NULL, then the encode/decode function
|
||||
* must take care of this flag - there is no additional processing in parameter bitmapping.
|
||||
* If EncodeValue is equal to NULL, then the encode/decode function takes care of this.
|
||||
*/
|
||||
Word8 fZeroAllowed;
|
||||
/** Function to get the value of this parameter.
|
||||
* The function returns a pointer to be used in functions in pSubParamBitMap.
|
||||
* If the function returns NULL then the same pointer as for the current
|
||||
* parameter is to be used.
|
||||
* The function should not do any additional processing if fZeroAllowed == 0,
|
||||
* but just set the value as it is.
|
||||
*/
|
||||
TGetParamValue GetParamValue;
|
||||
/** Function to set the value of this parameter.
|
||||
* The function returns a pointer to be used in functions in pSubParamBitMap.
|
||||
* If the function returns NULL then the same pointer as for the current
|
||||
* parameter is to be used.
|
||||
* The function should not do any additional processing if fZeroAllowed == 0,
|
||||
* but just set the value as it is.
|
||||
*/
|
||||
TSetParamValue SetParamValue;
|
||||
|
||||
/** Function to encode a value of this parameter.
|
||||
* When it is equal to NULL, fixed-width coding is used.
|
||||
* If fZeroAllowed == 0 then EncodeValue must take care of this.
|
||||
*/
|
||||
TEncodeValue EncodeValue;
|
||||
|
||||
/** Function to decode a value of this parameter.
|
||||
* When it is equal to NULL, fixed-width coding is used.
|
||||
* If fZeroAllowed == 0 then DecodeValue must take care of this.
|
||||
*/
|
||||
TDecodeValue DecodeValue;
|
||||
|
||||
/** Pointer to the map for substructure.
|
||||
* The number of structures is determined by this parameter's value.
|
||||
* NULL means that there is no substructure.
|
||||
*/
|
||||
struct ParamsBitMap const * pSubParamBitMap;
|
||||
} ParamBitMap;
|
||||
|
||||
/** Structure that defines mapping between parameters and a bistream. */
|
||||
typedef struct ParamsBitMap
|
||||
{
|
||||
/** Number of parameters in params. */
|
||||
Word16 nParams;
|
||||
/** Definition of the mapping for each parameter. */
|
||||
ParamBitMap params[NPARAMS_MAX];
|
||||
} ParamsBitMap;
|
||||
|
||||
/*tns_tables.h*/
|
||||
struct TnsParameters
|
||||
{
|
||||
/* Parameters for each TNS filter */
|
||||
Word16 startLineFrequency; /* Starting lower frequency of the TNS filter [20..16000] */
|
||||
Word16 nSubdivisions; /* Number of spectrum subdivisions in which the filter operates [1..8) */
|
||||
Word16 minPredictionGain; /* Minimum prediction gain required to turn on the TNS filter. Exponent = PRED_GAIN_E */
|
||||
Word16 minAvgSqrCoef; /* Minimum average square of coefficients required to turn on the TNS filter. Exponent = 0 */
|
||||
};
|
||||
|
||||
/**********************************************/
|
||||
/* Helper structures for hufmann table coding */
|
||||
/**********************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Word8 value;
|
||||
Word16 code;
|
||||
Word8 nBits;
|
||||
} Coding;
|
||||
|
||||
|
||||
/* Scale TCX setup */
|
||||
typedef struct
|
||||
{
|
||||
Word16 bwmode;
|
||||
|
||||
Word32 bitrateFrom;
|
||||
Word32 bitrateTo;
|
||||
|
||||
Word16 scale;
|
||||
|
||||
} SCALE_TCX_SETUP;
|
||||
|
||||
|
||||
/* glob_con.h */
|
||||
typedef struct
|
||||
{
|
||||
Word16 frame_bits; /*Bits per frame*/
|
||||
Word16 frame_net_bits; /*Net Bits per frame*/
|
||||
Word8 transmission_bits; /*max=1*/
|
||||
Word8 transmission_mode[2]; /*SID,VBR/CBR*/
|
||||
Word8 bandwidth_bits; /*max=2*/
|
||||
Word8 bandwidth_min; /*first valid bandwidth (NB,WB,SWB,FB)*/
|
||||
Word8 bandwidth_max; /*last valid bandwidth (NB,WB,SWB,FB)*/
|
||||
Word8 reserved_bits; /*max=1*/
|
||||
} FrameSizeParams;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Word16 lb_scale; /*!< Scale of low band area */
|
||||
Word16 lb_scale16; /*!< Scale of low band area */
|
||||
Word16 ov_lb_scale; /*!< Scale of adjusted overlap low band area */
|
||||
Word16 hb_scale; /*!< Scale of high band area */
|
||||
Word16 ov_hb_scale; /*!< Scale of adjusted overlap high band area */
|
||||
} CLDFB_SCALE_FACTOR;
|
||||
|
||||
struct CLDFB_FILTER_BANK
|
||||
{
|
||||
const Word16 *p_filter; /*!< Pointer to filter coefficients */
|
||||
|
||||
Word16 *FilterStates; /*!< Pointer to buffer of filter states */
|
||||
Word16 FilterStates_e[CLDFB_NO_COL_MAX+9]; /*!< Filter states time slot exponents */
|
||||
Word16 FilterStates_eg; /*!< Filter states current exponent */
|
||||
|
||||
Word16 p_filter_length; /*!< Size of prototype filter. */
|
||||
const Word16 *rRotVctr; /*!< Modulation tables. */
|
||||
const Word16 *iRotVctr;
|
||||
Word16 filterScale; /*!< filter scale */
|
||||
|
||||
Word16 synGain; /*!< gain for synthesis filterbank */
|
||||
|
||||
Word16 no_channels; /*!< Total number of channels (subbands) */
|
||||
Word16 no_col; /*!< Number of time slots */
|
||||
Word16 lsb; /*!< Top of low subbands */
|
||||
Word16 usb; /*!< Top of high subbands */
|
||||
Word16 zeros; /*!< number of zeros in filter coefficients */
|
||||
|
||||
Word16 anaScalefactor; /*!< Scale factor of analysis cldfb */
|
||||
Word16 synScalefactor; /*!< Scale factor of synthesis cldfb */
|
||||
Word16 outScalefactor; /*!< Scale factor of output data (syn only) */
|
||||
|
||||
Word16 synFilterHeadroom; /*!< Headroom for states in synthesis cldfb filterbank */
|
||||
|
||||
UWord16 flags; /*!< flags */
|
||||
|
||||
Word16 bandsToZero; /*!< additional bands which are zeroed in inverse modulation */
|
||||
|
||||
Word16 filtermode;
|
||||
|
||||
Word16 type;
|
||||
Word16 *memory;
|
||||
Word16 memory_length;
|
||||
Word16 scale;
|
||||
};
|
||||
|
||||
typedef struct CLDFB_FILTER_BANK *HANDLE_CLDFB_FILTER_BANK;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Word16 pGainTemp_m[CLDFB_NO_COL_MAX];
|
||||
Word16 pGainTemp_e[CLDFB_NO_COL_MAX];
|
||||
Word16 loBuffer[CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG];
|
||||
|
||||
Word16 cldfbExp;
|
||||
Word16 lastCldfbExp;
|
||||
} TEMPORAL_ENVELOPE_CODING_DECODER_FX;
|
||||
typedef TEMPORAL_ENVELOPE_CODING_DECODER_FX* HANDLE_TEC_DEC_FX;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Word16 loBuffer[CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC];
|
||||
Word16 loTempEnv[CLDFB_NO_COL_MAX];
|
||||
Word16 loTempEnv_ns[CLDFB_NO_COL_MAX];
|
||||
Word16 hiTempEnv[CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV];
|
||||
Word16 tranFlag;
|
||||
Word16 corrFlag;
|
||||
} TEMPORAL_ENVELOPE_CODING_ENCODER_FX;
|
||||
typedef TEMPORAL_ENVELOPE_CODING_ENCODER_FX* HANDLE_TEC_ENC_FX;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FRAME_0 = 0,
|
||||
FRAME_2 = 40,
|
||||
FRAME_2_4 = 48,
|
||||
FRAME_4 = 80,
|
||||
FRAME_5_6 = 112,
|
||||
FRAME_7_2 = 144,
|
||||
FRAME_8 = 160,
|
||||
FRAME_9_6 = 192,
|
||||
FRAME_13_2 = 264,
|
||||
FRAME_16_4 = 328,
|
||||
FRAME_24_4 = 488,
|
||||
FRAME_32 = 640,
|
||||
FRAME_48 = 960,
|
||||
FRAME_64 = 1280,
|
||||
FRAME_96 = 1920,
|
||||
FRAME_128 = 2560
|
||||
} FRAME_SIZE;
|
||||
|
||||
/*---------------------------------------------------------------*
|
||||
* IGF *
|
||||
*---------------------------------------------------------------*/
|
||||
typedef struct igf_grid_struct
|
||||
{
|
||||
Word16 swb_offset[IGF_MAX_SFB];
|
||||
Word16 swb_offset_len;
|
||||
Word16 startFrequency;
|
||||
Word16 stopFrequency;
|
||||
Word16 startLine;
|
||||
Word16 stopLine;
|
||||
Word16 startSfb; /* 15Q0, startSfb = [0, 11], IGF start sfb */
|
||||
Word16 stopSfb; /* 15Q0, stopSfb = [0, 22], IGF stop sfb */
|
||||
Word16 sfbWrap[IGF_MAX_TILES+1];
|
||||
Word16 sbWrap[IGF_MAX_TILES];
|
||||
Word16 nTiles; /* 15Q0, nTiles = [1, 4], number of tiles */
|
||||
Word16 minSrcSubband;
|
||||
Word16 minSrcFrequency;
|
||||
Word16 tile[IGF_MAX_TILES];
|
||||
Word16 infoIsRefined;
|
||||
Word16 infoGranuleLen; /* 15Q0, infoGranuleLen = [0, 1200], core coder granule length */
|
||||
Word16 infoTransFac; /* 1Q14 */
|
||||
Word16 whiteningThreshold[2][IGF_MAX_TILES]; /* 2Q13 */
|
||||
Word16 gFactor; /* 1Q14 */
|
||||
Word16 fFactor; /* 1Q14 */
|
||||
Word16 lFactor; /* 1Q14 */
|
||||
} IGF_GRID, *H_IGF_GRID;
|
||||
|
||||
typedef struct IGF_INFO_struct
|
||||
{
|
||||
Word16 nfSeed;
|
||||
Word32 sampleRate;
|
||||
Word16 frameLength;
|
||||
Word16 maxHopsize;
|
||||
IGF_GRID grid[IGF_NOF_GRIDS];
|
||||
Word16 bitRateIndex;
|
||||
} IGF_INFO, *H_IGF_INFO;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Word16 *indexBuffer;
|
||||
Word16 *peakIndices, *holeIndices;
|
||||
Word16 numPeakIndices, numHoleIndices;
|
||||
} CONTEXT_HM_CONFIG;
|
||||
|
||||
/* Returns: index of next coefficient */
|
||||
typedef Word16 (*get_next_coeff_function)(
|
||||
Word16 ii[2], /* i/o: coefficient indexes */
|
||||
Word16 *pp, /* o : peak(1)/hole(0) indicator */
|
||||
Word16 *idx, /* o : index in unmapped domain */
|
||||
CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */
|
||||
);
|
||||
|
||||
/*CLDFB-VAD*/
|
||||
|
||||
|
||||
#endif
|
||||
+420
@@ -0,0 +1,420 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "cnst_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
#define TILT_COMP_LIM_FX 24576 /* 0.75 in Q15 */
|
||||
#define GE_SHIFT 6
|
||||
#define P1 (32768-ISP_SMOOTHING_QUANT_A1_FX-1)
|
||||
#define P9 (32767-P1)
|
||||
|
||||
/*---------------------------------------------------------*
|
||||
* Local functions
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
static Word16 calc_tilt_fx(const Word16 *x, const Word16 Q_shift, const Word16 len);
|
||||
Word32 L_Sqrt_Q0(const Word32 x);
|
||||
/*--------------------------------------------------------------------*
|
||||
* stat_noise_uv_mod()
|
||||
*
|
||||
* Modifies excitation signal in stationary noise segments
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
void stat_noise_uv_mod_fx(
|
||||
const Word16 coder_type, /* i : Coder type */
|
||||
Word16 noisiness, /* i : noisiness parameter */
|
||||
const Word16 *lsp_old, /* i : old LSP vector at 4th sfr */
|
||||
const Word16 *lsp_new, /* i : LSP vector at 4th sfr */
|
||||
const Word16 *lsp_mid, /* i : LSP vector at 2nd sfr */
|
||||
Word16 *Aq, /* o : A(z) quantized for the 4 subframes */
|
||||
Word16 *exc2, /* i/o: excitation buffer */
|
||||
Word16 Q_exc, /* i : Q of exc2 excitation buffer [11..-1] expected */
|
||||
const Word16 bfi , /* i : Bad frame indicator */
|
||||
Word32 *ge_sm, /* i/o: smoothed excitation gain */
|
||||
Word16 *uv_count, /* i/o: unvoiced counter */
|
||||
Word16 *act_count, /* i/o: activation counter */
|
||||
Word16 lspold_s[], /* i/o: old LSP */
|
||||
Word16 *noimix_seed, /* i/o: mixture seed */
|
||||
Word16 *st_min_alpha, /* i/o: minimum alpha */
|
||||
Word16 *exc_pe, /* i/o: scale Q_stat_noise */
|
||||
const Word32 bitrate, /* i : core bitrate */
|
||||
const Word16 bwidth_fx, /* i : input bandwidth */
|
||||
Word16 *Q_stat_noise, /* i/o: noise scaling */
|
||||
Word16 *Q_stat_noise_ge /* i/o: noise scaling */
|
||||
)
|
||||
{
|
||||
Word16 exctilt; /* Q15 */
|
||||
Word32 vare; /* Q31 */
|
||||
Word16 randval; /* Q?? */
|
||||
Word16 alpha; /* Q15 */
|
||||
Word16 alpha_m1; /* (1-alpha) Q15 */
|
||||
Word16 min_alpha; /* Q15 */
|
||||
Word16 lspnew_s[M]; /* Same for all LSP (Q15) */
|
||||
Word16 oldlsp_mix[M];
|
||||
Word16 midlsp_mix[M];
|
||||
Word16 newlsp_mix[M];
|
||||
Word16 beta; /* Q15 */
|
||||
Word16 Noimix_fract; /* (noimix_fac - 1.0) in Q15 */
|
||||
/* noimix_fax * x <-> x + Noimix_fract * x */
|
||||
Word16 i_subfr;
|
||||
Word16 i, k;
|
||||
|
||||
/* Work variables for div and sqrt */
|
||||
Word16 tmp_nom,tmp_den,tmp_shift,tmp_res;
|
||||
Word16 Qdiff,Q_local; /* new Q to be used for states Exc_pe and Ge_sm, and Exc2_local */
|
||||
Word32 L_tmp_res,L_tmp, L_tmp3,L_Ge;
|
||||
|
||||
Word16 En_shift,Tmp;
|
||||
Word16 Exc2_local[L_FRAME]; /* local_copy in scaled Q_local*/
|
||||
|
||||
/*---------------------------------------------------------*
|
||||
* Init local variables
|
||||
*---------------------------------------------------------*/
|
||||
alpha = 32767;
|
||||
move16();
|
||||
min_alpha = 16384;
|
||||
move16();
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF (sub(coder_type,INACTIVE) == 0 && ( L_sub(bitrate,ACELP_9k60) == 0 || (L_sub(bitrate,ACELP_9k60) < 0 && sub(bwidth_fx,NB) > 0) ) )
|
||||
{
|
||||
min_alpha = *st_min_alpha;
|
||||
move16();
|
||||
/*---------------------------------------------------------*
|
||||
* decode noisiness parameter
|
||||
*---------------------------------------------------------*/
|
||||
IF (bfi == 0)
|
||||
{
|
||||
tmp_den = 31;
|
||||
move16();
|
||||
tmp_shift = norm_s(tmp_den);
|
||||
move16();
|
||||
L_tmp_res = L_deposit_h(noisiness);
|
||||
L_tmp_res = L_shl(L_tmp_res,sub(tmp_shift,1));
|
||||
tmp_den = shl(tmp_den,tmp_shift);
|
||||
move16();
|
||||
tmp_res = div_l(L_tmp_res,tmp_den);
|
||||
move16();
|
||||
min_alpha = add(tmp_res, 16384);
|
||||
move16();
|
||||
|
||||
/**st_min_alpha = sub(*st_min_alpha, 1638); move16();*/
|
||||
min_alpha = s_max(min_alpha, sub(*st_min_alpha, 1638));
|
||||
|
||||
*st_min_alpha = min_alpha;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*
|
||||
* Mix excitation signal with random noise
|
||||
*---------------------------------------------------------*/
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF ( sub(coder_type,INACTIVE) == 0 && ( L_sub(bitrate,ACELP_9k60) == 0 || (L_sub(bitrate,ACELP_9k60) < 0 && sub(bwidth_fx,NB) > 0) ) )
|
||||
{
|
||||
/* use a local working copy for scaling and filtering, not needed if input Q-range is fixed */
|
||||
Copy(exc2, Exc2_local, L_FRAME);
|
||||
|
||||
/* bound Q for internal use, optimization possible */
|
||||
Q_local = s_min(11, s_max(-1, Q_exc));
|
||||
/* local excitation Q and incoming excitation Q*/
|
||||
Qdiff = sub(Q_local, Q_exc);
|
||||
/* only shift if incoming Q is outside [11..-1] shift is done in energy calculations aswell */
|
||||
Scale_sig(Exc2_local, L_FRAME, Qdiff);
|
||||
/* current excitation Q and previous stat_noise states Q */
|
||||
Qdiff = sub(Q_local, *Q_stat_noise);
|
||||
|
||||
*Q_stat_noise_ge = GE_SHIFT;
|
||||
move16(); /* assign the fixed Q for Ge_sm */
|
||||
|
||||
IF (Qdiff != 0)
|
||||
{
|
||||
Scale_sig(exc_pe, 1, Qdiff);
|
||||
}
|
||||
|
||||
En_shift = 0;
|
||||
move16();
|
||||
if (sub(Q_local, 3) > 0)
|
||||
{
|
||||
/* increase margin for energy accumulation in calc_tilt and vare accumulation */
|
||||
En_shift = sub(Q_local, 3);
|
||||
}
|
||||
|
||||
IF (sub(min_alpha, TILT_COMP_LIM_FX) < 0)
|
||||
{
|
||||
FOR (i_subfr=0; i_subfr<L_FRAME; i_subfr+=L_SUBFR)
|
||||
{
|
||||
exctilt = calc_tilt_fx(&Exc2_local[i_subfr], En_shift, L_SUBFR); /*Q15 */
|
||||
exctilt = mult(shl(sub(TILT_COMP_LIM_FX, min_alpha), 2), exctilt); /*Q15 */
|
||||
|
||||
preemph_fx(&Exc2_local[i_subfr],exctilt,L_SUBFR,exc_pe);
|
||||
}
|
||||
}
|
||||
|
||||
(*uv_count)++;
|
||||
|
||||
IF (sub(*uv_count,START_NG) <= 0)
|
||||
{
|
||||
alpha = 32767;
|
||||
move16();
|
||||
*act_count = 3;
|
||||
move16();
|
||||
Copy(lsp_new, lspold_s, M);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
*uv_count = s_min(*uv_count , FULL_NG);
|
||||
|
||||
tmp_nom = sub(*uv_count,START_NG);
|
||||
tmp_den = sub(FULL_NG,START_NG);
|
||||
tmp_shift = norm_s(tmp_den);
|
||||
tmp_den = shl(tmp_den,tmp_shift);
|
||||
tmp_res = div_s(tmp_nom,tmp_den);
|
||||
tmp_res = shl(tmp_res,tmp_shift);
|
||||
alpha = add(32767, mult(tmp_res, sub(min_alpha, 32767)));
|
||||
|
||||
*act_count = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*
|
||||
* calculate lowpass filtered excitation gain
|
||||
*---------------------------------------------------------*/
|
||||
Tmp = shr(Exc2_local[0], En_shift);
|
||||
vare = L_mult(Tmp, Tmp); /* positive accumulation only */
|
||||
FOR (i=1; i<L_FRAME; i++)
|
||||
{
|
||||
Tmp = shr(Exc2_local[i], En_shift);
|
||||
vare = L_mac(vare, Tmp, Tmp); /* positive accumulation only */
|
||||
}
|
||||
|
||||
/* obtain Ge in Q_local with safety saturation */
|
||||
L_Ge = L_shl(L_Sqrt_Q0(L_shr(vare,1)),add(sub(*Q_stat_noise_ge,4),En_shift)); /* L_Ge in Q_local*/
|
||||
|
||||
/* st->ge_sm = ISP_SMOOTHING_QUANT_A1 * st->ge_sm + (1.0f-ISP_SMOOTHING_QUANT_A1) * ge */
|
||||
|
||||
IF ( sub(*uv_count,1) == 0)
|
||||
{
|
||||
*ge_sm = L_shr(L_Ge,Q_local);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_tmp = Mult_32_16(L_Ge,P1); /* 0.1*ge still in Q local */
|
||||
L_tmp3 = Mult_32_16(*ge_sm,P9); /* 0.9*ge_sm still in Q_ge */
|
||||
|
||||
*ge_sm = L_add(L_shr(L_tmp,Q_local),L_tmp3);
|
||||
move32(); /* addition in Q_ge domain*/
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* generate mixture of excitation and noise
|
||||
* float:
|
||||
* noimix_fac = 1.0f/(float)sqrt(alpha*alpha + (1-alpha)*(1-alpha))
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
beta = shl(sub(alpha, 16384), 1);
|
||||
alpha_m1 = sub(32767, alpha);
|
||||
L_tmp_res = L_mac(0, alpha, alpha);
|
||||
L_tmp_res = L_mac(L_tmp_res, alpha_m1, alpha_m1);
|
||||
tmp_den = round_fx(L_Frac_sqrtQ31(L_tmp_res));
|
||||
|
||||
tmp_nom = sub(32767, tmp_den);
|
||||
tmp_shift = norm_s(tmp_den);
|
||||
tmp_den = shl(tmp_den, tmp_shift);
|
||||
tmp_res = div_s(tmp_nom, tmp_den);
|
||||
|
||||
Noimix_fract = shr(tmp_res, tmp_shift); /* float value is in range 0.0 to 0.42 */
|
||||
|
||||
/* L_Ge might be 0 in unvoiced WB */
|
||||
L_Ge = L_max(L_Ge, 1);
|
||||
tmp_shift = norm_l(L_Ge);
|
||||
tmp_den = extract_h(L_shl(L_Ge, tmp_shift)); /* Q_local+Q_ge+tmp_shift-16 */
|
||||
tmp_res = div_s(1<<14, tmp_den); /* 15+14-Q_local-tmp_shift-Q_ge+16 */
|
||||
L_tmp_res = Mult_32_16(*ge_sm, tmp_res); /* Q_stat_noise_ge+45-Q_local-Q_ge-tmp_shift-15 */
|
||||
L_tmp_res = Mult_32_16(L_tmp_res, sub(32767, beta)); /*30-Q_local-tmp_shift+15-15 */
|
||||
L_tmp_res = L_add(L_shl(L_tmp_res, sub(add(Q_local, tmp_shift), 15)), beta); /* Q15 */
|
||||
tmp_res = extract_h(L_shl(L_tmp_res, 15)); /* 15+15-16=14 */
|
||||
|
||||
Noimix_fract = extract_l(Mult_32_16(L_tmp_res, Noimix_fract)); /*15+15-15 */
|
||||
|
||||
FOR (i=0; i<L_FRAME; i++)
|
||||
{
|
||||
/*--------------------------------------------------------------------*
|
||||
* flt: exc2[i] = noimix_fac*exc2[i] * alpha + st->ge_sm*Rnd*((1.0f)-alpha)
|
||||
* flt: exc2[i] = (noimix_fract*exc2[i]+exc2 )* alpha + st->ge_sm*Rnd*((1.0f)-alpha)
|
||||
* NB: currently uses 32bit accumulation for best low level performance,
|
||||
* possibly overkill if input is always up-scaled
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
/* (1-alpha)*(float)sqrt(12.0f) * ((float)own_random(&(st->noimix_seed))/65536.0f) */
|
||||
randval = Random(noimix_seed); /* +/-32767 */
|
||||
randval = mult_r(28378, randval); /* Q downscaled by 2 bits ends up in Q14 */ /*sqrt(12.0f) in Q13*/
|
||||
randval = extract_l(L_shl(Mult_32_16(L_Ge, randval), 1-*Q_stat_noise_ge)); /*Q_local+Q_ge+14-15+1-Q_ge=Q_local */
|
||||
|
||||
L_tmp = L_mult(Exc2_local[i], alpha); /* Q_local + 16 */
|
||||
L_tmp = L_mac(L_tmp, randval, alpha_m1); /* Q_local + 16 */
|
||||
L_tmp3 = Mult_32_16(L_tmp, Noimix_fract); /* Q_local+16+15-15 */
|
||||
L_tmp = L_add(L_tmp3, L_shl(Mult_32_16(L_tmp, tmp_res), 1)); /* Q_local+16+14-15+1 */
|
||||
|
||||
Exc2_local[i] = extract_h(L_tmp); /*Q_local */
|
||||
}
|
||||
*Q_stat_noise = Q_local; /* update for next call, routine can only be called once every frame */
|
||||
Qdiff = sub(Q_exc, Q_local); /* local excitation and incoming excitation */
|
||||
Scale_sig(Exc2_local, L_FRAME, Qdiff);
|
||||
Copy(Exc2_local, exc2, L_FRAME);
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* Generate low-pass filtered version of ISP coefficients
|
||||
*--------------------------------------------------------------------*/
|
||||
FOR (k=0; k<M; k++)
|
||||
{
|
||||
move16();
|
||||
lspnew_s[k] = add(
|
||||
mult(ISP_SMOOTHING_QUANT_A1_FX, lspold_s[k]),
|
||||
mult(32767-ISP_SMOOTHING_QUANT_A1_FX, lsp_new[k]));
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* replace LPC coefficients
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
* pre-calculation of (1-beta)
|
||||
*--------------------------------------------------------------------*/
|
||||
FOR (i=0; i<M; i++)
|
||||
{
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
oldlsp_mix[i] = add(mult(beta, lsp_old[i]),
|
||||
mult(sub(32767, beta), lspold_s[i]));
|
||||
|
||||
midlsp_mix[i] = add(mult(beta,lsp_mid[i]),
|
||||
mult(sub(32767, beta), add(shr(lspold_s[i], 1),
|
||||
shr(lspnew_s[i], 1))));
|
||||
|
||||
newlsp_mix[i] = add(mult(beta, lsp_new[i]),
|
||||
mult(sub(32767, beta),lspnew_s[i]));
|
||||
}
|
||||
|
||||
int_lsp4_fx( L_FRAME, oldlsp_mix, midlsp_mix, newlsp_mix, Aq, M, 0);
|
||||
Copy(lspnew_s,lspold_s,M);
|
||||
}
|
||||
ELSE /* (unvoiced_vad != 0) */
|
||||
{
|
||||
(*act_count)++;
|
||||
IF (sub(*act_count,3) > 0)
|
||||
{
|
||||
*act_count = 3;
|
||||
move16();
|
||||
*uv_count = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*
|
||||
* calc_tilt()
|
||||
*
|
||||
* Calculate spectral tilt by means of 1st-order LP analysis
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
static Word16 calc_tilt_fx( /* o : Excitation tilt Q15*/
|
||||
const Word16 *x, /* i : Signal input */
|
||||
const Word16 Q_shift, /* i : input scaling */
|
||||
const Word16 len /* i : lenght */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word16 tmp_shift;
|
||||
Word32 L_tmp_res;
|
||||
Word16 tmp_sign,xi,xi_p1;
|
||||
Word32 r0, r1;
|
||||
|
||||
r0 = L_deposit_l(0);
|
||||
r1 = L_deposit_l(0);
|
||||
xi = shr(x[0], Q_shift);
|
||||
move16();
|
||||
|
||||
FOR (i=0; i<len-1; i++)
|
||||
{
|
||||
/* r0 = L_mac(r0,x[i],x[i]) */
|
||||
/* r1 = L_mac(r1,x[i],x[i+1]) -> correlation loop can be optimized */
|
||||
r0 = L_mac(r0,xi,xi);
|
||||
|
||||
xi_p1 = shr(x[i+1], Q_shift);
|
||||
r1 = L_mac(r1, xi, xi_p1);
|
||||
|
||||
xi = xi_p1;
|
||||
move16();
|
||||
}
|
||||
|
||||
if (r0 == 0)
|
||||
{
|
||||
r0 = L_shl(327, 16);
|
||||
}
|
||||
|
||||
tmp_shift = norm_l(r0);
|
||||
move16();
|
||||
r0 = L_shl(r0,tmp_shift);
|
||||
tmp_sign = 1;
|
||||
move16();
|
||||
if (r1 >= 0)
|
||||
{
|
||||
tmp_sign = 0;
|
||||
move16();
|
||||
}
|
||||
r1 = L_abs(r1);
|
||||
|
||||
L_tmp_res = Div_32(r1,extract_h(r0), extract_l(r0));
|
||||
L_tmp_res = L_shl(L_tmp_res, tmp_shift); /*Q31 */
|
||||
|
||||
if (tmp_sign != 0)
|
||||
{
|
||||
L_tmp_res = L_negate(L_tmp_res); /*Q31 */
|
||||
}
|
||||
|
||||
return extract_h(L_tmp_res); /*Q15 */
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* L_Sqrt_Q0
|
||||
*
|
||||
* Calculate square root from fractional values (Q0 -> Q0)
|
||||
* Uses 32 bit internal representation for precision
|
||||
*---------------------------------------------------------------------------*/
|
||||
Word32 L_Sqrt_Q0( /* o : Square root of input */
|
||||
const Word32 x /* i : Input */
|
||||
)
|
||||
{
|
||||
Word32 log2_work;
|
||||
|
||||
Word16 log2_int;
|
||||
Word16 log2_frac;
|
||||
|
||||
IF (x > 0)
|
||||
{
|
||||
log2_int = norm_l(x);
|
||||
log2_frac = Log2_norm_lc(L_shl(x, log2_int));
|
||||
|
||||
log2_work = L_mac0(30*32768L, log2_frac, 1);
|
||||
log2_work = L_msu(log2_work, log2_int, 16384);
|
||||
log2_frac = L_Extract_lc(log2_work, &log2_int);
|
||||
|
||||
return Pow2(log2_int, log2_frac);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user