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