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 <stdint.h>
38 : #include "options.h"
39 : #include <math.h>
40 : #include "prot.h"
41 : #ifdef DEBUGGING
42 : #include "debug.h"
43 : #endif
44 : #include "wmc_auto.h"
45 :
46 : /*-------------------------------------------------------------------*
47 : * tcxGetNoiseFillingTilt()
48 : *
49 : *
50 : *-------------------------------------------------------------------*/
51 :
52 4215937 : int16_t tcxGetNoiseFillingTilt(
53 : const float A[],
54 : const int16_t L_frame,
55 : const int16_t mode,
56 : float *noiseTiltFactor )
57 : {
58 : int16_t firstLine;
59 :
60 4215937 : if ( mode )
61 : {
62 4051720 : firstLine = L_frame / 6;
63 4051720 : *noiseTiltFactor = 0.5625f;
64 : }
65 : else
66 : {
67 164217 : firstLine = L_frame / 8;
68 164217 : *noiseTiltFactor = get_gain( A + 1, A, M, NULL );
69 164217 : *noiseTiltFactor = min( 1.0f, ( *noiseTiltFactor ) + 0.09375f );
70 : }
71 :
72 4215937 : return firstLine;
73 : }
74 :
75 : /*-------------------------------------------------------------------*
76 : * tcxFormantEnhancement()
77 : *
78 : *
79 : *-------------------------------------------------------------------*/
80 :
81 130179 : void tcxFormantEnhancement(
82 : float xn_buf[],
83 : const float *gainlpc,
84 : float spectrum[],
85 : const int16_t L_frame )
86 : {
87 130179 : int16_t k, i, j, l = 0;
88 : float fac, step;
89 :
90 130179 : k = L_frame / FDNS_NPTS;
91 :
92 : /* Formant enhancement via square root of the LPC gains */
93 130179 : xn_buf[0] = (float) sqrt( gainlpc[0] );
94 130179 : xn_buf[1] = (float) sqrt( gainlpc[1] );
95 130179 : fac = 1.0f / min( xn_buf[0], xn_buf[1] );
96 :
97 8201277 : for ( i = 1; i < FDNS_NPTS - 1; i++ )
98 : {
99 8071098 : xn_buf[i + 1] = (float) sqrt( gainlpc[i + 1] );
100 :
101 8071098 : if ( ( xn_buf[i - 1] <= xn_buf[i] ) && ( xn_buf[i + 1] <= xn_buf[i] ) )
102 : {
103 392999 : step = max( xn_buf[i - 1], xn_buf[i + 1] );
104 392999 : step = ( 1.0f / step - fac ) / (float) ( i - l );
105 392999 : xn_buf[l] = 1.0f;
106 392999 : fac += step;
107 5828991 : for ( j = l + 1; j < i; j++ )
108 : {
109 5435992 : xn_buf[j] = min( 1.0f, xn_buf[j] * fac );
110 5435992 : fac += step;
111 : }
112 392999 : l = i;
113 : }
114 : }
115 :
116 : /* i = hTcxCfg->fdns_npts - 1; Completing changes to gains */
117 130179 : step = min( xn_buf[i - 1], xn_buf[i] );
118 130179 : step = ( 1.0f / step - fac ) / (float) ( i - l );
119 130179 : xn_buf[l] = 1.0f;
120 130179 : fac += step;
121 2372286 : for ( j = l + 1; j < i; j++ )
122 : {
123 2242107 : xn_buf[j] = min( 1.0f, xn_buf[j] * fac );
124 2242107 : fac += step;
125 : }
126 130179 : xn_buf[i] = 1.0f;
127 :
128 : /* Application of changed gains onto decoded MDCT lines */
129 8461635 : for ( i = j = 0; i < L_frame; j++ )
130 : {
131 42234816 : for ( l = 0; l < k; i++, l++ )
132 : {
133 33903360 : spectrum[i] *= xn_buf[j];
134 : }
135 : }
136 :
137 130179 : return;
138 : }
139 :
140 : /*-------------------------------------------------------------------*
141 : * tcxInvertWindowGrouping()
142 : *
143 : *
144 : *-------------------------------------------------------------------*/
145 :
146 4154 : void tcxInvertWindowGrouping(
147 : TCX_CONFIG_HANDLE hTcxCfg,
148 : float xn_buf[],
149 : float spectrum[],
150 : const int16_t L_frame,
151 : const int16_t fUseTns,
152 : const int16_t last_core,
153 : const int16_t index,
154 : const int16_t frame_cnt,
155 : const int16_t bfi )
156 : {
157 : int16_t i, w, t_integer;
158 : int16_t L_win, L_spec;
159 :
160 4154 : if ( frame_cnt && !bfi && last_core != ACELP_CORE )
161 : {
162 : /* fix sub-window overlap */
163 2077 : hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode;
164 : }
165 :
166 4154 : if ( ( ( !bfi ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
167 2521 : ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) ) ) ||
168 0 : ( ( bfi ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) &&
169 0 : !( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) ) ) )
170 : {
171 :
172 : /* ungroup sub-windows: deinterleave MDCT bins into separate windows */
173 6693 : for ( t_integer = w = 0; w < 2; w++ )
174 : {
175 1055182 : for ( i = w; i < L_frame; i += 2 )
176 : {
177 1050720 : xn_buf[t_integer++] = spectrum[i];
178 : }
179 : }
180 :
181 2231 : mvr2r( xn_buf, spectrum, L_frame );
182 :
183 2231 : if ( hTcxCfg->fIsTNSAllowed && !bfi && fUseTns )
184 : {
185 1749 : L_win = L_frame >> 1;
186 1749 : L_spec = hTcxCfg->tnsConfig[0][0].iFilterBorders[0];
187 :
188 : /* rearrange LF sub-window lines prior to TNS synthesis filtering */
189 1749 : if ( L_spec < L_frame )
190 : {
191 1653 : mvr2r( spectrum + 8, spectrum + 16, L_spec / 2 - 8 );
192 1653 : mvr2r( spectrum + L_frame / 2, spectrum + 8, 8 );
193 1653 : mvr2r( spectrum + L_frame / 2 + 8, spectrum + L_spec / 2 + 8, L_spec / 2 - 8 );
194 : }
195 : else
196 : {
197 96 : mvr2r( spectrum + 8, xn_buf, L_win );
198 96 : mvr2r( xn_buf, spectrum + 16, L_win - 8 );
199 96 : mvr2r( xn_buf + L_win - 8, spectrum + 8, 8 );
200 : }
201 : }
202 : }
203 :
204 4154 : return;
205 : }
206 :
207 :
208 : /*-------------------------------------------------------------------*
209 : * tcx5SpectrumInterleaving()
210 : *
211 : *
212 : *-------------------------------------------------------------------*/
213 :
214 113129 : void tcx5SpectrumInterleaving(
215 : const int16_t tcx5Size,
216 : float *spectrum )
217 : {
218 : int16_t i;
219 : float interleaveBuf[N_TCX10_MAX];
220 :
221 113129 : set_f( interleaveBuf, 0.0f, N_TCX10_MAX );
222 :
223 : /* group sub-windows: interleave bins according to their frequencies */
224 23958889 : for ( i = 0; i < tcx5Size; i++ )
225 : {
226 23845760 : interleaveBuf[2 * i] = spectrum[i];
227 23845760 : interleaveBuf[2 * i + 1] = spectrum[tcx5Size + i];
228 : }
229 :
230 113129 : mvr2r( interleaveBuf, spectrum, 2 * tcx5Size );
231 :
232 113129 : return;
233 : }
234 :
235 :
236 : /*-------------------------------------------------------------------*
237 : * tcx5SpectrumDeinterleaving()
238 : *
239 : *
240 : *-------------------------------------------------------------------*/
241 :
242 134194 : void tcx5SpectrumDeinterleaving(
243 : const int16_t tcx5Size,
244 : float *spectrum )
245 : {
246 : int16_t i;
247 : float interleaveBuf[N_TCX10_MAX];
248 :
249 134194 : set_f( interleaveBuf, 0.0f, N_TCX10_MAX );
250 :
251 : /* ungroup sub-windows: interleave bins according to their frequencies */
252 28497314 : for ( i = 0; i < tcx5Size; i++ )
253 : {
254 28363120 : interleaveBuf[i] = spectrum[2 * i];
255 28363120 : interleaveBuf[tcx5Size + i] = spectrum[2 * i + 1];
256 : }
257 :
258 134194 : mvr2r( interleaveBuf, spectrum, 2 * tcx5Size );
259 :
260 134194 : return;
261 : }
262 :
263 :
264 : /*-------------------------------------------------------------------*
265 : * tcx5TnsGrouping()
266 : *
267 : *
268 : *-------------------------------------------------------------------*/
269 :
270 54713 : void tcx5TnsGrouping(
271 : const int16_t L_frame, /* i : frame length (TCX5) */
272 : const int16_t L_spec, /* i : coded spec length (TCX5, derived from filter borders*/
273 : float *spectrum )
274 : {
275 : /* rearrange LF sub-window lines prior to TNS synthesis filtering */
276 54713 : if ( L_spec < L_frame )
277 : {
278 30624 : mvr2r( spectrum + 8, spectrum + 16, L_spec - 8 );
279 30624 : mvr2r( spectrum + L_frame, spectrum + 8, 8 );
280 30624 : mvr2r( spectrum + L_frame + 8, spectrum + L_spec + 8, L_spec - 8 );
281 : }
282 : else
283 : {
284 : float buff[8]; /* Buffer for the rearrangement of LF TCX5 */
285 24089 : mvr2r( spectrum + L_spec, buff, 8 );
286 24089 : mvr2r( spectrum + 8, spectrum + 16, L_spec - 8 );
287 24089 : mvr2r( buff, spectrum + 8, 8 );
288 : }
289 :
290 54713 : return;
291 : }
292 :
293 :
294 : /*-------------------------------------------------------------------*
295 : * tcx5TnsUngrouping()
296 : *
297 : *
298 : *-------------------------------------------------------------------*/
299 :
300 54713 : void tcx5TnsUngrouping(
301 : const int16_t L_frame, /* i : frame length (TCX5) */
302 : const int16_t L_spec, /* i : coded spec length (TCX5, derived from filter borders*/
303 : float *spectrum,
304 : const int16_t enc_dec /* i : 0: encoder, else decoder */
305 : )
306 : {
307 : /* undo rearrangement of LF sub-window lines prior to TNS analysis */
308 54713 : if ( L_spec < L_frame )
309 : {
310 34158 : mvr2r( spectrum + L_spec + 8, spectrum + L_frame + 8, L_spec - 8 );
311 34158 : mvr2r( spectrum + 8, spectrum + L_frame, 8 );
312 34158 : mvr2r( spectrum + 16, spectrum + 8, L_spec - 8 );
313 34158 : set_zero( spectrum + L_spec, L_frame - L_spec );
314 34158 : set_zero( spectrum + L_frame + L_spec, L_frame - L_spec );
315 : }
316 : else
317 : {
318 : float buff[8]; /* Buffer for the rearrangement of LF TCX5 */
319 :
320 20555 : mvr2r( spectrum + 8, buff, 8 );
321 :
322 20555 : if ( enc_dec == ENC )
323 : {
324 7064 : mvr2r( spectrum + 16, spectrum + 8, L_frame - 8 );
325 7064 : mvr2r( buff, spectrum + L_frame, 8 );
326 : }
327 : else
328 : {
329 13491 : mvr2r( spectrum + 16, spectrum + 8, L_spec - 8 );
330 13491 : mvr2r( buff, spectrum + L_spec, 8 );
331 : }
332 : }
333 :
334 54713 : return;
335 : }
|