FreeCalypso > hg > gsm-codec-lib
view libgsmhr1/dtx_rxfe.c @ 577:d68b2c92464a
libgsmhr1: bring in parts of dtx.[ch] needed for RxFE
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 13 Feb 2025 03:06:11 +0000 |
parents | |
children | 7756b23b78cd |
line wrap: on
line source
/* * Here we implement the subset of DTX functions that are used by the Rx * front end, i.e., the part of libgsmhr1 that is common between the full * decoder and our TFO transform implementation. Note that the same DTX * functions will also be used by the speech encoder. */ #include "typedefs.h" #include "namespace.h" #include "dtx_rxfe.h" #include "mathhalf.h" #include "mathdp31.h" /* relevant definitions from original dtx.c */ #define PN_XOR_REG (Longword)0x00000005L #define PN_XOR_ADD (Longword)0x40000000L #define OH_SHIFT 3 /* shift corresponding to OVERHANG */ /* Values of GS for voicing state 0, all values shifted down by 2 shifts */ const LongwordRom ppLr_gsTable[4][32] = { { 0x000011ab, 0x000038d2, 0x0000773e, 0x000144ef, 0x00035675, 0x000648c5, 0x000c3d65, 0x0017ae17, 0x002a3dbb, 0x005238e7, 0x00695c1a, 0x00a60d45, 0x00e4cc68, 0x01c3ba6a, 0x019e3c96, 0x02d1fbac, 0x030453ec, 0x0549a998, 0x05190298, 0x08258920, 0x08daff30, 0x0c3150e0, 0x0e45d850, 0x14c111a0, 0x0ff7e1c0, 0x18a06860, 0x13810400, 0x1abc9ee0, 0x28500940, 0x41f22800, 0x22fc5040, 0x2cd90180 }, { 0x00003ede, 0x00021fc9, 0x0013f0c3, 0x003a7be2, 0x007a6663, 0x00fe3773, 0x012fabf4, 0x02275cd0, 0x01c0ef14, 0x02c0b1d8, 0x0350fc70, 0x05505078, 0x04175f30, 0x052c1098, 0x08ed3310, 0x0a63b470, 0x05417870, 0x08995ee0, 0x07bbe018, 0x0a19fa10, 0x0b5818c0, 0x0fd96ea0, 0x0e5cad10, 0x13b40d40, 0x12d45840, 0x14577320, 0x2b2e5e00, 0x333e9640, 0x194c35c0, 0x1c30f8c0, 0x2d16db00, 0x2cc970ff }, { 0x002f18e7, 0x00a47be0, 0x01222efe, 0x01c42df8, 0x024be794, 0x03424c40, 0x036950fc, 0x04973108, 0x038405b4, 0x05d8c8f0, 0x05063e08, 0x070cdea0, 0x05812be8, 0x06da5fc8, 0x088fcd60, 0x0a013cb0, 0x0909a460, 0x09e6cf40, 0x0ee581d0, 0x0ec99f20, 0x0b4e7470, 0x0c730e80, 0x0ff39d20, 0x105d0d80, 0x158b0b00, 0x172babe0, 0x14576460, 0x181a6720, 0x26126e80, 0x1f590180, 0x1fdaad60, 0x2e0e8000 }, { 0x00c7f603, 0x01260cda, 0x01b3926a, 0x026d82bc, 0x0228fba0, 0x036ec5b0, 0x034bf4cc, 0x043a55d0, 0x044f9c20, 0x05c66f50, 0x0515f890, 0x06065300, 0x0665dc00, 0x0802b630, 0x0737a1c0, 0x087294e0, 0x09253fc0, 0x0a619760, 0x097bd060, 0x0a6d4e50, 0x0d19e520, 0x0e15c420, 0x0c4e4eb0, 0x0e8880e0, 0x11cdf480, 0x12c85800, 0x10f4c0a0, 0x13e51b00, 0x189dbaa0, 0x18a6bb60, 0x22e31500, 0x21615240 } }; /************************************************************************* * * FUNCTION NAME: avgGsHistQntz * * PURPOSE: * * Average gs history, where history is of length OVERHANG-1 * frames. The last frame's (i.e. this frame) gs values are not * available since quantization would have occured only after the * VAD decision is made. * * INPUTS: * * pL_GsHistory[(OVERHANG-1)*N_SUB] - the GS of the past * OVERHANG-1 frames. The GS values are stored shifted down by 2 * shifts to avoid overflow (the largest GS is greater than 2.0). * * * OUTPUTS: * * *pL_GsAvgd - the average of pL_GsHistory[], also shifted down * by two shifts. * * RETURN VALUE: * * none. * * *************************************************************************/ void avgGsHistQntz(Longword pL_GsHistory[], Longword *pL_GsAvgd) { /*_________________________________________________________________________ | | | Automatic Variables | |_________________________________________________________________________| */ int i; Longword L_avg; /*_________________________________________________________________________ | | | Executable Code | |_________________________________________________________________________| */ L_avg = L_shift_r(pL_GsHistory[0], -(OH_SHIFT + 2)); for (i = 1; i < N_SUB * (OVERHANG - 1); i++) L_avg = L_add(L_shift_r(pL_GsHistory[i], -(OH_SHIFT + 2)), L_avg); /* avg number x/32 not x/28 */ *pL_GsAvgd = L_add(L_avg, L_mpy_ls(L_avg, 0x1249)); /* L_avg *= 32/28 */ } /************************************************************************* * * FUNCTION NAME: gsQuant * * PURPOSE: * * Quantize a value of gs in any of the voicing modes. Input GS * is a 32 bit number. The GSP0 index is returned. * * INPUTS: * * L_GsIn - 32 bit GS value, shifted down by 2 shifts. * * swVoicingMode - voicing level * * ppLr_gsTable[4][32] - Rom GS Table. (global), all GS values * have been shifted down by 2 from their true value. * * OUTPUTS: * * none * * RETURN VALUE: * * * GSP0 Index closest to the input value of GS. * * *************************************************************************/ Shortword gsQuant(Longword L_GsIn, Shortword swVoicingMode) { /*_________________________________________________________________________ | | | Automatic Variables | |_________________________________________________________________________| */ Shortword swGsIndex, swBestGs; Longword L_diff, L_min = LW_MAX; /*_________________________________________________________________________ | | | Executable Code | |_________________________________________________________________________| */ for (swGsIndex = 0; swGsIndex < 32; swGsIndex++) { L_diff = L_abs(L_sub(L_GsIn, ppLr_gsTable[swVoicingMode][swGsIndex])); if (L_sub(L_diff, L_min) < 0) { /* new minimum */ /* ----------- */ swBestGs = swGsIndex; L_min = L_diff; } } return (swBestGs); } /************************************************************************* * * FUNCTION NAME: getPnBits * * PURPOSE: * * Generate iBits pseudo-random bits using *pL_PNSeed as the * pn-generators seed. * * INPUTS: * * iBits - integer indicating how many random bits to return. * range [0,15], 0 yields 1 bit output * * *pL_PNSeed - 32 bit seed (changed by function) * * OUTPUTS: * * *pL_PNSeed - 32 bit seed, modified. * * RETURN VALUE: * * random bits in iBits LSB's. * * * IMPLEMENTATION: * * implementation of x**31 + x**3 + 1 == PN_XOR_REG | PN_XOR_ADD a * PN sequence generator using Longwords generating a 2**31 -1 * length pn-sequence. * *************************************************************************/ Shortword getPnBits(int iBits, Longword *pL_PNSeed) { /*_________________________________________________________________________ | | | Automatic Variables | |_________________________________________________________________________| */ Shortword swPnBits = 0; Longword L_Taps, L_FeedBack; int i; /*_________________________________________________________________________ | | | Executable Code | |_________________________________________________________________________| */ for (i = 0; i < iBits; i++) { /* update the state */ /* ---------------- */ L_Taps = *pL_PNSeed & PN_XOR_REG; L_FeedBack = L_Taps; /* Xor tap bits to yield * feedback bit */ L_Taps = L_shr(L_Taps, 1); while (L_Taps) { L_FeedBack = L_FeedBack ^ L_Taps; L_Taps = L_shr(L_Taps, 1); } /* LSB of L_FeedBack is next MSB of PN register */ *pL_PNSeed = L_shr(*pL_PNSeed, 1); if (L_FeedBack & 1) *pL_PNSeed = *pL_PNSeed | PN_XOR_ADD; /* State update complete. Get the output bit from the state, add/or it * into output */ swPnBits = shl(swPnBits, 1); swPnBits = swPnBits | (extract_l(*pL_PNSeed) & 0x0001); } return (swPnBits); }