FreeCalypso > hg > gsm-codec-lib
changeset 308:8dfb7cbe6b59
libtwamr: integrated up to bgnscd.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 16 Apr 2024 17:57:21 +0000 |
parents | 6b33f3ba4289 |
children | 947693c879a4 |
files | libtwamr/Makefile libtwamr/bgnscd.c libtwamr/bgnscd.h libtwamr/gmed_n.c libtwamr/gmed_n.h libtwamr/memops.h libtwamr/namespace.h libtwamr/sqrt_l.c libtwamr/sqrt_l.h libtwamr/sqrt_l.tab |
diffstat | 10 files changed, 694 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/libtwamr/Makefile Tue Apr 16 17:18:04 2024 +0000 +++ b/libtwamr/Makefile Tue Apr 16 17:57:21 2024 +0000 @@ -1,7 +1,8 @@ CC= gcc CFLAGS= -O2 -OBJS= a_refl.o agc.o autocorr.o az_lsp.o b_cn_cod.o basicop2.o bitno.o \ - bits2prm.o inv_sqrt.o oper_32b.o prmno.o tls_flags.o window.o +OBJS= a_refl.o agc.o autocorr.o az_lsp.o b_cn_cod.o basicop2.o bgnscd.o \ + bitno.o bits2prm.o gmed_n.o inv_sqrt.o oper_32b.o prmno.o sqrt_l.o \ + tls_flags.o window.o LIB= libtwamr.a INSTALL_PREFIX= /usr/local
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/bgnscd.c Tue Apr 16 17:57:21 2024 +0000 @@ -0,0 +1,229 @@ +/************************************************************************* +* +* GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 +* R99 Version 3.3.0 +* REL-4 Version 4.1.0 +* +******************************************************************************** +* +* File : bgnscd.c +* Purpose : Background noise source charateristic detector (SCD) +* +******************************************************************************** +*/ + +/* +******************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +******************************************************************************** +*/ +#include "namespace.h" +#include "bgnscd.h" + +#include "typedef.h" +#include "basic_op.h" +#include "no_count.h" +#include "cnst.h" +#include "memops.h" +#include "gmed_n.h" +#include "sqrt_l.h" + +/* +******************************************************************************** +* LOCAL VARIABLES AND TABLES +******************************************************************************** +*/ +/*-----------------------------------------------------------------* + * Decoder constant parameters (defined in "cnst.h") * + *-----------------------------------------------------------------* + * L_FRAME : Frame size. * + * L_SUBFR : Sub-frame size. * + *-----------------------------------------------------------------*/ + +/* +******************************************************************************** +* PUBLIC PROGRAM CODE +******************************************************************************** +*/ +/* +************************************************************************** +* +* Function : Bgn_scd_reset +* Purpose : Resets state memory +* +************************************************************************** +*/ +void Bgn_scd_reset (Bgn_scdState *state) +{ + /* Static vectors to zero */ + Set_zero (state->frameEnergyHist, L_ENERGYHIST); + + /* Initialize hangover handling */ + state->bgHangover = 0; +} + +/* +************************************************************************** +* +* Function : Bgn_scd +* Purpose : Charaterice synthesis speech and detect background noise +* Returns : background noise decision; 0 = no bgn, 1 = bgn +* +************************************************************************** +*/ +Word16 Bgn_scd (Bgn_scdState *st, /* i : State variables for bgn SCD */ + Word16 ltpGainHist[], /* i : LTP gain history */ + Word16 speech[], /* o : synthesis speech frame */ + Word16 *voicedHangover /* o : # of frames after last + voiced frame */ + ) +{ + Word16 i; + Word16 prevVoiced, inbgNoise; + Word16 temp; + Word16 ltpLimit, frameEnergyMin; + Word16 currEnergy, noiseFloor, maxEnergy, maxEnergyLastPart; + Word32 s; + + /* Update the inBackgroundNoise flag (valid for use in next frame if BFI) */ + /* it now works as a energy detector floating on top */ + /* not as good as a VAD. */ + + currEnergy = 0; move16 (); + s = (Word32) 0; move32 (); + + for (i = 0; i < L_FRAME; i++) + { + s = L_mac (s, speech[i], speech[i]); + } + + s = L_shl(s, 2); + + currEnergy = extract_h (s); + + frameEnergyMin = 32767; move16 (); + + for (i = 0; i < L_ENERGYHIST; i++) + { + test (); + if (sub(st->frameEnergyHist[i], frameEnergyMin) < 0) + frameEnergyMin = st->frameEnergyHist[i]; move16 (); + } + + noiseFloor = shl (frameEnergyMin, 4); /* Frame Energy Margin of 16 */ + + maxEnergy = st->frameEnergyHist[0]; move16 (); + for (i = 1; i < L_ENERGYHIST-4; i++) + { + test (); + if ( sub (maxEnergy, st->frameEnergyHist[i]) < 0) + { + maxEnergy = st->frameEnergyHist[i]; move16 (); + } + } + + maxEnergyLastPart = st->frameEnergyHist[2*L_ENERGYHIST/3]; move16 (); + for (i = 2*L_ENERGYHIST/3+1; i < L_ENERGYHIST; i++) + { + test (); + if ( sub (maxEnergyLastPart, st->frameEnergyHist[i] ) < 0) + { + maxEnergyLastPart = st->frameEnergyHist[i]; move16 (); + } + } + + inbgNoise = 0; /* false */ move16 (); + + /* Do not consider silence as noise */ + /* Do not consider continuous high volume as noise */ + /* Or if the current noise level is very low */ + /* Mark as noise if under current noise limit */ + /* OR if the maximum energy is below the upper limit */ + + test (); test (); test (); test (); test (); + if ( (sub(maxEnergy, LOWERNOISELIMIT) > 0) && + (sub(currEnergy, FRAMEENERGYLIMIT) < 0) && + (sub(currEnergy, LOWERNOISELIMIT) > 0) && + ( (sub(currEnergy, noiseFloor) < 0) || + (sub(maxEnergyLastPart, UPPERNOISELIMIT) < 0))) + { + test (); + if (sub(add(st->bgHangover, 1), 30) > 0) + { + st->bgHangover = 30; move16 (); + } else + { + st->bgHangover = add(st->bgHangover, 1); + } + } + else + { + st->bgHangover = 0; move16 (); + } + + /* make final decision about frame state , act somewhat cautiosly */ + test (); + if (sub(st->bgHangover,1) > 0) + inbgNoise = 1; /* true */ move16 (); + + for (i = 0; i < L_ENERGYHIST-1; i++) + { + st->frameEnergyHist[i] = st->frameEnergyHist[i+1]; move16 (); + } + st->frameEnergyHist[L_ENERGYHIST-1] = currEnergy; move16 (); + + /* prepare for voicing decision; tighten the threshold after some + time in noise */ + ltpLimit = 13926; /* 0.85 Q14 */ move16 (); + test (); + if (sub(st->bgHangover, 8) > 0) + { + ltpLimit = 15565; /* 0.95 Q14 */ move16 (); + } + test (); + if (sub(st->bgHangover, 15) > 0) + { + ltpLimit = 16383; /* 1.00 Q14 */ move16 (); + } + + /* weak sort of voicing indication. */ + prevVoiced = 0; /* false */ move16 (); + test (); + + if (sub(gmed_n(<pGainHist[4], 5), ltpLimit) > 0) + { + prevVoiced = 1; /* true */ move16 (); + } + test (); + if (sub(st->bgHangover, 20) > 0) { + if (sub(gmed_n(ltpGainHist, 9), ltpLimit) > 0) + { + prevVoiced = 1; /* true */ move16 (); + } + else + { + prevVoiced = 0; /* false */ move16 (); + } + } + + test (); + if (prevVoiced) + { + *voicedHangover = 0; move16 (); + } + else + { + temp = add(*voicedHangover, 1); + test (); + if (sub(temp, 10) > 0) + { + *voicedHangover = 10; move16 (); + } + else + { + *voicedHangover = temp; move16 (); + } + } + + return inbgNoise; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/bgnscd.h Tue Apr 16 17:57:21 2024 +0000 @@ -0,0 +1,85 @@ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 +* R99 Version 3.3.0 +* REL-4 Version 4.1.0 +* +******************************************************************************** +* +* File : bgnscd.h +* Purpose : Background noise source charateristic detector (SCD) +* +******************************************************************************** +*/ +#ifndef bgnscd_h +#define bgnscd_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" +#include "cnst.h" + +/* +******************************************************************************** +* LOCAL VARIABLES AND TABLES +******************************************************************************** +*/ +#define L_ENERGYHIST 60 +#define INV_L_FRAME 102 + + +/* 2*(160*x)^2 / 65536 where x is FLP values 150,5 and 50 */ +#define FRAMEENERGYLIMIT 17578 /* 150 */ +#define LOWERNOISELIMIT 20 /* 5 */ +#define UPPERNOISELIMIT 1953 /* 50 */ + +/* +******************************************************************************** +* DEFINITION OF DATA TYPES +******************************************************************************** +*/ +typedef struct{ + /* history vector of past synthesis speech energy */ + Word16 frameEnergyHist[L_ENERGYHIST]; + + /* state flags */ + Word16 bgHangover; /* counter; number of frames after last speech frame */ + +} Bgn_scdState; + +/* +******************************************************************************** +* DECLARATION OF PROTOTYPES +******************************************************************************** +*/ +/* +************************************************************************** +* +* Function : Bgn_scd_reset +* Purpose : Resets state memory +* Returns : 0 on success +* +************************************************************************** +*/ +void Bgn_scd_reset (Bgn_scdState *st); + +/* +************************************************************************** +* +* Function : Bgn_scd +* Purpose : Charaterice synthesis speech and detect background noise +* Returns : background noise decision; 0 = bgn, 1 = no bgn +* +************************************************************************** +*/ +Word16 Bgn_scd (Bgn_scdState *st, /* i : State variables for bgn SCD */ + Word16 ltpGainHist[], /* i : LTP gain history */ + Word16 speech[], /* o : synthesis speech frame */ + Word16 *voicedHangover /* o : # of frames after last voiced frame */ +); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/gmed_n.c Tue Apr 16 17:57:21 2024 +0000 @@ -0,0 +1,91 @@ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 +* R99 Version 3.3.0 +* REL-4 Version 4.1.0 +* +******************************************************************************** +* +* File : gmed_n.c +* Purpose : calculates N-point median. +* +******************************************************************************** +*/ +/* +******************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +******************************************************************************** +*/ +#include "namespace.h" +#include "gmed_n.h" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" +#include "basic_op.h" +#include "no_count.h" + +/* +******************************************************************************** +* LOCAL VARIABLES AND TABLES +******************************************************************************** +*/ + +#define NMAX 9 /* largest N used in median calculation */ + +/* +******************************************************************************** +* PUBLIC PROGRAM CODE +******************************************************************************** +*/ +/************************************************************************* + * + * FUNCTION: gmed_n + * + * PURPOSE: calculates N-point median. + * + * DESCRIPTION: + * + *************************************************************************/ + +Word16 gmed_n ( /* o : index of the median value (0...N-1) */ + Word16 ind[], /* i : Past gain values */ + Word16 n /* i : The number of gains; this routine */ + /* is only valid for a odd number of gains */ + /* (n <= NMAX) */ +) +{ + Word16 i, j, ix = 0; + Word16 max; + Word16 medianIndex; + Word16 tmp[NMAX]; + Word16 tmp2[NMAX]; + + for (i = 0; i < n; i++) + { + tmp2[i] = ind[i]; move16 (); + } + + for (i = 0; i < n; i++) + { + max = -32767; move16 (); + for (j = 0; j < n; j++) + { + test (); + if (sub (tmp2[j], max) >= 0) + { + max = tmp2[j]; move16 (); + ix = j; move16 (); + } + } + tmp2[ix] = -32768; move16 (); + tmp[i] = ix; move16 (); + } + + medianIndex=tmp[ shr(n,1) ]; move16 (); /* account for complex addressing */ + return (ind[medianIndex]); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/gmed_n.h Tue Apr 16 17:57:21 2024 +0000 @@ -0,0 +1,43 @@ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 +* R99 Version 3.3.0 +* REL-4 Version 4.1.0 +* +******************************************************************************** +* +* File : gmed_n.h +* Purpose : calculates N-point median. +* +******************************************************************************** +*/ +#ifndef gmed_n_h +#define gmed_n_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" + +/* +******************************************************************************** +* DEFINITION OF DATA TYPES +******************************************************************************** +*/ + +/* +******************************************************************************** +* DECLARATION OF PROTOTYPES +******************************************************************************** +*/ +Word16 gmed_n ( /* o : index of the median value (0...N-1) */ + Word16 ind[], /* i : Past gain values */ + Word16 n /* i : The number of gains; this routine */ + /* is only valid for a odd number of gains */ +); + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/memops.h Tue Apr 16 17:57:21 2024 +0000 @@ -0,0 +1,24 @@ +/* + * The original code from ETSI uses its own Copy() and Set_zero() + * functions, operating on Word16 elements. Here we implement them + * as static inline functions wrapping around memcpy and memset. + */ + +#include <string.h> + +static inline void Copy ( + const Word16 x[], /* (i) : input vector */ + Word16 y[], /* (o) : output vector */ + Word16 L /* (i) : vector length */ +) +{ + memcpy(y, x, L * 2); +} + +static inline void Set_zero ( + Word16 x[], /* (o) : vector to clear */ + Word16 L /* (i) : length of vector */ +) +{ + memset(x, 0, L * 2); +}
--- a/libtwamr/namespace.h Tue Apr 16 17:18:04 2024 +0000 +++ b/libtwamr/namespace.h Tue Apr 16 17:57:21 2024 +0000 @@ -61,15 +61,17 @@ #define A_Refl AMR__A_Refl #define Autocorr AMR__Autocorr #define Az_lsp AMR__Az_lsp +#define Bgn_scd AMR__Bgn_scd +#define Bgn_scd_reset AMR__Bgn_scd_reset -#define agc_init AMR__agc_init -#define agc_reset AMR__agc_reset -#define agc_exit AMR__agc_exit #define agc AMR__agc #define agc2 AMR__agc2 +#define agc_reset AMR__agc_reset #define pseudonoise AMR__pseudonoise #define build_CN_code AMR__build_CN_code #define build_CN_param AMR__build_CN_param +#define gmed_n AMR__gmed_n +#define sqrt_l_exp AMR__sqrt_l_exp #define Bits2prm AMR__Bits2prm #define Prm2bits AMR__Prm2bits
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/sqrt_l.c Tue Apr 16 17:57:21 2024 +0000 @@ -0,0 +1,107 @@ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 +* R99 Version 3.3.0 +* REL-4 Version 4.1.0 +* +******************************************************************************** +* +* File : sqrt_l.c +* Purpose : Computes sqrt(L_x), where L_x is positive. +* : If L_var is negative or zero, the result is 0 +* Description : +* The function sqrt(L_x) is approximated by a table and linear +* interpolation. The square root is computed using the +* following steps: +* 1- Normalization of L_x. +* 2- If exponent is even then shift right once. +* 3- exponent = exponent/2 +* 4- i = bit25-b31 of L_x; 16<=i<=63 because of normalization. +* 5- a = bit10-b24 +* 6- i -=16 +* 7- L_y = table[i]<<16 - (table[i] - table[i+1]) * a * 2 +* 8- return L_y and exponent so caller can do denormalization +* +******************************************************************************** +*/ +/* +******************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +******************************************************************************** +*/ +#include "namespace.h" +#include "sqrt_l.h" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" +#include "basic_op.h" +#include "no_count.h" + +/* +******************************************************************************** +* LOCAL VARIABLES AND TABLES +******************************************************************************** +*/ +#include "sqrt_l.tab" /* Table for sqrt_l_exp() */ + +/* +******************************************************************************** +* PUBLIC PROGRAM CODE +******************************************************************************** +*/ + +Word32 sqrt_l_exp (/* o : output value, Q31 */ + Word32 L_x, /* i : input value, Q31 */ + Word16 *exp /* o : right shift to be applied to result, Q1 */ +) +{ + /* + y = sqrt(x) + + x = f * 2^-e, 0.5 <= f < 1 (normalization) + + y = sqrt(f) * 2^(-e/2) + + a) e = 2k --> y = sqrt(f) * 2^-k (k = e div 2, + 0.707 <= sqrt(f) < 1) + b) e = 2k+1 --> y = sqrt(f/2) * 2^-k (k = e div 2, + 0.5 <= sqrt(f/2) < 0.707) + */ + + + Word16 e, i, a, tmp; + Word32 L_y; + + test (); + if (L_x <= (Word32) 0) + { + *exp = 0; move16 (); + return (Word32) 0; + } + + e = norm_l (L_x) & 0xFFFE; logic16 (); /* get next lower EVEN norm. exp */ + L_x = L_shl (L_x, e); /* L_x is normalized to [0.25..1) */ + *exp = e; move16 (); /* return 2*exponent (or Q1) */ + + L_x = L_shr (L_x, 9); + i = extract_h (L_x); /* Extract b25-b31, 16 <= i <= 63 because + of normalization */ + L_x = L_shr (L_x, 1); + a = extract_l (L_x); /* Extract b10-b24 */ + a = a & (Word16) 0x7fff; logic16 (); + + i = sub (i, 16); /* 0 <= i <= 47 */ + + L_y = L_deposit_h (table[i]); /* table[i] << 16 */ + tmp = sub (table[i], table[i + 1]); /* table[i] - table[i+1]) */ + L_y = L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */ + + /* L_y = L_shr (L_y, *exp); */ /* denormalization done by caller */ + + return (L_y); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/sqrt_l.h Tue Apr 16 17:57:21 2024 +0000 @@ -0,0 +1,38 @@ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 +* R99 Version 3.3.0 +* REL-4 Version 4.1.0 +* +******************************************************************************** +* +* File : sqrt_l.h +* Purpose : Computes sqrt(L_x), where L_x is positive. +* : If L_x is negative or zero, the result is +* : 0 (3fff ffff). +* +******************************************************************************** +*/ +#ifndef sqrt_l_h +#define sqrt_l_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" + +/* +******************************************************************************** +* DECLARATION OF PROTOTYPES +******************************************************************************** +*/ + +Word32 sqrt_l_exp (/* o : output value, Q31 */ + Word32 L_x, /* i : input value, Q31 */ + Word16 *exp /* o : right shift to be applied to result, Q0 */ +); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/sqrt_l.tab Tue Apr 16 17:57:21 2024 +0000 @@ -0,0 +1,69 @@ +/* +******************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 +* R99 Version 3.3.0 +* REL-4 Version 4.1.0 +* +******************************************************************************** +* +* File : sqrt_l.tab +* Purpose : Table for routine sqrt_l_exp() +* $Id $ +* +******************************************************************************** +*/ +/* table[i] = sqrt((i+16)*2^-6) * 2^15, i.e. sqrt(x) scaled Q15 */ + +static const Word16 table[49] = +{ + 16384, + 16888, + 17378, + 17854, + 18318, + 18770, + 19212, + 19644, + 20066, + 20480, + 20886, + 21283, + 21674, + 22058, + 22435, + 22806, + 23170, + 23530, + 23884, + 24232, + 24576, + 24915, + 25249, + 25580, + 25905, + 26227, + 26545, + 26859, + 27170, + 27477, + 27780, + 28081, + 28378, + 28672, + 28963, + 29251, + 29537, + 29819, + 30099, + 30377, + 30652, + 30924, + 31194, + 31462, + 31727, + 31991, + 32252, + 32511, + 32767 +};