Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include "options.h" /* Compilation switches */
6 : #include "cnst.h" /* Common FX constants */
7 : #include "prot_fx.h" /* Function prototypes */
8 : #include "rom_com.h" /* Function prototypes */
9 :
10 : /*-------------------------------------------------------------------
11 : * direct_transform()
12 : *
13 : * Transformation of the signal to DCT domain
14 : *-------------------------------------------------------------------*/
15 45886 : void direct_transform_fx(
16 : const Word32 in32_fx[], /* i : input signal Q*/
17 : Word32 out32_fx[], /* o : transformation Q*/
18 : const Word16 is_transient, /* i : is transient Q0*/
19 : const Word16 L, /* i : length Q0*/
20 : Word16 *Q,
21 : const Word16 element_mode /* i : IVAS element mode Q0*/
22 : )
23 : {
24 :
25 : Word16 i, k;
26 : Word16 seg;
27 : Word16 segment_length, segment_length2, segment_length4;
28 :
29 : const Word16 *wh_fx;
30 : const Word16 *wl_fx;
31 : const Word32 *sh_fx;
32 : const Word32 *sl_fx2;
33 : Word32 *sl_fx;
34 : Word32 *iseg_fx;
35 : Word32 *oseg_fx;
36 : Word32 dctin32_fx[L_FRAME48k];
37 : Word32 in32_r16_fx[L_FRAME48k];
38 :
39 : const Word16 *win_fx;
40 45886 : Word16 shift, Qmin = 31;
41 : Word32 L_tmp;
42 : Word16 Qs[NUM_TIME_SWITCHING_BLOCKS];
43 : (void) ( element_mode );
44 45886 : move16();
45 :
46 45886 : segment_length = shr( L, 1 );
47 45886 : segment_length2 = shr( segment_length, 1 );
48 45886 : segment_length4 = shr( segment_length2, 1 );
49 :
50 45886 : IF( is_transient )
51 : {
52 560 : IF( EQ_16( L, L_FRAME48k ) )
53 : {
54 543 : win_fx = wscw16q15_fx; /*Q15*/
55 : }
56 17 : ELSE IF( EQ_16( L, L_FRAME32k ) )
57 : {
58 17 : win_fx = wscw16q15_32_fx; /*Q15*/
59 : }
60 0 : ELSE IF( EQ_16( L, L_FRAME8k ) )
61 : {
62 0 : win_fx = wscw16q15_8_fx; /*Q15*/
63 : }
64 : ELSE
65 : {
66 0 : win_fx = wscw16q15_16_fx; /*Q15*/
67 : }
68 :
69 560 : sh_fx = &in32_fx[( L - 1 )]; /*Q*/
70 560 : sl_fx = &in32_r16_fx[( L - 1 )]; /*Q*/
71 266640 : FOR( i = 0; i < segment_length; i++ )
72 : {
73 266080 : in32_r16_fx[i] = ( *sh_fx-- ); /*Q*/
74 266080 : move32();
75 266080 : ( *sl_fx-- ) = in32_fx[i]; /*Q*/
76 266080 : move32();
77 : }
78 :
79 560 : iseg_fx = &in32_r16_fx[-segment_length4]; /*Q*/
80 560 : oseg_fx = out32_fx; /*Q*/
81 :
82 560 : wh_fx = &win_fx[segment_length4]; /*Q15*/
83 560 : wl_fx = wh_fx - 1; /*Q15*/
84 :
85 560 : shift = extract_l( L_mult0( 3, segment_length4 ) ); /*Q0*/
86 560 : sh_fx = &iseg_fx[shift]; /*Q*/
87 560 : sl_fx2 = sh_fx - 1; /*Q*/
88 :
89 :
90 67080 : FOR( i = 0; i < segment_length4; i++ )
91 : {
92 66520 : L_tmp = L_negate( Mult_32_16( ( *sh_fx++ ), ( *wh_fx++ ) ) ); /*Q+15-15=Q */
93 66520 : dctin32_fx[i] = Madd_32_16( L_tmp, *sl_fx2--, *wl_fx-- ); /*Q*/
94 66520 : move32();
95 : }
96 :
97 560 : sl_fx2 = &iseg_fx[( segment_length2 - 1 )]; /*Q*/
98 :
99 67080 : FOR( i = segment_length4; i < segment_length2; i++ )
100 : {
101 66520 : dctin32_fx[i] = L_negate( *sl_fx2-- ); /*Q*/
102 66520 : move32();
103 : }
104 :
105 560 : Qs[0] = *Q;
106 560 : move16();
107 560 : edct_fx( dctin32_fx, oseg_fx, segment_length2, &Qs[0] );
108 560 : Qmin = s_min( Qs[0], Qmin );
109 :
110 560 : iseg_fx += segment_length2;
111 560 : oseg_fx += segment_length2;
112 :
113 1680 : FOR( seg = 1; seg < NUM_TIME_SWITCHING_BLOCKS - 1; seg++ )
114 : {
115 1120 : wh_fx = &win_fx[segment_length4]; /*Q15*/
116 1120 : wl_fx = wh_fx - 1; /*Q15*/
117 1120 : sh_fx = &iseg_fx[shift]; /*Q*/
118 1120 : sl_fx2 = sh_fx - 1; /*Q*/
119 134160 : FOR( i = 0; i < segment_length4; i++ )
120 : {
121 133040 : L_tmp = L_negate( Mult_32_16( ( *sh_fx++ ), ( *wh_fx++ ) ) ); /*Q+15-15=Q */
122 133040 : dctin32_fx[i] = Madd_32_16( L_tmp, *sl_fx2--, *wl_fx-- ); /*Q*/
123 133040 : move32();
124 : }
125 :
126 1120 : sh_fx = iseg_fx; /*Q*/
127 1120 : sl_fx2 = &iseg_fx[( segment_length2 - 1 )]; /*Q*/
128 1120 : wh_fx = &win_fx[( segment_length2 - 1 )]; /*Q15*/
129 1120 : wl_fx = win_fx; /*Q15*/
130 :
131 134160 : FOR( i = segment_length4; i < segment_length2; i++ )
132 : {
133 133040 : L_tmp = Mult_32_16( ( *sh_fx++ ), ( *wh_fx-- ) ); /*Q+15-15=Q */
134 133040 : dctin32_fx[i] = Madd_32_16( L_tmp, *sl_fx2--, *wl_fx++ ); /*Q*/
135 133040 : move32();
136 : }
137 :
138 1120 : Qs[seg] = *Q;
139 1120 : move16();
140 1120 : edct_fx( dctin32_fx, oseg_fx, segment_length2, &Qs[seg] );
141 1120 : Qmin = s_min( Qs[seg], Qmin );
142 :
143 1120 : iseg_fx += segment_length2;
144 1120 : oseg_fx += segment_length2;
145 : }
146 :
147 560 : sh_fx = &iseg_fx[( shift - 1 )]; /*Q*/
148 67080 : FOR( i = 0; i < segment_length4; i++ )
149 : {
150 66520 : dctin32_fx[i] = L_negate( *sh_fx-- ); /*Q*/
151 66520 : move32();
152 : }
153 :
154 :
155 560 : sh_fx = iseg_fx; /*Q*/
156 560 : sl_fx2 = &iseg_fx[( segment_length2 - 1 )]; /*Q*/
157 560 : wh_fx = &win_fx[( segment_length2 - 1 )]; /*Q15*/
158 560 : wl_fx = win_fx; /*Q15*/
159 :
160 67080 : FOR( i = segment_length4; i < segment_length2; i++ )
161 : {
162 66520 : L_tmp = Mult_32_16( ( *sl_fx2-- ), ( *wl_fx++ ) ); /*Q+15-15=Q */
163 66520 : dctin32_fx[i] = Madd_32_16( L_tmp, *sh_fx++, *wh_fx-- ); /*Q*/
164 66520 : move32();
165 : }
166 560 : Qs[NUM_TIME_SWITCHING_BLOCKS - 1] = *Q;
167 560 : move16();
168 560 : edct_fx( dctin32_fx, oseg_fx, segment_length2, &Qs[NUM_TIME_SWITCHING_BLOCKS - 1] );
169 560 : Qmin = s_min( Qs[NUM_TIME_SWITCHING_BLOCKS - 1], Qmin );
170 :
171 560 : *Q = Qmin;
172 560 : move16();
173 560 : oseg_fx = out32_fx; /*Q*/
174 2800 : FOR( k = 0; k < NUM_TIME_SWITCHING_BLOCKS; k++ )
175 : {
176 2240 : shift = sub( Qs[k], *Q );
177 534400 : FOR( i = 0; i < segment_length2; i++ )
178 : {
179 532160 : *oseg_fx = L_shr( ( *oseg_fx ), shift ); /*Q*/
180 532160 : move32();
181 532160 : oseg_fx++;
182 : }
183 : }
184 : }
185 : ELSE
186 : {
187 45326 : edct_fx( in32_fx, out32_fx, L, Q );
188 : }
189 :
190 45886 : return;
191 : }
|