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" /* Compilation switches */
7 : #include "cnst.h" /* Common constants */
8 : #include "prot_fx.h" /* Function prototypes */
9 : #include "rom_com.h"
10 :
11 :
12 : /*-------------------------------------------------*
13 : * Local constants
14 : *-------------------------------------------------*/
15 :
16 : #define LIMIT_PIT_REL_LOWER 2 /* delta interval to extend pitch coding in relative Q */
17 : #define LIMIT_PIT_REL_UPPER 0
18 :
19 : /*-------------------------------------------------*
20 : * limit_T0()
21 : *
22 : * Close-loop pitch lag search limitation
23 : *-------------------------------------------------*/
24 :
25 541632 : void limit_T0_fx(
26 : const Word16 L_frame, /* i : length of the frame Q0*/
27 : const Word16 delta, /* i : Half the close-loop searched interval Q0*/
28 : const Word16 pit_flag, /* i : selecting absolute(0) or delta(1) pitch quantization Q0*/
29 : const Word16 limit_flag, /* i : flag for Q limits (0=restrained, 1=extended) Q0*/
30 : const Word16 T0, /* i : rough pitch estimate around which the search is done Q0*/
31 : const Word16 T0_frac, /* i : pitch estimate fractional part Q0*/
32 : Word16 *T0_min, /* o : lower pitch limit Q0*/
33 : Word16 *T0_max /* o : higher pitch limit Q0*/
34 : )
35 : {
36 :
37 : Word16 delta2, T1;
38 : Word16 pit_min, pit_max;
39 :
40 541632 : IF( limit_flag == 0 ) /* restrained Q limits */
41 : {
42 : /* set limits */
43 64203 : IF( EQ_16( L_frame, L_FRAME ) )
44 : {
45 61625 : pit_max = PIT_MAX;
46 61625 : move16();
47 61625 : pit_min = PIT_MIN;
48 61625 : move16();
49 : }
50 : ELSE /* L_frame == L_FRAME16k */
51 : {
52 2578 : pit_max = PIT16k_MAX;
53 2578 : move16();
54 2578 : pit_min = PIT16k_MIN;
55 2578 : move16();
56 : }
57 :
58 64203 : delta2 = sub( shl( delta, 1 ), 1 ); /*Q0*/
59 64203 : T1 = T0;
60 64203 : move16();
61 :
62 64203 : if ( GE_16( T0_frac, 2 ) )
63 : {
64 27351 : T1 = add( T1, 1 );
65 : }
66 :
67 64203 : *T0_min = sub( T1, delta );
68 64203 : move16();
69 :
70 64203 : *T0_min = s_max( *T0_min, pit_min );
71 64203 : move16();
72 :
73 64203 : *T0_max = add( *T0_min, delta2 );
74 64203 : move16();
75 :
76 64203 : IF( GT_16( *T0_max, pit_max ) )
77 : {
78 699 : *T0_max = pit_max;
79 699 : move16();
80 699 : *T0_min = sub( *T0_max, delta2 );
81 699 : move16();
82 : }
83 : }
84 : ELSE /* extended Q limits */
85 : {
86 : /* set limits */
87 477429 : IF( EQ_16( L_frame, L_FRAME ) )
88 : {
89 163151 : pit_max = PIT_MAX;
90 163151 : move16();
91 163151 : pit_min = PIT_MIN_EXTEND;
92 163151 : move16();
93 163151 : if ( EQ_16( limit_flag, 2 ) )
94 : {
95 29648 : pit_min = PIT_MIN_DOUBLEEXTEND;
96 29648 : move16();
97 : }
98 : }
99 : ELSE /* L_frame == L_FRAME16k */
100 : {
101 314278 : pit_max = PIT16k_MAX;
102 314278 : move16();
103 314278 : pit_min = PIT16k_MIN_EXTEND;
104 314278 : move16();
105 : }
106 :
107 477429 : delta2 = sub( shl( delta, 1 ), 1 ); /*Q0*/
108 477429 : move16();
109 477429 : T1 = T0;
110 477429 : move16();
111 477429 : if ( GE_16( T0_frac, 2 ) )
112 : {
113 238446 : T1 = add( T1, 1 );
114 : }
115 477429 : *T0_min = sub( T1, delta );
116 477429 : move16();
117 477429 : IF( pit_flag == 0 )
118 : {
119 : /* subframes with absolute search: keep Q range */
120 1783 : *T0_min = s_max( *T0_min, pit_min );
121 1783 : move16();
122 1783 : *T0_max = add( *T0_min, delta2 );
123 1783 : move16();
124 1783 : IF( GT_16( *T0_max, pit_max ) )
125 : {
126 1 : *T0_max = pit_max;
127 1 : move16();
128 1 : *T0_min = sub( *T0_max, delta2 );
129 1 : move16();
130 : }
131 : }
132 : ELSE
133 : {
134 : /* subframes with relative search: extend Q range */
135 475646 : *T0_min = s_max( *T0_min, sub( pit_min, LIMIT_PIT_REL_LOWER ) );
136 475646 : move16();
137 :
138 475646 : *T0_min = s_max( *T0_min, L_INTERPOL );
139 475646 : move16();
140 475646 : *T0_max = *T0_min + delta2;
141 475646 : move16();
142 :
143 475646 : IF( GT_16( *T0_max, add( pit_max, LIMIT_PIT_REL_UPPER ) ) )
144 : {
145 4029 : *T0_max = add( pit_max, LIMIT_PIT_REL_UPPER );
146 4029 : move16();
147 4029 : *T0_min = sub( *T0_max, delta2 );
148 4029 : move16();
149 : }
150 : }
151 : }
152 541632 : return;
153 : }
154 :
155 :
156 : #define inv_T0_res InvIntTable
157 :
158 : /*-------------------------------------------------*
159 : * Routine limit_T0_voiced()
160 : *
161 : * Close-loop pitch lag search limitation
162 : *-------------------------------------------------*/
163 2098 : void limit_T0_voiced(
164 : const Word16 nbits,
165 : const Word16 res,
166 : const Word16 T0, /* i : rough pitch estimate around which the search is done Q0*/
167 : const Word16 T0_frac, /* i : pitch estimate fractional part Q0*/
168 : const Word16 T0_res, /* i : pitch resolution Q0*/
169 : Word16 *T0_min, /* o : lower pitch limit Q0*/
170 : Word16 *T0_min_frac, /* o : lower pitch limit Q0*/
171 : Word16 *T0_max, /* o : higher pitch limit Q0*/
172 : Word16 *T0_max_frac, /* o : higher pitch limit Q0*/
173 : const Word16 pit_min, /* i : Minimum pitch lag Q0*/
174 : const Word16 pit_max /* i : Maximum pitch lag Q0*/
175 : )
176 : {
177 : Word16 T1, temp1, temp2, res2;
178 :
179 :
180 2098 : assert( res > 1 && res <= 6 );
181 :
182 2098 : res2 = res; /*Q0*/
183 2098 : move16();
184 2098 : if ( EQ_16( res, 6 ) )
185 : {
186 0 : res2 = shr( res2, 1 ); /*Q0*/
187 : }
188 :
189 : /* Mid-point */
190 2098 : T1 = T0; /*Q0*/
191 2098 : test();
192 2098 : if ( GT_16( T0_res, 1 ) && GE_16( T0_frac, ( shr( T0_res, 1 ) ) ) )
193 : {
194 0 : T1 = add( T1, 1 );
195 : }
196 :
197 : /* Lower-bound */
198 2098 : temp1 = sub( i_mult( T1, res ), shl( 1, sub( nbits, 1 ) ) ); /*Q0*/
199 :
200 2098 : temp2 = mult( temp1, inv_T0_res[res2] );
201 2098 : if ( EQ_16( res, 6 ) )
202 : {
203 0 : temp2 = shr( temp2, 1 ); /*Q0*/
204 : }
205 :
206 2098 : *T0_min = temp2;
207 2098 : move16();
208 :
209 2098 : *T0_min_frac = sub( temp1, i_mult( temp2, res ) );
210 2098 : move16();
211 :
212 2098 : IF( LT_16( *T0_min, pit_min ) )
213 : {
214 285 : *T0_min = pit_min;
215 285 : move16();
216 285 : *T0_min_frac = 0;
217 285 : move16();
218 : }
219 :
220 : /* Higher-bound */
221 2098 : temp1 = add( i_mult( *T0_min, res ), add( *T0_min_frac, sub( shl( 1, nbits ), 1 ) ) ); /*Q0*/
222 :
223 2098 : temp2 = mult( temp1, inv_T0_res[res2] );
224 2098 : if ( EQ_16( res, 6 ) )
225 : {
226 0 : temp2 = shr( temp2, 1 );
227 : }
228 :
229 2098 : *T0_max = temp2;
230 2098 : move16();
231 :
232 2098 : *T0_max_frac = sub( temp1, i_mult( temp2, res ) );
233 2098 : move16();
234 :
235 2098 : IF( GT_16( *T0_max, pit_max ) )
236 : {
237 15 : *T0_max = pit_max;
238 15 : move16();
239 :
240 15 : *T0_max_frac = sub( res, 1 );
241 15 : move16();
242 :
243 15 : temp1 = add( i_mult( *T0_max, res ), sub( *T0_max_frac, sub( shl( 1, nbits ), 1 ) ) );
244 :
245 15 : temp2 = mult( temp1, inv_T0_res[res2] ); /*Q0*/
246 15 : if ( EQ_16( res, 6 ) )
247 : {
248 0 : temp2 = shr( temp2, 1 ); /*Q0*/
249 : }
250 15 : move16();
251 15 : *T0_min = temp2;
252 :
253 15 : *T0_min_frac = sub( temp1, i_mult( temp2, res ) ); /*Q0*/
254 15 : move16();
255 : }
256 :
257 :
258 2098 : return;
259 : }
|