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 21294 : 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 21294 : Word16 shift, Qmin = 31;
41 : Word32 L_tmp;
42 : Word16 Qs[NUM_TIME_SWITCHING_BLOCKS];
43 : (void) ( element_mode );
44 21294 : move16();
45 :
46 21294 : segment_length = shr( L, 1 );
47 21294 : segment_length2 = shr( segment_length, 1 );
48 21294 : segment_length4 = shr( segment_length2, 1 );
49 :
50 21294 : IF( is_transient )
51 : {
52 0 : IF( EQ_16( L, L_FRAME48k ) )
53 : {
54 0 : win_fx = wscw16q15_fx; /*Q15*/
55 : }
56 0 : ELSE IF( EQ_16( L, L_FRAME32k ) )
57 : {
58 0 : 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 0 : sh_fx = &in32_fx[( L - 1 )]; /*Q*/
70 0 : sl_fx = &in32_r16_fx[( L - 1 )]; /*Q*/
71 0 : FOR( i = 0; i < segment_length; i++ )
72 : {
73 0 : in32_r16_fx[i] = ( *sh_fx-- ); /*Q*/
74 0 : move32();
75 0 : ( *sl_fx-- ) = in32_fx[i]; /*Q*/
76 0 : move32();
77 : }
78 :
79 0 : iseg_fx = &in32_r16_fx[-segment_length4]; /*Q*/
80 0 : oseg_fx = out32_fx; /*Q*/
81 :
82 0 : wh_fx = &win_fx[segment_length4]; /*Q15*/
83 0 : wl_fx = wh_fx - 1; /*Q15*/
84 :
85 0 : shift = extract_l( L_mult0( 3, segment_length4 ) ); /*Q0*/
86 0 : sh_fx = &iseg_fx[shift]; /*Q*/
87 0 : sl_fx2 = sh_fx - 1; /*Q*/
88 :
89 :
90 0 : FOR( i = 0; i < segment_length4; i++ )
91 : {
92 0 : L_tmp = L_negate( Mult_32_16( ( *sh_fx++ ), ( *wh_fx++ ) ) ); /*Q+15-15=Q */
93 0 : dctin32_fx[i] = Madd_32_16( L_tmp, *sl_fx2--, *wl_fx-- ); /*Q*/
94 0 : move32();
95 : }
96 :
97 0 : sl_fx2 = &iseg_fx[( segment_length2 - 1 )]; /*Q*/
98 :
99 0 : FOR( i = segment_length4; i < segment_length2; i++ )
100 : {
101 0 : dctin32_fx[i] = L_negate( *sl_fx2-- ); /*Q*/
102 0 : move32();
103 : }
104 :
105 0 : Qs[0] = *Q;
106 0 : move16();
107 0 : edct_fx( dctin32_fx, oseg_fx, segment_length2, &Qs[0] );
108 0 : Qmin = s_min( Qs[0], Qmin );
109 :
110 0 : iseg_fx += segment_length2;
111 0 : oseg_fx += segment_length2;
112 :
113 0 : FOR( seg = 1; seg < NUM_TIME_SWITCHING_BLOCKS - 1; seg++ )
114 : {
115 0 : wh_fx = &win_fx[segment_length4]; /*Q15*/
116 0 : wl_fx = wh_fx - 1; /*Q15*/
117 0 : sh_fx = &iseg_fx[shift]; /*Q*/
118 0 : sl_fx2 = sh_fx - 1; /*Q*/
119 0 : FOR( i = 0; i < segment_length4; i++ )
120 : {
121 0 : L_tmp = L_negate( Mult_32_16( ( *sh_fx++ ), ( *wh_fx++ ) ) ); /*Q+15-15=Q */
122 0 : dctin32_fx[i] = Madd_32_16( L_tmp, *sl_fx2--, *wl_fx-- ); /*Q*/
123 0 : move32();
124 : }
125 :
126 0 : sh_fx = iseg_fx; /*Q*/
127 0 : sl_fx2 = &iseg_fx[( segment_length2 - 1 )]; /*Q*/
128 0 : wh_fx = &win_fx[( segment_length2 - 1 )]; /*Q15*/
129 0 : wl_fx = win_fx; /*Q15*/
130 :
131 0 : FOR( i = segment_length4; i < segment_length2; i++ )
132 : {
133 0 : L_tmp = Mult_32_16( ( *sh_fx++ ), ( *wh_fx-- ) ); /*Q+15-15=Q */
134 0 : dctin32_fx[i] = Madd_32_16( L_tmp, *sl_fx2--, *wl_fx++ ); /*Q*/
135 0 : move32();
136 : }
137 :
138 0 : Qs[seg] = *Q;
139 0 : move16();
140 0 : edct_fx( dctin32_fx, oseg_fx, segment_length2, &Qs[seg] );
141 0 : Qmin = s_min( Qs[seg], Qmin );
142 :
143 0 : iseg_fx += segment_length2;
144 0 : oseg_fx += segment_length2;
145 : }
146 :
147 0 : sh_fx = &iseg_fx[( shift - 1 )]; /*Q*/
148 0 : FOR( i = 0; i < segment_length4; i++ )
149 : {
150 0 : dctin32_fx[i] = L_negate( *sh_fx-- ); /*Q*/
151 0 : move32();
152 : }
153 :
154 :
155 0 : sh_fx = iseg_fx; /*Q*/
156 0 : sl_fx2 = &iseg_fx[( segment_length2 - 1 )]; /*Q*/
157 0 : wh_fx = &win_fx[( segment_length2 - 1 )]; /*Q15*/
158 0 : wl_fx = win_fx; /*Q15*/
159 :
160 0 : FOR( i = segment_length4; i < segment_length2; i++ )
161 : {
162 0 : L_tmp = Mult_32_16( ( *sl_fx2-- ), ( *wl_fx++ ) ); /*Q+15-15=Q */
163 0 : dctin32_fx[i] = Madd_32_16( L_tmp, *sh_fx++, *wh_fx-- ); /*Q*/
164 0 : move32();
165 : }
166 0 : Qs[NUM_TIME_SWITCHING_BLOCKS - 1] = *Q;
167 0 : move16();
168 0 : edct_fx( dctin32_fx, oseg_fx, segment_length2, &Qs[NUM_TIME_SWITCHING_BLOCKS - 1] );
169 0 : Qmin = s_min( Qs[NUM_TIME_SWITCHING_BLOCKS - 1], Qmin );
170 :
171 0 : *Q = Qmin;
172 0 : move16();
173 0 : oseg_fx = out32_fx; /*Q*/
174 0 : FOR( k = 0; k < NUM_TIME_SWITCHING_BLOCKS; k++ )
175 : {
176 0 : shift = sub( Qs[k], *Q );
177 0 : FOR( i = 0; i < segment_length2; i++ )
178 : {
179 0 : *oseg_fx = L_shr( ( *oseg_fx ), shift ); /*Q*/
180 0 : move32();
181 0 : oseg_fx++;
182 : }
183 : }
184 : }
185 : ELSE
186 : {
187 21294 : edct_fx( in32_fx, out32_fx, L, Q );
188 : }
189 :
190 21294 : return;
191 : }
|