Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <assert.h>
38 : #include <stdint.h>
39 : #include "options.h"
40 : #include "basop_proto_func.h"
41 : #include "basop_util.h"
42 :
43 : #define WMC_TOOL_SKIP
44 :
45 : #define NC_MAX 8
46 :
47 : static Word16 E_LPC_f_lsp_pol_get( const Word16 lsp[], Word32 f[], const Word16 n, const Word16 past_Ovf, const Word16 isMODE1 );
48 :
49 :
50 : /*
51 : * E_LPC_f_lsp_a_conversion
52 : *
53 : * Parameters:
54 : * lsp I: Line spectral pairs Q15
55 : * a O: Predictor coefficients (order = m) Qx (The Q factor of the output to be deduced from a(0))
56 : * m I: order of LP filter
57 : *
58 : * Function:
59 : * Convert ISPs to predictor coefficients a[]
60 : *
61 : * Returns:
62 : * void
63 : */
64 635091 : void basop_E_LPC_f_lsp_a_conversion(
65 : const Word16 *lsp,
66 : Word16 *a,
67 : const Word16 m )
68 : {
69 : Word16 i, j, k;
70 : Word32 f1[NC_MAX + 1], f2[NC_MAX + 1];
71 : Word16 nc;
72 : Word32 t0;
73 : Word16 Ovf, Ovf2;
74 :
75 :
76 : /*-----------------------------------------------------*
77 : * Find the polynomials F1(z) and F2(z) *
78 : *-----------------------------------------------------*/
79 :
80 635091 : nc = shr( m, 1 );
81 :
82 635091 : assert( m == 16 || m == 10 );
83 :
84 635091 : Ovf = 0;
85 635091 : move16();
86 635091 : Ovf = E_LPC_f_lsp_pol_get( &lsp[0], f1, nc, Ovf, 1 );
87 635091 : Ovf2 = E_LPC_f_lsp_pol_get( &lsp[1], f2, nc, Ovf, 1 );
88 635091 : IF( sub( Ovf2, Ovf ) != 0 )
89 : {
90 : /* to ensure similar scaling for f1 and f2 in case
91 : an overflow would be detected only in f2,
92 : but this case never happen on my dtb */
93 0 : E_LPC_f_lsp_pol_get( &lsp[0], f1, nc, s_max( Ovf2, Ovf ), 1 );
94 : }
95 : /*-----------------------------------------------------*
96 : * Multiply F1(z) by (1+z^-1) and F2(z) by (1-z^-1) *
97 : *-----------------------------------------------------*/
98 : /*modification*/
99 635091 : k = sub( nc, 1 );
100 5715819 : FOR( i = 0; i <= k; i++ )
101 : {
102 5080728 : f1[nc - i] = L_add( f1[nc - i], f1[nc - i - 1] );
103 5080728 : move32();
104 5080728 : f2[nc - i] = L_sub( f2[nc - i], f2[nc - i - 1] );
105 5080728 : move32();
106 : }
107 :
108 : /*-----------------------------------------------------*
109 : * A(z) = (F1(z)+F2(z))/2 *
110 : * F1(z) is symmetric and F2(z) is antisymmetric *
111 : *-----------------------------------------------------*/
112 :
113 635091 : t0 = L_deposit_l( 0 );
114 5715819 : FOR( i = 1; i <= nc; i++ )
115 : {
116 5080728 : t0 = L_max( t0, L_abs( L_add( f1[i], f2[i] ) ) );
117 5080728 : t0 = L_max( t0, L_abs( L_sub( f1[i], f2[i] ) ) );
118 : }
119 635091 : k = s_min( norm_l( t0 ), 6 );
120 635091 : a[0] = shl( 256, k );
121 635091 : move16();
122 635091 : test();
123 635091 : IF( Ovf || Ovf2 )
124 : {
125 0 : a[0] = shl( 256, sub( k, Ovf ) );
126 0 : move16();
127 : }
128 635091 : j = m;
129 5715819 : FOR( i = 1; i <= nc; i++ )
130 : {
131 : /* a[i] = 0.5*(f1[i] + f2[i]) */
132 5080728 : t0 = L_add( f1[i], f2[i] );
133 5080728 : t0 = L_shl( t0, k );
134 5080728 : a[i] = round_fx( t0 ); /* from Q23 to Qx and * 0.5 */
135 :
136 : /* a[j] = 0.5*(f1[i] - f2[i]) */
137 5080728 : t0 = L_sub( f1[i], f2[i] );
138 5080728 : t0 = L_shl( t0, k );
139 5080728 : a[j] = round_fx( t0 ); /* from Q23 to Qx and * 0.5 */
140 5080728 : j--;
141 : }
142 :
143 635091 : return;
144 : }
145 :
146 :
147 : /*---------------------------------------------------------------------------
148 : * procedure reorder_lsf()
149 : *
150 : * To make sure that the lsfs are properly ordered and to keep a certain
151 : * minimum distance between consecutive lsfs.
152 : *--------------------------------------------------------------------------*/
153 635283 : void basop_reorder_lsf(
154 : Word16 *lsf, /* i/o: LSFs in the frequency domain (0..0.5) Q(x2.56)*/
155 : const Word16 min_dist, /* i : minimum required distance x2.56*/
156 : const Word16 n, /* i : LPC order */
157 : const Word32 Fs /* i : sampling frequency */
158 : )
159 : {
160 : Word16 i, lsf_min, n_m_1;
161 : Word16 lsf_max;
162 :
163 635283 : lsf_min = min_dist;
164 635283 : move16();
165 :
166 : /*-----------------------------------------------------------------------*
167 : * Verify the LSF ordering and minimum GAP
168 : *-----------------------------------------------------------------------*/
169 :
170 10799811 : FOR( i = 0; i < n; i++ )
171 : {
172 10164528 : if ( sub( lsf[i], lsf_min ) < 0 )
173 : {
174 0 : lsf[i] = lsf_min;
175 0 : move16();
176 : }
177 10164528 : lsf_min = add( lsf[i], min_dist );
178 : }
179 :
180 : /*-----------------------------------------------------------------------*
181 : * Reverify the LSF ordering and minimum GAP in the reverse order (security)
182 : *-----------------------------------------------------------------------*/
183 :
184 635283 : lsf_max = round_fx( L_sub( L_shr( L_mult0( extract_l( L_shr( Fs, 1 ) ), 1311 ), 9 - 16 ), L_deposit_h( min_dist ) ) ); /* Q0 + Q9 , 1311 is 2.56 in Q9 */
185 :
186 635283 : n_m_1 = sub( n, 1 );
187 635283 : IF( sub( lsf[n_m_1], lsf_max ) > 0 ) /* If danger of unstable filter in case of resonance in HF */
188 : {
189 0 : FOR( i = n_m_1; i >= 0; i-- ) /* Reverify the minimum LSF gap in the reverse direction */
190 : {
191 0 : if ( sub( lsf[i], lsf_max ) > 0 )
192 : {
193 0 : lsf[i] = lsf_max;
194 0 : move16();
195 : }
196 0 : lsf_max = sub( lsf[i], min_dist );
197 : }
198 : }
199 :
200 635283 : return;
201 : }
202 :
203 :
204 : /*
205 : * E_LPC_f_lsp_pol_get
206 : *
207 : * Parameters:
208 : * lsp/isp I: Line spectral pairs (cosine domaine) Q15
209 : * f O: the coefficients of F1 or F2 Q23
210 : * n I: no of coefficients (m/2)
211 : * == NC for F1(z); == NC-1 for F2(z)
212 : * fact I: scaling factor
213 : *
214 : *-----------------------------------------------------------*
215 : * procedure E_LPC_f_lsp_pol_get: *
216 : * ~~~~~~~~~~~ *
217 : * Find the polynomial F1(z) or F2(z) from the LSPs. *
218 : * This is performed by expanding the product polynomials: *
219 : * *
220 : * F1(z) = product ( 1 - 2 LSF_i z^-1 + z^-2 ) *
221 : * i=0,2,4,6,8 *
222 : * F2(z) = product ( 1 - 2 LSF_i z^-1 + z^-2 ) *
223 : * i=1,3,5,7,9 *
224 : * *
225 : * where LSP_i are the LSPs in the cosine domain. *
226 : * *
227 : *-----------------------------------------------------------*
228 : * R.A.Salami October 1990 *
229 : *-----------------------------------------------------------*
230 : */
231 1270182 : static Word16 E_LPC_f_lsp_pol_get(
232 : const Word16 lsp[],
233 : Word32 f[],
234 : const Word16 n,
235 : const Word16 past_Ovf,
236 : const Word16 isMODE1 )
237 : {
238 : /* All computation in Q23 */
239 : const Word16 *plsp;
240 : Word16 i, j;
241 : Word16 b;
242 : Word32 b32;
243 1270182 : Word16 Ovf = 0;
244 : Word16 Q_out;
245 : Word16 m2;
246 : #ifdef BASOP_NOGLOB
247 : Flag Overflow;
248 : #endif /* BASOP_NOGLOB */
249 :
250 :
251 1270182 : Q_out = 31 - 23;
252 1270182 : move16();
253 1270182 : Ovf = past_Ovf;
254 1270182 : move16();
255 :
256 1270182 : test();
257 1270182 : if ( past_Ovf && isMODE1 ) /* Currently this feature is implemented only in MODE1 */
258 : {
259 : /* In some NB cases, overflow where detectected
260 : in f1 or f2 polynomial computation when it
261 : happen we reduce the precision of the computing
262 : to limit the risk of saturation*/
263 0 : Q_out = add( Q_out, past_Ovf );
264 : }
265 1270182 : Overflow = 0;
266 1270182 : move16();
267 1270182 : plsp = lsp;
268 1270182 : f[0] = L_shl( 1, sub( 31, Q_out ) );
269 1270182 : move32();
270 : /*b = -2.0f * *plsp;*/
271 1270182 : b = *plsp;
272 1270182 : move16();
273 1270182 : m2 = shl( -2, sub( 15, Q_out ) );
274 1270182 : f[1] = L_mult( b, m2 );
275 1270182 : move32();
276 :
277 10161456 : FOR( i = 2; i <= n; i++ )
278 : {
279 8891274 : plsp += 2;
280 : /*b = 2.0f * *plsp;*/
281 8891274 : move16();
282 8891274 : b = *plsp;
283 8891274 : b32 = L_mult( b, m2 );
284 :
285 : /*f[i] = -b*f[i-1] + 2.0f*f[i-2];*/
286 8891274 : move32();
287 8891274 : f[i] = L_shl( L_sub( f[i - 2], Mpy_32_16( f[i - 1], b ) ), 1 );
288 :
289 35565096 : FOR( j = i - 1; j > 1; j-- )
290 : {
291 : /*f[j] += b*f[j-1] + f[j-2];*/
292 26673822 : move32();
293 26673822 : f[j] = L_add( f[j], L_sub( f[j - 2], L_shl( Mpy_32_16( f[j - 1], b ), 1 ) ) );
294 : }
295 8891274 : move32();
296 8891274 : f[1] = L_add( f[1], b32 );
297 : }
298 :
299 :
300 1270182 : test();
301 1270182 : IF( Overflow > 0 && isMODE1 )
302 : {
303 : #ifdef BASOP_NOGLOB
304 0 : assert( 0 );
305 : #endif /* BASOP_NOGLOB */
306 : /* If an overflow is detected, redo the computation with 1 bit less */
307 : Ovf = add( Ovf, 1 );
308 : Ovf = E_LPC_f_lsp_pol_get( lsp, f, n, Ovf, isMODE1 );
309 : }
310 1270182 : return Ovf;
311 : }
312 :
313 : #undef WMC_TOOL_SKIP
|