FreeCalypso > hg > gsm-codec-lib
diff libtwamr/set_sign.c @ 314:15c354f75110
libtwamr: integrate set_sign.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 18 Apr 2024 16:58:25 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/set_sign.c Thu Apr 18 16:58:25 2024 +0000 @@ -0,0 +1,213 @@ +/* +******************************************************************************** +* +* 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 : set_sign.c +* Purpose : Builds sign vector according to "dn[]" and "cn[]". +* +******************************************************************************** +*/ +/* +******************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +******************************************************************************** +*/ +#include "namespace.h" +#include "set_sign.h" +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" +#include "basic_op.h" +#include "no_count.h" +#include "inv_sqrt.h" +#include "cnst.h" + +/* +******************************************************************************** +* PUBLIC PROGRAM CODE +******************************************************************************** +*/ + +/************************************************************************* + * + * FUNCTION set_sign() + * + * PURPOSE: Builds sign[] vector according to "dn[]" and "cn[]". + * Also finds the position of maximum of correlation in each track + * and the starting position for each pulse. + * + *************************************************************************/ +void set_sign(Word16 dn[], /* i/o : correlation between target and h[] */ + Word16 sign[], /* o : sign of dn[] */ + Word16 dn2[], /* o : maximum of correlation in each track. */ + Word16 n /* i : # of maximum correlations in dn2[] */ +) +{ + Word16 i, j, k; + Word16 val, min; + Word16 pos = 0; /* initialization only needed to keep gcc silent */ + + /* set sign according to dn[] */ + + for (i = 0; i < L_CODE; i++) { + val = dn[i]; move16 (); + + test (); + if (val >= 0) { + sign[i] = 32767; move16 (); + } else { + sign[i] = -32767; move16 (); + val = negate(val); + } + dn[i] = val; move16 (); /* modify dn[] according to the fixed sign */ + dn2[i] = val; move16 (); + } + + /* keep 8-n maximum positions/8 of each track and store it in dn2[] */ + + for (i = 0; i < NB_TRACK; i++) + { + for (k = 0; k < (8-n); k++) + { + min = 0x7fff; move16 (); + for (j = i; j < L_CODE; j += STEP) + { + test (); move16 (); + if (dn2[j] >= 0) + { + val = sub(dn2[j], min); + test (); + if (val < 0) + { + min = dn2[j]; move16 (); + pos = j; move16 (); + } + } + } + dn2[pos] = -1; move16 (); + } + } + + return; +} + +/************************************************************************* + * + * FUNCTION set_sign12k2() + * + * PURPOSE: Builds sign[] vector according to "dn[]" and "cn[]", and modifies + * dn[] to include the sign information (dn[i]=sign[i]*dn[i]). + * Also finds the position of maximum of correlation in each track + * and the starting position for each pulse. + * + *************************************************************************/ +void set_sign12k2 ( + Word16 dn[], /* i/o : correlation between target and h[] */ + Word16 cn[], /* i : residual after long term prediction */ + Word16 sign[], /* o : sign of d[n] */ + Word16 pos_max[], /* o : position of maximum correlation */ + Word16 nb_track, /* i : number of tracks tracks */ + Word16 ipos[], /* o : starting position for each pulse */ + Word16 step /* i : the step size in the tracks */ +) +{ + Word16 i, j; + Word16 val, cor, k_cn, k_dn, max, max_of_all; + Word16 pos = 0; /* initialization only needed to keep gcc silent */ + Word16 en[L_CODE]; /* correlation vector */ + Word32 s; + + /* calculate energy for normalization of cn[] and dn[] */ + + s = 256; move32 (); + for (i = 0; i < L_CODE; i++) + { + s = L_mac (s, cn[i], cn[i]); + } + s = Inv_sqrt (s); move32 (); + k_cn = extract_h (L_shl (s, 5)); + + s = 256; move32 (); + for (i = 0; i < L_CODE; i++) + { + s = L_mac (s, dn[i], dn[i]); + } + s = Inv_sqrt (s); move32 (); + k_dn = extract_h (L_shl (s, 5)); + + for (i = 0; i < L_CODE; i++) + { + val = dn[i]; move16 (); + cor = round (L_shl (L_mac (L_mult (k_cn, cn[i]), k_dn, val), 10)); + + test (); + if (cor >= 0) + { + sign[i] = 32767; move16 (); /* sign = +1 */ + } + else + { + sign[i] = -32767; move16 (); /* sign = -1 */ + cor = negate (cor); + val = negate (val); + } + /* modify dn[] according to the fixed sign */ + dn[i] = val; move16 (); + en[i] = cor; move16 (); + } + + max_of_all = -1; move16 (); + for (i = 0; i < nb_track; i++) + { + max = -1; move16 (); + + for (j = i; j < L_CODE; j += step) + { + cor = en[j]; move16 (); + val = sub (cor, max); + test (); + if (val > 0) + { + max = cor; move16 (); + pos = j; move16 (); + } + } + /* store maximum correlation position */ + pos_max[i] = pos; move16 (); + val = sub (max, max_of_all); + test (); + if (val > 0) + { + max_of_all = max; move16 (); + /* starting position for i0 */ + ipos[0] = i; move16 (); + } + } + + /*----------------------------------------------------------------* + * Set starting position of each pulse. * + *----------------------------------------------------------------*/ + + pos = ipos[0]; move16 (); + ipos[nb_track] = pos; move16 (); + + for (i = 1; i < nb_track; i++) + { + pos = add (pos, 1); + test (); + if (sub (pos, nb_track) >= 0) + { + pos = 0; move16 (); + } + ipos[i] = pos; move16 (); + ipos[add(i, nb_track)] = pos; move16 (); + } +}