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 : #ifdef DEBUGGING
40 : #include "debug.h"
41 : #endif
42 : #include <math.h>
43 : #include "prot.h"
44 : #include "cnst.h"
45 : #include "stat_com.h"
46 : #include "wmc_auto.h"
47 :
48 :
49 : /*---------------------------------------------------------------------*
50 : * minimumStatistics()
51 : *
52 : *
53 : *---------------------------------------------------------------------*/
54 :
55 1086396 : void minimumStatistics(
56 : float *noiseLevelMemory,
57 : int16_t *noiseLevelIndex,
58 : int16_t *currLevelIndex,
59 : float *noiseEstimate,
60 : float *lastFrameLevel,
61 : float currentFrameLevel,
62 : const float minLev,
63 : const int16_t buffSize )
64 : {
65 : float aOpt, f;
66 : int16_t p, i;
67 :
68 1086396 : if ( currentFrameLevel < minLev )
69 : {
70 204678 : currentFrameLevel = minLev;
71 : }
72 : /* compute optimal factor aOpt for recursive smoothing of frame minima */
73 1086396 : if ( *lastFrameLevel >= *noiseEstimate )
74 : {
75 996435 : aOpt = *noiseEstimate / *lastFrameLevel;
76 : }
77 : else
78 : {
79 89961 : aOpt = *lastFrameLevel / *noiseEstimate;
80 : }
81 1086396 : aOpt *= aOpt;
82 1086396 : *lastFrameLevel = currentFrameLevel;
83 : /* recursively compute smoothed frame minima using optimal factor aOpt */
84 1086396 : f = currentFrameLevel * ( 1.0f - aOpt );
85 1086396 : f += aOpt * noiseLevelMemory[( *currLevelIndex ? *currLevelIndex : buffSize ) - 1];
86 : /* if current frame min is a new local min, set index to current index */
87 1086396 : p = *noiseLevelIndex;
88 1086396 : if ( noiseLevelMemory[p] >= f )
89 : {
90 274059 : noiseLevelMemory[*currLevelIndex] = f;
91 274059 : p = *currLevelIndex;
92 : }
93 : else
94 : {
95 812337 : noiseLevelMemory[*currLevelIndex] = f;
96 : /* current min is not a new min, so check if min must be re-searched */
97 812337 : if ( p != *currLevelIndex )
98 : {
99 768954 : f = noiseLevelMemory[p]; /* min is still in memory, so return it */
100 : }
101 : else
102 : {
103 : /* p == currLevelIndex; min was removed from memory, re-search min */
104 1268814 : for ( i = *currLevelIndex + 1; i < buffSize; i++ )
105 : {
106 1225431 : if ( f >= noiseLevelMemory[i] )
107 : {
108 67005 : f = noiseLevelMemory[i];
109 67005 : p = i;
110 : }
111 : }
112 987102 : for ( i = 0; i <= *currLevelIndex; i++ )
113 : {
114 943719 : if ( f >= noiseLevelMemory[i] )
115 : {
116 18384 : f = noiseLevelMemory[i];
117 18384 : p = i;
118 : }
119 : }
120 : }
121 : }
122 : /* update local-minimum-value index and current circular-buffer index */
123 1086396 : *noiseLevelIndex = p;
124 1086396 : p = *currLevelIndex + 1;
125 1086396 : *currLevelIndex = ( p == buffSize ) ? 0 : p;
126 :
127 1086396 : *noiseEstimate = f;
128 :
129 1086396 : return;
130 : }
131 :
132 : /*---------------------------------------------------------------------*
133 : * getLevelSynDeemph()
134 : *
135 : * PLC: [ACELP: Fade-out]
136 : * PLC: getLevelSynDeemph: derives on frame or subframe basis the level
137 : * of LPC synthesis and deeemphasis based on the given input
138 : *----------------------------------------------------------------------*/
139 :
140 16731 : float getLevelSynDeemph(
141 : const float h1Init[], /* i : input value or vector to be processed */
142 : const float A[], /* i : LPC coefficients */
143 : const int16_t lenLpcExc, /* i : length of the LPC excitation buffer */
144 : const float preemph_fac, /* i : preemphasis factor */
145 : const int16_t numLoops /* i : number of loops */
146 : )
147 : {
148 : float levelSynDeemphSub;
149 16731 : float levelSynDeemph = 0;
150 : float h1[L_FRAME_PLUS / 4];
151 : float mem[M];
152 16731 : float tmp = 0;
153 : int16_t loop;
154 :
155 33462 : for ( loop = 0; loop < numLoops; loop++ )
156 : {
157 16731 : set_zero( h1, lenLpcExc );
158 16731 : set_zero( mem, M );
159 :
160 16731 : h1[0] = *h1Init;
161 :
162 16731 : syn_filt( A, M, h1, h1, lenLpcExc, mem, 0 );
163 16731 : deemph( h1, preemph_fac, lenLpcExc, &tmp );
164 16731 : A += ( M + 1 );
165 :
166 : /* gain introduced by synthesis+deemphasis */
167 16731 : levelSynDeemphSub = (float) sqrt( dotp( h1, h1, lenLpcExc ) );
168 :
169 : /* mean of the above across all subframes */
170 16731 : levelSynDeemph += ( 1.0f / (float) numLoops ) * levelSynDeemphSub;
171 : }
172 :
173 16731 : return levelSynDeemph;
174 : }
175 :
176 :
177 : /*---------------------------------------------------------------------
178 : * genPlcFiltBWAdap()
179 : *
180 : *
181 : *---------------------------------------------------------------------*/
182 :
183 0 : void genPlcFiltBWAdap(
184 : const int32_t sr_core, /* i : core sampling rate */
185 : float *lpFiltAdapt, /* o : filter coefficients for filtering codebooks in case of flc */
186 : const int16_t type, /* i : type of filter, either 0 : lowpass or 1 : highpass */
187 : const float alpha /* i : fade out factor [0 1) used decrease filter tilt */
188 : )
189 : {
190 : float a;
191 :
192 0 : switch ( sr_core )
193 : {
194 0 : case INT_FS_16k:
195 0 : a = 0.4000f;
196 0 : break;
197 0 : default:
198 0 : a = 0.2813f; /*sr_core = INT_FS_12k8 */
199 0 : break;
200 : }
201 :
202 0 : switch ( type )
203 : {
204 0 : case 0:
205 0 : *lpFiltAdapt++ = a / ( 2.f * a + 1.f );
206 0 : *lpFiltAdapt++ = 1.f / ( 2.f * a + 1.f );
207 0 : *lpFiltAdapt = a / ( 2.f * a + 1.f );
208 0 : break;
209 0 : case 1:
210 0 : a *= alpha;
211 0 : *lpFiltAdapt++ = -a / ( 2.f * a + 1.f );
212 0 : *lpFiltAdapt++ = 1.f / ( 2.f * a + 1.f );
213 0 : *lpFiltAdapt = -a / ( 2.f * a + 1.f );
214 0 : break;
215 0 : default:
216 0 : IVAS_ERROR( IVAS_ERR_INTERNAL, "PLC: Filter type neither lowpass nor highpass." );
217 0 : break;
218 : }
219 :
220 0 : return;
221 : }
222 :
223 : /*------------------------------------------------------------------
224 : * highPassFiltering()
225 : *
226 : * PLC: [ACELP: general]
227 : * PLC: high pass filtering
228 : *-----------------------------------------------------------------*/
229 :
230 9159 : void highPassFiltering(
231 : const int16_t last_good, /* i : last classification type */
232 : const int16_t L_buffer, /* i : buffer length */
233 : float exc2[], /* i/o: unvoiced excitation before the high pass filtering */
234 : const float hp_filt[], /* i : high pass filter coefficients */
235 : const int16_t l_fir_fer /* i : high pass filter length */
236 : )
237 : {
238 : int16_t i;
239 :
240 9159 : if ( last_good > UNVOICED_TRANSITION )
241 : {
242 10411668 : for ( i = 0; i < L_buffer; i++ )
243 : {
244 10402509 : exc2[i] = dotp( &exc2[i], hp_filt, l_fir_fer );
245 : }
246 : }
247 :
248 9159 : return;
249 : }
250 :
251 : /*---------------------------------------------------------------------
252 : * GetPLCModeDecision()
253 : *
254 : * PLC: [Common: mode decision]
255 : * PLC: Decide which Concealment to use. Update pitch lags if needed
256 : *--------------------------------------------------------------------*/
257 :
258 50778 : int16_t GetPLCModeDecision(
259 : Decoder_State *st /* i/o: decoder memory state pointer */
260 : )
261 : {
262 : int16_t core;
263 50778 : int16_t numIndices = 0;
264 50778 : TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
265 :
266 50778 : if ( st->flagGuidedAcelp == 1 )
267 : {
268 : /* update mem_lag according to info available on future frame */
269 0 : st->old_pitch_buf[2 * st->nb_subfr] = (float) st->guidedT0;
270 0 : st->old_pitch_buf[2 * st->nb_subfr + 1] = (float) st->guidedT0;
271 0 : st->mem_pitch_gain[0] = st->mem_pitch_gain[1] = 1.f;
272 : }
273 50778 : if ( ( st->last_core > ACELP_CORE && hTcxDec->tcxltp_last_gain_unmodified != 0 ) || ( st->flagGuidedAcelp == 1 ) )
274 : {
275 : /* no updates needed here, because already updated in last good frame */
276 38283 : st->plc_use_future_lag = 1;
277 : }
278 : else
279 : {
280 12495 : st->plc_use_future_lag = 0;
281 : }
282 50778 : if ( st->last_core == -1 )
283 : {
284 0 : if ( st->Opt_AMR_WB )
285 : {
286 0 : core = ACELP_CORE;
287 : }
288 : else
289 : {
290 0 : core = TCX_20_CORE;
291 : }
292 0 : st->last_core = ACELP_CORE;
293 0 : st->tonal_mdct_plc_active = 0;
294 : }
295 : else
296 : {
297 : #ifndef DEBUG_NO_TD_TCX_PLC
298 50778 : core = ACELP_CORE;
299 : #else
300 : core = st->last_core;
301 : #endif
302 50778 : if ( st->nbLostCmpt > 1 )
303 : {
304 21135 : core = st->last_core_bfi;
305 : }
306 :
307 : /* no FD TCX PLC after a TCX transition frame: the appropriate framing is not implemented */
308 50778 : if ( st->nbLostCmpt == 1 )
309 : {
310 29643 : st->tonal_mdct_plc_active = 0;
311 29643 : if ( !( st->rf_flag && st->use_partial_copy && ( st->rf_frame_type == RF_TCXTD1 || st->rf_frame_type == RF_TCXTD2 ) ) )
312 : {
313 29643 : if ( st->hTonalMDCTConc != NULL && st->last_core == TCX_20_CORE && st->second_last_core == TCX_20_CORE && ( ( st->old_fpitch <= 0.5f * st->L_frame ) || ( hTcxDec->tcxltp_last_gain_unmodified <= 0.4f ) )
314 : /* it is fine to call the detection even if no ltp information
315 : is available, meaning that st->old_fpitch ==
316 : st->tcxltp_second_last_pitch == st->L_frame */
317 25950 : && ( st->old_fpitch == hTcxDec->tcxltp_second_last_pitch ) && !st->last_tns_active && !st->second_last_tns_active )
318 : {
319 :
320 7215 : TonalMDCTConceal_Detect( st->hTonalMDCTConc, ( hTcxDec->tcxltp_last_gain_unmodified > 0 ) ? st->old_fpitch : 0, &numIndices,
321 7215 : ( st->element_mode == IVAS_CPE_MDCT ? &( st->hTcxCfg->psychParamsTCX20 ) : st->hTcxCfg->psychParamsCurrent ) );
322 :
323 7215 : if ( ( numIndices > 10 ) || ( ( numIndices > 5 ) && ( fabs( hTcxDec->tcxltp_third_last_pitch - hTcxDec->tcxltp_second_last_pitch ) < 0.5f ) ) || ( ( numIndices > 0 ) && ( ( st->last_good <= UNVOICED_TRANSITION ) || ( hTcxDec->tcxltp_last_gain_unmodified <= 0.4f ) ) && ( fabs( hTcxDec->tcxltp_third_last_pitch - hTcxDec->tcxltp_second_last_pitch ) < 0.5f ) ) )
324 : {
325 1359 : core = TCX_20_CORE;
326 : #ifndef DEBUG_NO_TONAL_PLC
327 1359 : st->tonal_mdct_plc_active = 1;
328 : #endif
329 : }
330 5856 : else if ( st->last_good <= UNVOICED_TRANSITION || hTcxDec->tcxltp_last_gain_unmodified <= 0.4f )
331 : {
332 5277 : core = TCX_20_CORE;
333 : }
334 : }
335 : #ifndef DEBUG_FORCE_TD_TCX_CONCEALMENT
336 22428 : else if ( st->last_core != ACELP_CORE )
337 : {
338 22428 : if ( st->last_good <= UNVOICED_TRANSITION || hTcxDec->tcxltp_last_gain_unmodified <= 0.4f )
339 : {
340 13596 : core = st->last_core;
341 : }
342 : }
343 : #endif
344 : }
345 : }
346 : }
347 :
348 50778 : return core;
349 : }
|