Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include "options.h"
7 : #include "cnst.h"
8 : #include "rom_com.h"
9 : #include "prot_fx.h" /* Function prototypes */
10 : #include "prot_fx_enc.h" /* Function prototypes */
11 :
12 :
13 : #define ISF_ONE 3 /*1.0f*1.28f Q1*/ /*=1.0f in 14Q1*1.28*/
14 :
15 : /*------------------------------------------------------------------*
16 : * lsf_weight_fx()
17 : *
18 : * outputs only the weightings, doesn't do anything with the lsfq
19 : *------------------------------------------------------------------*/
20 : /*outputs only the weightings, doesn't do anything with the lsfq*/
21 108948 : static void lsf_weight_fx(
22 : const Word16 *lsfq, /* i : quantized lsf coefficients (14Q1*1.28)*/
23 : Word16 *w /* o : lsf weighting vector (0Q15) */
24 : )
25 : {
26 : Word16 i;
27 : Word16 inv_di0, inv_di1;
28 :
29 :
30 : /* weighting function */
31 : /*use the second element as the base to avoid the following division by 0*/
32 : /*this happens when the ac function is nearly flat*/
33 108948 : i = lsfq[0]; /* (14Q1*1.28)*/
34 108948 : move16();
35 108948 : if ( lsfq[0] == 0 )
36 : {
37 0 : i = lsfq[1];
38 0 : move16();
39 : }
40 108948 : inv_di0 = 0x7fff;
41 108948 : move16();
42 108948 : IF( GT_16( i, ISF_ONE ) )
43 : {
44 108948 : inv_di0 = div_s( ISF_ONE, i ); /*0Q15*/ /*inv_di0 = 1.0f / lsfq[0];*/
45 : }
46 :
47 : /* Allow saturation during weight calculation, because the values that are
48 : weighted later are used for a minimum search and experimental saturation
49 : avoidance also showed no improvement. */
50 : BASOP_SATURATE_WARNING_OFF_EVS
51 871584 : FOR( i = 1; i < ( M - 2 ); i += 2 ) /*for (i=1; i<(M-2); i+=2)*/
52 : {
53 762636 : inv_di1 = div_s( ISF_ONE, s_max( ISF_ONE, sub( lsfq[i], lsfq[i - 1] ) ) ); /*0Q15*/ /*inv_di1 = 1.0f / (lsfq[i] - lsfq[i-1]);*/
54 762636 : w[i - 1] = add_sat( inv_di0, inv_di1 );
55 762636 : move16(); /*0Q15*/ /*w[i-1] = inv_di0 + inv_di1;*/
56 762636 : inv_di0 = div_s( ISF_ONE, s_max( ISF_ONE, sub( lsfq[i + 1], lsfq[i] ) ) ); /*0Q15*/ /*inv_di0 = 1.0f / (lsfq[i+1] - lsfq[i]);*/
57 762636 : w[i] = add_sat( inv_di1, inv_di0 );
58 762636 : move16(); /*0Q15*/ /*w[i] = inv_di1 + inv_di0;*/
59 : }
60 108948 : inv_di1 = div_s( ISF_ONE, s_max( ISF_ONE, sub( lsfq[i], lsfq[i - 1] ) ) ); /*inv_di1 = 1.0f / (lsfq[i] - lsfq[i-1]);*/
61 108948 : w[i - 1] = add_sat( inv_di0, inv_di1 );
62 108948 : move16(); /*w[i-1] = inv_di0 + inv_di1;*/
63 108948 : inv_di0 = div_s( ISF_ONE, s_max( ISF_ONE, sub( FREQ_MAX, lsfq[i] ) ) ); /*inv_di0 = 1.0f / (FREQ_MAX - lsfq[i]);*/
64 108948 : w[i] = add_sat( inv_di1, inv_di0 );
65 108948 : move16(); /*w[i] = inv_di1 + inv_di0;*/
66 :
67 : BASOP_SATURATE_WARNING_ON_EVS
68 :
69 :
70 108948 : return;
71 : }
72 : /*------------------------------------------------------------------*
73 : * vlpc_1st_cod_fx()
74 : *
75 : *
76 : *------------------------------------------------------------------*/
77 108948 : Word16 vlpc_1st_cod_fx( /* o : codebook index */
78 : const Word16 *lsf, /* i : vector to quantize (14Q1*1.28) */
79 : Word16 *lsfq, /* o : quantized lsf (14Q1*1.28) */
80 : Word16 *wout, /* o : lsf weights */
81 : Word16 rf_mode )
82 : {
83 : Word16 i, j, index, diff, wdiff;
84 : Word16 w[M];
85 : Word32 dist_min, dist;
86 : const Word16 *p_dico;
87 :
88 :
89 : /* weighting */
90 108948 : lsf_weight_fx( lsf, w ); /*lsf:14Q1*1.28=>w:0Q15*/
91 108948 : IF( EQ_16( rf_mode, 1 ) )
92 : {
93 : Word16 s;
94 0 : s = Find_Max_Norm16( w, M );
95 0 : Scale_sig( w, M, s );
96 : }
97 108948 : Copy( w, wout, M );
98 : /* remove lsf prediction/means */
99 :
100 : /*dist_min = 1.0e30f;*/
101 108948 : dist_min = L_add( MAX_32, 0 );
102 108948 : p_dico = dico_lsf_abs_8b; /*14Q1*1.28*/
103 108948 : index = 0;
104 108948 : move16();
105 :
106 27999636 : FOR( i = 0; i < 256; i++ )
107 : {
108 27890688 : dist = 0;
109 27890688 : move32();
110 474141696 : FOR( j = 0; j < M; j++ )
111 : {
112 446251008 : diff = sub( lsf[j], p_dico[j] );
113 446251008 : wdiff = shr( mult_r( w[j], diff ), 4 );
114 446251008 : dist = L_mac( dist, wdiff, diff );
115 : }
116 27890688 : p_dico += M;
117 :
118 27890688 : if ( LT_32( dist, dist_min ) )
119 : {
120 715303 : index = i; /* store index of new minimum */
121 715303 : move16();
122 : }
123 27890688 : dist_min = L_min( dist, dist_min );
124 : }
125 :
126 : /* quantized vector */
127 108948 : p_dico = &dico_lsf_abs_8b[index * M];
128 :
129 1852116 : FOR( j = 0; j < M; j++ )
130 : {
131 : /*lsfq[j] += *p_dico++;*/ /* += cause it's differential#
132 : -> since isfq[i] is 0, only data move is sufficient*/
133 : /*lsfq[j] = add(lsfq[j],*p_dico++);*/
134 1743168 : lsfq[j] = *p_dico++;
135 1743168 : move16();
136 : }
137 :
138 :
139 108948 : return index;
140 : }
|