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 : #define _USE_MATH_DEFINES
38 :
39 : #include <assert.h>
40 : #include <stdint.h>
41 : #include "options.h"
42 : #ifdef DEBUGGING
43 : #include "debug.h"
44 : #endif
45 : #include <math.h>
46 : #include "prot.h"
47 : #include "ivas_prot.h"
48 : #include "wmc_auto.h"
49 :
50 :
51 : /*******************************************************/
52 : /*-------------- public functions -------------------- */
53 : /*******************************************************/
54 :
55 754173 : ivas_error TonalMDCTConceal_Init(
56 : TonalMDCTConcealPtr hTonalMDCTConc,
57 : const uint16_t nSamples,
58 : const uint16_t nSamplesCore,
59 : const uint16_t nScaleFactors,
60 : TCX_CONFIG_HANDLE hTcxCfg )
61 : {
62 754173 : if ( nSamples > L_FRAME_MAX || nScaleFactors > FDNS_NPTS )
63 : {
64 0 : assert( nSamples <= L_FRAME_MAX );
65 0 : assert( nScaleFactors <= FDNS_NPTS );
66 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "TonalMDCT FEC: Number of samples larger than max. block size\n" ) );
67 : }
68 754173 : assert( ( hTonalMDCTConc->nScaleFactors == nScaleFactors ) || ( hTonalMDCTConc->nSamples != nSamples ) ); /* If nSamples doesn't change then also nScaleFactors must stay the same */
69 :
70 754173 : hTonalMDCTConc->tcx_cfg = hTcxCfg;
71 754173 : hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
72 754173 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
73 754173 : hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
74 754173 : hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
75 754173 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
76 754173 : hTonalMDCTConc->lastBlockData.blockIsValid = 0;
77 754173 : hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
78 754173 : hTonalMDCTConc->nSamples = 0;
79 754173 : hTonalMDCTConc->nScaleFactors = 0;
80 :
81 754173 : hTonalMDCTConc->lastBlockData.blockIsConcealed = 0;
82 754173 : hTonalMDCTConc->secondLastBlockData.blockIsConcealed = 0;
83 754173 : hTonalMDCTConc->pTCI = (TonalComponentsInfo *) hTonalMDCTConc->timeDataBuffer;
84 :
85 754173 : hTonalMDCTConc->lastPitchLag = 0;
86 :
87 754173 : if ( hTonalMDCTConc->nSamples != nSamples )
88 : {
89 754173 : hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
90 754173 : hTonalMDCTConc->lastBlockData.blockIsValid = 0;
91 : }
92 754173 : hTonalMDCTConc->nSamples = nSamples;
93 754173 : hTonalMDCTConc->nSamplesCore = nSamplesCore;
94 754173 : hTonalMDCTConc->nScaleFactors = nScaleFactors;
95 :
96 754173 : set_zero( hTonalMDCTConc->scaleFactorsBackground, FDNS_NPTS );
97 754173 : hTonalMDCTConc->scf_fadeout = 1.0f;
98 754173 : PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k, 64, 1, 1, &hTonalMDCTConc->psychParamsTCX20 );
99 754173 : PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k / 2, 64, 0, 1, &hTonalMDCTConc->psychParamsTCX10 );
100 754173 : hTonalMDCTConc->psychParams = NULL;
101 :
102 754173 : hTonalMDCTConc->last_block_nrg = 0.0f;
103 754173 : hTonalMDCTConc->curr_noise_nrg = 0.0f;
104 754173 : hTonalMDCTConc->faded_signal_nrg = 0.0f;
105 :
106 : /* Offset the pointer to the end of buffer, so that pTCI is not destroyed when
107 : new time samples are stored in lastPcmOut */
108 : /* just the second half of the second last pcm output is needed */
109 754173 : hTonalMDCTConc->secondLastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - ( 3 * min( L_FRAME_MAX, nSamples ) ) / 2];
110 754173 : hTonalMDCTConc->lastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - min( L_FRAME_MAX, nSamples )];
111 :
112 : /* If the second last frame was lost and concealed with tonal PLC, we
113 : reuse saved TonalComponentsInfo and don't update pcm buffers */
114 754173 : assert( sizeof( *hTonalMDCTConc->pTCI ) <= ( hTonalMDCTConc->lastPcmOut - hTonalMDCTConc->timeDataBuffer ) * sizeof( hTonalMDCTConc->timeDataBuffer[0] ) );
115 :
116 754173 : return IVAS_ERR_OK;
117 : }
118 :
119 :
120 27406495 : void TonalMDCTConceal_SaveFreqSignal(
121 : TonalMDCTConcealPtr hTonalMDCTConc,
122 : const float *mdctSpectrum,
123 : const uint16_t nNewSamples,
124 : const uint16_t nNewSamplesCore,
125 : const float *scaleFactors,
126 : const int16_t infoIGFStartLine )
127 : {
128 : float *temp;
129 : uint16_t nOldSamples;
130 :
131 27406495 : assert( nNewSamples > 0 && nNewSamples <= 2 * L_FRAME_MAX );
132 :
133 : /* Avoid overwriting hTonalMDCTConc->secondLastPowerSpectrum stored in spectralData,
134 : because it is needed if the second last and the current frame are lost
135 : and concealed using the Tonal MDCT PLC */
136 27406495 : if ( !hTonalMDCTConc->lastBlockData.tonalConcealmentActive || ( hTonalMDCTConc->lastBlockData.nSamples != nNewSamples ) )
137 : {
138 27362040 : if ( nNewSamples <= L_FRAME_MAX )
139 : {
140 : /* Shift the buffers */
141 27247207 : temp = hTonalMDCTConc->secondLastBlockData.spectralData; /* Save the pointer */
142 27247207 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->lastBlockData.spectralData;
143 27247207 : hTonalMDCTConc->lastBlockData.spectralData = temp;
144 27247207 : temp = hTonalMDCTConc->secondLastBlockData.scaleFactors;
145 27247207 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->lastBlockData.scaleFactors;
146 27247207 : hTonalMDCTConc->lastBlockData.scaleFactors = temp;
147 : }
148 : else
149 : {
150 : /* Order the buffers so that even transition frame can fit in if written into the first buffer */
151 114833 : hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
152 114833 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
153 114833 : hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
154 114833 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
155 : }
156 27362040 : nOldSamples = hTonalMDCTConc->lastBlockData.nSamples;
157 27362040 : hTonalMDCTConc->lastBlockData.nSamples = nNewSamples;
158 27362040 : hTonalMDCTConc->secondLastBlockData.nSamples = nOldSamples;
159 27362040 : nOldSamples = hTonalMDCTConc->lastBlockData.nSamplesCore;
160 27362040 : hTonalMDCTConc->lastBlockData.nSamplesCore = nNewSamplesCore;
161 27362040 : hTonalMDCTConc->secondLastBlockData.nSamplesCore = nOldSamples;
162 : }
163 :
164 27406495 : if ( ( nNewSamples > 0 ) && ( nNewSamples <= 2 * L_FRAME_MAX ) )
165 : {
166 : /* Store new data */
167 : int16_t i;
168 :
169 27406495 : hTonalMDCTConc->last_block_nrg = 0.0f;
170 12349911371 : for ( i = 0; i < infoIGFStartLine; i++ )
171 : {
172 12322504876 : hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i];
173 12322504876 : hTonalMDCTConc->last_block_nrg += mdctSpectrum[i] * mdctSpectrum[i];
174 : }
175 8037030859 : for ( ; i < nNewSamples; i++ )
176 : {
177 8009624364 : hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i];
178 : }
179 :
180 27406495 : mvr2r( scaleFactors, hTonalMDCTConc->lastBlockData.scaleFactors, hTonalMDCTConc->nScaleFactors );
181 : }
182 :
183 27406495 : return;
184 : }
185 :
186 :
187 32647776 : void TonalMDCTConceal_UpdateState(
188 : TonalMDCTConcealPtr hTonalMDCTConc,
189 : const int16_t nNewSamples,
190 : const float pitchLag,
191 : const int16_t badBlock,
192 : const int16_t tonalConcealmentActive )
193 : {
194 : int16_t newBlockIsValid;
195 :
196 32647776 : assert( !( !badBlock && tonalConcealmentActive ) );
197 :
198 32647776 : if ( badBlock )
199 : {
200 2226073 : newBlockIsValid = hTonalMDCTConc->lastBlockData.blockIsValid;
201 : }
202 : else
203 : {
204 30421703 : newBlockIsValid = ( nNewSamples <= 2 * L_FRAME_MAX ) && ( nNewSamples > 0 );
205 : }
206 :
207 : /* Shift old state */
208 32647776 : hTonalMDCTConc->secondLastBlockData.blockIsConcealed = hTonalMDCTConc->lastBlockData.blockIsConcealed;
209 32647776 : hTonalMDCTConc->secondLastBlockData.blockIsValid = hTonalMDCTConc->lastBlockData.blockIsValid;
210 32647776 : hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive = hTonalMDCTConc->lastBlockData.tonalConcealmentActive;
211 :
212 : /* Store new state */
213 32647776 : hTonalMDCTConc->lastBlockData.blockIsConcealed = badBlock;
214 32647776 : hTonalMDCTConc->lastBlockData.blockIsValid = newBlockIsValid;
215 32647776 : hTonalMDCTConc->lastBlockData.tonalConcealmentActive = tonalConcealmentActive;
216 32647776 : hTonalMDCTConc->lastPitchLag = pitchLag;
217 :
218 32647776 : return;
219 : }
220 :
221 :
222 171929 : static void FindPhases(
223 : const TonalMDCTConcealPtr hTonalMDCTConc,
224 : const float secondLastMDCT[],
225 : const float secondLastMDST[] )
226 : {
227 : int16_t i;
228 : int16_t l;
229 : float *pCurrentPhase;
230 :
231 171929 : pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
232 : /* for each index/index group */
233 468389 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
234 : {
235 2353833 : for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
236 : {
237 2057373 : *pCurrentPhase++ = (float) atan2( secondLastMDST[l], secondLastMDCT[l] );
238 : }
239 : }
240 :
241 171929 : return;
242 : }
243 :
244 : #define CNST_bandwidth 7.0f
245 : #define CNST_m (float) cos( EVS_PI / CNST_bandwidth )
246 : #define CNST_s (float) cos( ( 3 * EVS_PI ) / CNST_bandwidth )
247 : #define CNST_n (float) sin( EVS_PI / CNST_bandwidth )
248 : #define CNST_j (float) sin( ( 3 * EVS_PI ) / CNST_bandwidth )
249 : #define CNST_G (float) ( 1.0 / ( 2 * 1.36 ) )
250 : #define CNST_maxRatio 44.8f /* Maximum ratio |ODFT[k-1]|/|ODFT[k+1]| is 16.5 dB, that is maximum ratio (for fractional = 0) is (cos(EVS_PI/bandwidth)/cos(3PI/bandwidth))^1.36 */
251 :
252 :
253 171929 : static void FindPhaseDifferences(
254 : TonalMDCTConcealPtr const hTonalMDCTConc,
255 : float powerSpectrum[] )
256 : {
257 : int16_t i, k;
258 : float odft_left, odft_right;
259 : float *phaseDiff;
260 : float fractional;
261 : float Q, a;
262 :
263 171929 : phaseDiff = hTonalMDCTConc->pTCI->phaseDiff;
264 468389 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
265 : {
266 296460 : k = hTonalMDCTConc->pTCI->indexOfTonalPeak[i];
267 296460 : odft_left = powerSpectrum[k - 1];
268 296460 : odft_right = powerSpectrum[k + 1];
269 296460 : if ( odft_left >= CNST_maxRatio * odft_right )
270 : {
271 2070 : a = (float) tan( 0.0f * EVS_PI / CNST_bandwidth );
272 : }
273 : else
274 : {
275 294390 : if ( odft_right >= CNST_maxRatio * odft_left )
276 : {
277 2595 : a = (float) tan( 2.0f * EVS_PI / CNST_bandwidth );
278 : }
279 : else
280 : {
281 291795 : Q = (float) pow( odft_left / odft_right, CNST_G );
282 291795 : a = ( CNST_m - Q * CNST_s ) / ( CNST_n + Q * CNST_j );
283 : }
284 : }
285 296460 : fractional = (float) atan( a ) * ( CNST_bandwidth / 2.0f );
286 296460 : assert( ( fractional >= 0 ) && ( fractional <= EVS_PI + 1.192092896e-07F ) );
287 296460 : phaseDiff[i] = fractional + EVS_PI * ( k % 4 );
288 : }
289 :
290 171929 : return;
291 : }
292 :
293 171929 : static void CalcPowerSpec(
294 : const float *mdctSpec,
295 : const float *mdstSpec,
296 : const int16_t nSamples,
297 : float floorPowerSpectrum,
298 : float *powerSpec )
299 : {
300 : int16_t k;
301 : float x;
302 :
303 87204463 : for ( k = 1; k <= nSamples - 2; k++ )
304 : {
305 87032534 : x = mdctSpec[k] * mdctSpec[k] + mdstSpec[k] * mdstSpec[k];
306 87032534 : powerSpec[k] = max( floorPowerSpectrum, x );
307 : }
308 171929 : powerSpec[0] = 0.5f * powerSpec[1];
309 171929 : powerSpec[nSamples - 1] = 0.5f * powerSpec[nSamples - 2];
310 :
311 171929 : return;
312 : }
313 :
314 171929 : static void CalcPowerSpecAndDetectTonalComponents(
315 : const TonalMDCTConcealPtr hTonalMDCTConc,
316 : float secondLastMDST[],
317 : float secondLastMDCT[],
318 : const float pitchLag,
319 : const PsychoacousticParameters *psychParamsCurrent )
320 : {
321 : int16_t i, nSamples;
322 : float floorPowerSpectrum; /* Minimum significant value of a spectral line in the power spectrum */
323 : float powerSpectrum[L_FRAME_MAX]; /* 32 bits are required */
324 : float invScaleFactors[FDNS_NPTS];
325 : int16_t nBands;
326 :
327 171929 : nSamples = hTonalMDCTConc->nNonZeroSamples;
328 :
329 : /* It is taken into account that the MDCT is not normalized. */
330 171929 : floorPowerSpectrum = hTonalMDCTConc->nSamples * hTonalMDCTConc->nSamples / 400.0f;
331 171929 : CalcPowerSpec( secondLastMDCT, secondLastMDST, nSamples, floorPowerSpectrum, powerSpectrum );
332 :
333 : /* This setting to minimal level is required because the power spectrum is used in the threshold adaptation using the pitch up to hTonalMDCTConc->nSamples. */
334 171929 : set_f( powerSpectrum + nSamples, floorPowerSpectrum, hTonalMDCTConc->nSamples - nSamples );
335 : /* this setting to zero is needed since the FDNS needs to be called
336 : with hTonalMDCTConc->nSamplesCore; it relevant only for nb; it has no effect
337 : to the output, but memory checker may complain otherwise due to the
338 : usage of uninitialized values */
339 :
340 171929 : if ( hTonalMDCTConc->nSamplesCore > hTonalMDCTConc->nSamples )
341 : {
342 983 : set_zero( powerSpectrum + hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamplesCore - hTonalMDCTConc->nSamples );
343 : }
344 :
345 171929 : DetectTonalComponents( hTonalMDCTConc->pTCI->indexOfTonalPeak, hTonalMDCTConc->pTCI->lowerIndex, hTonalMDCTConc->pTCI->upperIndex, &hTonalMDCTConc->pTCI->numIndexes, hTonalMDCTConc->lastPitchLag, pitchLag,
346 171929 : hTonalMDCTConc->lastBlockData.spectralData, hTonalMDCTConc->lastBlockData.scaleFactors, powerSpectrum, nSamples, hTonalMDCTConc->nSamplesCore, floorPowerSpectrum, psychParamsCurrent );
347 :
348 171929 : FindPhases( hTonalMDCTConc, secondLastMDCT, secondLastMDST );
349 :
350 171929 : FindPhaseDifferences( hTonalMDCTConc, powerSpectrum );
351 :
352 171929 : if ( hTonalMDCTConc->pTCI->numIndexes > 0 )
353 : {
354 68179 : hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
355 :
356 33990103 : for ( i = 0; i < nSamples; i++ )
357 : {
358 33921924 : powerSpectrum[i] = (float) sqrt( powerSpectrum[i] );
359 : }
360 :
361 4431635 : for ( i = 0; i < hTonalMDCTConc->nScaleFactors; i++ )
362 : {
363 4363456 : invScaleFactors[i] = 1.0f / hTonalMDCTConc->secondLastBlockData.scaleFactors[i];
364 : }
365 :
366 68179 : if ( psychParamsCurrent == NULL )
367 : {
368 27585 : nBands = FDNS_NPTS;
369 27585 : mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, invScaleFactors, nBands );
370 : }
371 : else
372 : {
373 40594 : sns_shape_spectrum( powerSpectrum, psychParamsCurrent, invScaleFactors, hTonalMDCTConc->nSamplesCore );
374 40594 : nBands = psychParamsCurrent->nBands;
375 : }
376 :
377 68179 : v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, invScaleFactors[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples - hTonalMDCTConc->nSamplesCore );
378 68179 : mvr2r( powerSpectrum, hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamples ); /* 16 bits are now enough for storing the power spectrum */
379 : }
380 :
381 171929 : return;
382 : }
383 :
384 :
385 343858 : static void CalcMDXT(
386 : const TonalMDCTConcealPtr hTonalMDCTConc,
387 : const char type,
388 : const float *timeSignal,
389 : float *mdxtOutput )
390 : {
391 : float windowedTimeSignal[L_FRAME_PLUS + 2 * L_MDCT_OVLP_MAX];
392 : int16_t left_overlap, right_overlap;
393 : int16_t L_frame;
394 :
395 343858 : L_frame = hTonalMDCTConc->nSamples;
396 343858 : WindowSignal( hTonalMDCTConc->tcx_cfg, hTonalMDCTConc->tcx_cfg->tcx_offsetFB, FULL_OVERLAP, FULL_OVERLAP, &left_overlap, &right_overlap, timeSignal, &L_frame, windowedTimeSignal, 1, 1 );
397 :
398 343858 : if ( type == 'S' )
399 : {
400 171929 : TCX_MDST( windowedTimeSignal, mdxtOutput, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, EVS_MONO );
401 : }
402 : else
403 : {
404 171929 : TCX_MDCT( windowedTimeSignal, mdxtOutput, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, EVS_MONO );
405 : }
406 :
407 343858 : return;
408 : }
409 :
410 :
411 270508 : void TonalMDCTConceal_Detect(
412 : const TonalMDCTConcealPtr hTonalMDCTConc,
413 : const float pitchLag,
414 : int16_t *numIndices,
415 : const PsychoacousticParameters *psychParamsCurrent )
416 : {
417 : float secondLastMDST[L_FRAME_MAX]; /* 32 bits are required */
418 : float secondLastMDCT[L_FRAME_MAX]; /* 32 bits are required */
419 270508 : float *powerSpectrum = secondLastMDST;
420 : int16_t i, nSamples;
421 : int16_t nBands;
422 :
423 270508 : nSamples = hTonalMDCTConc->nSamples;
424 270508 : if ( hTonalMDCTConc->lastBlockData.blockIsValid && hTonalMDCTConc->secondLastBlockData.blockIsValid && ( hTonalMDCTConc->lastBlockData.nSamples == nSamples ) && ( hTonalMDCTConc->secondLastBlockData.nSamples == nSamples ) && ( !hTonalMDCTConc->secondLastBlockData.blockIsConcealed || hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive || ( pitchLag != 0 ) ) )
425 : {
426 : /* Safety if the second last frame was concealed and tonal concealment was inactive */
427 :
428 181358 : if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
429 : {
430 181358 : if ( !hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
431 : {
432 171929 : CalcMDXT( hTonalMDCTConc, 'S', hTonalMDCTConc->secondLastPcmOut, secondLastMDST );
433 171929 : CalcMDXT( hTonalMDCTConc, 'C', hTonalMDCTConc->secondLastPcmOut, secondLastMDCT );
434 171929 : hTonalMDCTConc->nNonZeroSamples = 0;
435 116127929 : for ( i = 0; i < hTonalMDCTConc->nSamples; i++ )
436 : {
437 115956000 : if ( hTonalMDCTConc->secondLastBlockData.spectralData[i] != 0 )
438 : {
439 78216639 : hTonalMDCTConc->nNonZeroSamples = i;
440 : }
441 : }
442 : /* 23 is the maximum length of the MA filter in getEnvelope */
443 171929 : hTonalMDCTConc->nNonZeroSamples = min( hTonalMDCTConc->nSamples, hTonalMDCTConc->nNonZeroSamples + 23 );
444 171929 : CalcPowerSpecAndDetectTonalComponents( hTonalMDCTConc, secondLastMDST, secondLastMDCT, pitchLag, psychParamsCurrent );
445 : }
446 : else
447 : {
448 : /* If the second last frame was also lost, it is expected that pastTimeSignal could hold a bit different signal (e.g. including fade-out) from the one stored in TonalMDCTConceal_SaveTimeSignal. */
449 : /* That is why we reuse the already stored information about the concealed spectrum in the second last frame */
450 9429 : nSamples = hTonalMDCTConc->nNonZeroSamples;
451 9429 : mvr2r( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples ); /* Convert from 16 bits to 32 bits */
452 9429 : if ( psychParamsCurrent == NULL )
453 : {
454 2451 : nBands = FDNS_NPTS;
455 2451 : mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors, nBands );
456 : }
457 : else
458 : {
459 6978 : sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore );
460 6978 : nBands = psychParamsCurrent->nBands;
461 : }
462 :
463 9429 : v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, nSamples - hTonalMDCTConc->nSamplesCore );
464 9429 : v_mult( powerSpectrum, powerSpectrum, powerSpectrum, nSamples );
465 :
466 9429 : RefineTonalComponents( hTonalMDCTConc->pTCI->indexOfTonalPeak, hTonalMDCTConc->pTCI->lowerIndex, hTonalMDCTConc->pTCI->upperIndex, hTonalMDCTConc->pTCI->phaseDiff,
467 9429 : hTonalMDCTConc->pTCI->phase_currentFramePredicted, &hTonalMDCTConc->pTCI->numIndexes, hTonalMDCTConc->lastPitchLag, pitchLag,
468 9429 : hTonalMDCTConc->lastBlockData.spectralData, hTonalMDCTConc->lastBlockData.scaleFactors, powerSpectrum,
469 9429 : nSamples, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples * hTonalMDCTConc->nSamples / 400.0f /* floorPowerSpectrum */, psychParamsCurrent );
470 : }
471 : }
472 : }
473 : else
474 : {
475 89150 : hTonalMDCTConc->pTCI->numIndexes = 0;
476 : }
477 :
478 270508 : *numIndices = hTonalMDCTConc->pTCI->numIndexes;
479 :
480 270508 : return;
481 : }
482 :
483 :
484 1587645 : void TonalMDCTConceal_InsertNoise(
485 : const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */
486 : float *mdctSpectrum, /*OUT*/
487 : const int16_t tonalConcealmentActive,
488 : int16_t *pSeed,
489 : const float tiltCompFactor,
490 : const float crossfadeGain,
491 : const float concealment_noise[L_FRAME48k],
492 : const float cngLevelBackgroundTrace_bfi,
493 : const int16_t crossOverFreq )
494 : {
495 : int16_t i, l;
496 : float x, y;
497 : Word16 rnd;
498 : float g, nrgNoiseInLastFrame, nrgWhiteNoise, tiltFactor, tilt;
499 : float last_block_nrg_correct;
500 :
501 1587645 : push_wmops( "InsertNoise" );
502 :
503 1587645 : g = 1.0f - crossfadeGain;
504 1587645 : if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
505 : {
506 584442 : rnd = 1977;
507 : }
508 : else
509 : {
510 1003203 : rnd = *pSeed;
511 : }
512 :
513 : /* based on what is done in tcx_noise_filling() */
514 : /* always initialize these to avoid compiler warnings */
515 1587645 : tiltFactor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / hTonalMDCTConc->lastBlockData.nSamples );
516 1587645 : tilt = 1.0f;
517 1587645 : nrgNoiseInLastFrame = 0.0f;
518 1587645 : nrgWhiteNoise = 0.0f;
519 1587645 : hTonalMDCTConc->faded_signal_nrg = 0.0f;
520 1587645 : last_block_nrg_correct = 0.0f;
521 :
522 1587645 : if ( !hTonalMDCTConc->lastBlockData.blockIsValid )
523 : {
524 : /* may just become active if the very first frame is lost */
525 0 : set_f( mdctSpectrum, 0.0f, hTonalMDCTConc->nSamples );
526 : }
527 1587645 : else if ( concealment_noise != NULL )
528 : {
529 419474 : if ( !tonalConcealmentActive )
530 : {
531 : /* if fadeout has not started yet, only apply sign scrambling */
532 385972 : if ( crossfadeGain == 1.0f )
533 : {
534 59788787 : for ( i = 0; i < crossOverFreq; i++ )
535 : {
536 59636172 : if ( concealment_noise[i] > 0 )
537 : {
538 31079313 : mdctSpectrum[i] = hTonalMDCTConc->lastBlockData.spectralData[i];
539 : }
540 : else
541 : {
542 28556859 : mdctSpectrum[i] = -hTonalMDCTConc->lastBlockData.spectralData[i];
543 : }
544 : }
545 :
546 37723083 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
547 : {
548 37570468 : mdctSpectrum[l] = 0.0f;
549 : }
550 : }
551 : /* actual fadeout is done in this case */
552 : else
553 : {
554 233357 : g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg );
555 :
556 91451477 : for ( i = 0; i < crossOverFreq; i++ )
557 : {
558 91218120 : x = hTonalMDCTConc->lastBlockData.spectralData[i];
559 91218120 : y = concealment_noise[i];
560 :
561 91218120 : if ( y > 0 )
562 : {
563 11068561 : mdctSpectrum[i] = g * y + crossfadeGain * x;
564 : }
565 : else
566 : {
567 80149559 : mdctSpectrum[i] = g * y - crossfadeGain * x;
568 : }
569 :
570 91218120 : hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[i] * mdctSpectrum[i];
571 : }
572 56888917 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
573 : {
574 56655560 : mdctSpectrum[l] = 0.0f;
575 : }
576 : }
577 : }
578 : else
579 : {
580 33502 : assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
581 :
582 : /* initialize bins of tonal components with zero: basically not
583 : necessary, but currently the whole spectrum is rescaled in
584 : mdct_noiseShaping() and then there would be a processing of
585 : uninitialized values */
586 186296 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
587 : {
588 1220104 : for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
589 : {
590 1067310 : mdctSpectrum[l] = 0;
591 1067310 : if ( l < crossOverFreq )
592 : {
593 1030379 : last_block_nrg_correct += hTonalMDCTConc->lastBlockData.spectralData[l] * hTonalMDCTConc->lastBlockData.spectralData[l];
594 1030379 : hTonalMDCTConc->curr_noise_nrg -= concealment_noise[l] * concealment_noise[l];
595 : }
596 : }
597 : }
598 :
599 : /* if fadeout has not started yet, only apply sign scrambling */
600 33502 : if ( crossfadeGain == 1.0f )
601 : {
602 947745 : for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
603 : {
604 935267 : if ( concealment_noise[l] > 0 )
605 : {
606 464477 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
607 : }
608 : else
609 : {
610 470790 : mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l];
611 : }
612 : }
613 56300 : for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
614 : {
615 1030241 : for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
616 : {
617 986419 : if ( concealment_noise[l] > 0 )
618 : {
619 515989 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
620 : }
621 : else
622 : {
623 470430 : mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l];
624 : }
625 : }
626 : }
627 :
628 2530567 : for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
629 : {
630 2518089 : if ( concealment_noise[l] > 0 )
631 : {
632 1333085 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
633 : }
634 : else
635 : {
636 1185004 : mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l];
637 : }
638 : }
639 :
640 3215046 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
641 : {
642 3202568 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
643 : }
644 : }
645 : /* actual fadeout is done in this case */
646 : else
647 : {
648 21024 : g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg );
649 :
650 2111761 : for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
651 : {
652 2090737 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
653 2090737 : y = concealment_noise[l];
654 :
655 2090737 : if ( y > 0 )
656 : {
657 384291 : mdctSpectrum[l] = g * y + crossfadeGain * x;
658 : }
659 : else
660 : {
661 1706446 : mdctSpectrum[l] = g * y - crossfadeGain * x;
662 : }
663 2090737 : hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l];
664 : }
665 96494 : for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
666 : {
667 1842842 : for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
668 : {
669 1767372 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
670 1767372 : y = concealment_noise[l];
671 :
672 1767372 : if ( y > 0 )
673 : {
674 453475 : mdctSpectrum[l] = g * y + crossfadeGain * x;
675 : }
676 : else
677 : {
678 1313897 : mdctSpectrum[l] = g * y - crossfadeGain * x;
679 : }
680 1767372 : hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l];
681 : }
682 : }
683 :
684 3568695 : for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
685 : {
686 3547671 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
687 3547671 : y = concealment_noise[l];
688 :
689 3547671 : if ( y > 0 )
690 : {
691 768764 : mdctSpectrum[l] = g * y + crossfadeGain * x;
692 : }
693 : else
694 : {
695 2778907 : mdctSpectrum[l] = g * y - crossfadeGain * x;
696 : }
697 3547671 : hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l];
698 : }
699 :
700 5274760 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
701 : {
702 5253736 : mdctSpectrum[l] = 0.0f;
703 : }
704 : }
705 : }
706 :
707 419474 : if ( hTonalMDCTConc->faded_signal_nrg > 0.0f && hTonalMDCTConc->curr_noise_nrg > MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG )
708 : {
709 : float nrg_corr_factor;
710 :
711 72433 : nrg_corr_factor = sqrtf( ( hTonalMDCTConc->last_block_nrg - last_block_nrg_correct ) / hTonalMDCTConc->faded_signal_nrg );
712 72433 : v_multc( mdctSpectrum, nrg_corr_factor, mdctSpectrum, crossOverFreq );
713 : }
714 : }
715 : else
716 : {
717 1168171 : if ( !tonalConcealmentActive )
718 : {
719 487668828 : for ( i = 0; i < crossOverFreq; i++ )
720 : {
721 486604346 : x = hTonalMDCTConc->lastBlockData.spectralData[i];
722 486604346 : nrgNoiseInLastFrame += x * x;
723 486604346 : rnd = own_random( &rnd );
724 486604346 : mdctSpectrum[i] = tilt * rnd;
725 486604346 : tilt *= tiltFactor;
726 486604346 : nrgWhiteNoise += mdctSpectrum[i] * mdctSpectrum[i];
727 : }
728 1064482 : if ( nrgWhiteNoise > 0 )
729 : {
730 1064482 : g *= (float) sqrt( nrgNoiseInLastFrame / nrgWhiteNoise );
731 : }
732 487668828 : for ( i = 0; i < crossOverFreq; i++ )
733 : {
734 486604346 : x = hTonalMDCTConc->lastBlockData.spectralData[i];
735 486604346 : y = mdctSpectrum[i];
736 :
737 486604346 : if ( y > 0 )
738 : {
739 241720022 : mdctSpectrum[i] = g * y + crossfadeGain * x;
740 : }
741 : else
742 : {
743 244884324 : mdctSpectrum[i] = g * y - crossfadeGain * x;
744 : }
745 : }
746 :
747 207746856 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
748 : {
749 206682374 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
750 : }
751 : }
752 : else
753 : {
754 103689 : assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
755 8730060 : for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
756 : {
757 8626371 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
758 8626371 : rnd = own_random( &rnd );
759 8626371 : mdctSpectrum[l] = tilt * rnd;
760 8626371 : tilt *= tiltFactor;
761 8626371 : nrgNoiseInLastFrame += x * x;
762 8626371 : nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l];
763 : }
764 :
765 465253 : for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
766 : {
767 361564 : tilt *= (float) pow( tiltFactor, hTonalMDCTConc->pTCI->upperIndex[i - 1] - hTonalMDCTConc->pTCI->lowerIndex[i - 1] + 1 );
768 7822086 : for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
769 : {
770 7460522 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
771 7460522 : rnd = own_random( &rnd );
772 7460522 : mdctSpectrum[l] = tilt * rnd;
773 7460522 : tilt *= tiltFactor;
774 7460522 : nrgNoiseInLastFrame += x * x;
775 7460522 : nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l];
776 : }
777 : }
778 103689 : tilt *= (float) pow( tiltFactor, hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] - hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1 );
779 :
780 22751676 : for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
781 : {
782 22647987 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
783 22647987 : rnd = own_random( &rnd );
784 22647987 : mdctSpectrum[l] = tilt * rnd;
785 22647987 : tilt *= tiltFactor;
786 22647987 : nrgNoiseInLastFrame += x * x;
787 22647987 : nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l];
788 : }
789 103689 : if ( nrgWhiteNoise > 0 )
790 : {
791 103689 : g *= (float) sqrt( nrgNoiseInLastFrame / nrgWhiteNoise );
792 : }
793 8730060 : for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
794 : {
795 8626371 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
796 8626371 : y = mdctSpectrum[l];
797 :
798 8626371 : if ( y > 0 )
799 : {
800 4380692 : mdctSpectrum[l] = g * y + crossfadeGain * x;
801 : }
802 : else
803 : {
804 4245679 : mdctSpectrum[l] = g * y - crossfadeGain * x;
805 : }
806 : }
807 465253 : for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
808 : {
809 7822086 : for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
810 : {
811 7460522 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
812 7460522 : y = mdctSpectrum[l];
813 :
814 7460522 : if ( y > 0 )
815 : {
816 3802549 : mdctSpectrum[l] = g * y + crossfadeGain * x;
817 : }
818 : else
819 : {
820 3657973 : mdctSpectrum[l] = g * y - crossfadeGain * x;
821 : }
822 : }
823 : }
824 : /* initialize bins of tonal components with zero: basically not
825 : necessary, but currently the whole spectrum is rescaled in
826 : mdct_noiseShaping() and then there would be a processing of
827 : uninitialized values */
828 568942 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
829 : {
830 3665430 : for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
831 : {
832 3200177 : mdctSpectrum[l] = 0;
833 : }
834 : }
835 22751676 : for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
836 : {
837 22647987 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
838 22647987 : y = mdctSpectrum[l];
839 :
840 22647987 : if ( y > 0 )
841 : {
842 11157859 : mdctSpectrum[l] = g * y + crossfadeGain * x;
843 : }
844 : else
845 : {
846 11490128 : mdctSpectrum[l] = g * y - crossfadeGain * x;
847 : }
848 : }
849 :
850 23790705 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
851 : {
852 23687016 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
853 : }
854 : }
855 : }
856 :
857 1587645 : *pSeed = rnd;
858 :
859 1587645 : pop_wmops();
860 :
861 1587645 : return;
862 : }
863 :
864 :
865 137191 : void TonalMDCTConceal_Apply(
866 : TonalMDCTConcealPtr hTonalMDCTConc, /*IN */
867 : float *mdctSpectrum, /*OUT */
868 : const PsychoacousticParameters *psychParamsCurrent )
869 : {
870 : int16_t i, l;
871 : float *phaseDiff, *pCurrentPhase;
872 : float phaseToAdd;
873 : float powerSpectrum[L_FRAME_MAX];
874 : int16_t nSamples;
875 : int16_t nBands;
876 :
877 137191 : if ( hTonalMDCTConc->lastBlockData.blockIsValid & hTonalMDCTConc->secondLastBlockData.blockIsValid )
878 : {
879 137191 : assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
880 :
881 137191 : nSamples = hTonalMDCTConc->nNonZeroSamples;
882 137191 : assert( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] < nSamples );
883 137191 : mvr2r( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples ); /* Convert from 16 bits to 32 bits */
884 137191 : if ( psychParamsCurrent == NULL )
885 : {
886 50484 : nBands = FDNS_NPTS;
887 50484 : mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors, nBands );
888 : }
889 : else
890 : {
891 86707 : sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore );
892 86707 : nBands = psychParamsCurrent->nBands;
893 : }
894 :
895 137191 : v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, nSamples - hTonalMDCTConc->nSamplesCore );
896 :
897 137191 : phaseDiff = hTonalMDCTConc->pTCI->phaseDiff; /* if multiple frame loss occurs use the phase from the last frame and continue rotating */
898 137191 : pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
899 :
900 137191 : if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
901 : {
902 45677 : if ( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
903 : {
904 3589 : hTonalMDCTConc->nFramesLost += 1;
905 : }
906 : else
907 : {
908 42088 : hTonalMDCTConc->nFramesLost = 1.5;
909 : }
910 : }
911 :
912 : /* for each index group */
913 755238 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
914 : {
915 618047 : phaseToAdd = hTonalMDCTConc->nFramesLost * phaseDiff[i];
916 :
917 : /* Move phaseToAdd to range -EVS_PI..EVS_PI */
918 8266772 : while ( phaseToAdd > EVS_PI )
919 : {
920 7648725 : phaseToAdd -= PI2;
921 : }
922 :
923 618047 : while ( phaseToAdd < -EVS_PI )
924 : {
925 : /* should never occur in flt - kept for safety reasons */
926 0 : phaseToAdd += PI2;
927 : }
928 :
929 4885534 : for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
930 : {
931 4267487 : const float currentPhase = ( *pCurrentPhase++ ) + phaseToAdd; /* *pCurrentPhase and phaseToAdd are in range -EVS_PI..EVS_PI */
932 4267487 : mdctSpectrum[l] = (float) cos( currentPhase ) * powerSpectrum[l];
933 : }
934 : }
935 : }
936 :
937 137191 : hTonalMDCTConc->nFramesLost++;
938 :
939 137191 : return;
940 : }
941 :
942 :
943 29731485 : void TonalMDCTConceal_SaveTimeSignal(
944 : TonalMDCTConcealPtr hTonalMDCTConc,
945 : float *timeSignal,
946 : const int16_t nNewSamples )
947 : {
948 29731485 : if ( nNewSamples == hTonalMDCTConc->nSamples )
949 : {
950 29136943 : assert( nNewSamples <= L_FRAME_MAX );
951 :
952 29136943 : if ( !hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
953 : {
954 29092022 : mvr2r( hTonalMDCTConc->lastPcmOut + hTonalMDCTConc->nSamples / 2, hTonalMDCTConc->secondLastPcmOut, hTonalMDCTConc->nSamples / 2 );
955 : }
956 :
957 29136943 : mvr2r( timeSignal, hTonalMDCTConc->lastPcmOut, hTonalMDCTConc->nSamples );
958 : }
959 :
960 29731485 : return;
961 : }
962 :
963 419474 : void TonalMdctConceal_create_concealment_noise(
964 : float concealment_noise[L_FRAME48k],
965 : CPE_DEC_HANDLE hCPE,
966 : const int16_t L_frameTCX,
967 : const int16_t L_frame,
968 : const int16_t idchan,
969 : const int16_t subframe_idx,
970 : const int16_t core,
971 : const float crossfade_gain,
972 : const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode )
973 : {
974 : STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct;
975 : TonalMDCTConcealPtr hTonalMDCTConc;
976 : Decoder_State *st;
977 : HANDLE_FD_CNG_COM hFdCngCom;
978 : int16_t *rnd_c, *rnd;
979 : int16_t crossOverFreq, i, save_rnd_c, max_noise_line;
980 : float c, c_inv;
981 : float noise_shape_buffer[L_FRAME48k];
982 : int16_t inc, start_idx, stop_idx;
983 : float *cngNoiseLevelPtr;
984 : float last_scf;
985 :
986 419474 : push_wmops( "create_conc_noise" );
987 :
988 419474 : hStereoMdct = hCPE->hStereoMdct;
989 419474 : st = hCPE->hCoreCoder[idchan];
990 419474 : hTonalMDCTConc = st->hTonalMDCTConc;
991 419474 : hFdCngCom = st->hFdCngDec->hFdCngCom;
992 419474 : rnd = &hStereoMdct->noise_seeds_channels[idchan];
993 419474 : rnd_c = &hStereoMdct->noise_seed_common;
994 :
995 : /* determine start bin for IGF */
996 419474 : if ( st->igf == 0 )
997 : {
998 168165 : if ( st->narrowBand == 0 )
999 : {
1000 : /* minimum needed for output with sampling rates lower then the
1001 : nominal sampling rate */
1002 168165 : crossOverFreq = min( L_frameTCX, L_frame );
1003 : }
1004 : else
1005 : {
1006 0 : crossOverFreq = L_frameTCX;
1007 : }
1008 : }
1009 : else
1010 : {
1011 251309 : crossOverFreq = min( st->hIGFDec->infoIGFStartLine, L_frameTCX );
1012 : }
1013 :
1014 : /* for tonal mdct concealment with tonal components above the crossover frequency, conditionally raise the frequency index until which noise is generated */
1015 419474 : max_noise_line = crossOverFreq;
1016 419474 : if ( st->tonal_mdct_plc_active )
1017 : {
1018 33502 : max_noise_line = max( max_noise_line, hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1 );
1019 : }
1020 :
1021 : /* first lost frame is handled separately */
1022 419474 : if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
1023 : {
1024 165093 : *rnd = 1977 + idchan;
1025 : /* will be set twice when looping over two channels, but does not matter */
1026 165093 : *rnd_c = 1979;
1027 : }
1028 :
1029 419474 : if ( crossfade_gain == 1.0f )
1030 : {
1031 : /* In first frame, noise is weighted with zero anyway, we only need the random numbers for the sign scrambling */
1032 64634500 : for ( i = 0; i < max_noise_line; i++ )
1033 : {
1034 64469407 : *rnd = own_random( rnd );
1035 64469407 : concealment_noise[i] = *rnd;
1036 : }
1037 :
1038 165093 : pop_wmops();
1039 :
1040 165093 : return;
1041 : }
1042 :
1043 254381 : save_rnd_c = *rnd_c;
1044 :
1045 254381 : c = sqrtf( hStereoMdct->lastCoh );
1046 254381 : c_inv = sqrtf( 1 - hStereoMdct->lastCoh );
1047 :
1048 : /* pre-compute the noise shape for later weighting of the noise spectra */
1049 254381 : cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0];
1050 254381 : inc = ( st->core > TCX_20_CORE ) ? 2 : 1;
1051 254381 : start_idx = hFdCngCom->startBand / inc;
1052 254381 : stop_idx = hFdCngCom->stopFFTbin / inc;
1053 :
1054 756363 : for ( i = 0; i < start_idx; i++ )
1055 : {
1056 501982 : noise_shape_buffer[i] = 0.0f;
1057 : }
1058 80069519 : for ( ; i < stop_idx; i++, cngNoiseLevelPtr += inc )
1059 : {
1060 79815138 : noise_shape_buffer[i] = sqrtf( *( cngNoiseLevelPtr ) );
1061 : }
1062 :
1063 254381 : last_scf = sqrtf( *( cngNoiseLevelPtr - inc ) );
1064 :
1065 19235011 : for ( ; i < max_noise_line; i++ )
1066 : {
1067 18980630 : noise_shape_buffer[i] = last_scf;
1068 : }
1069 :
1070 : /* fill the noise vector */
1071 254381 : hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG;
1072 254381 : if ( noise_gen_mode == EQUAL_CORES || ( ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 1 ) ) )
1073 : {
1074 : /* current channel is TCX20 -> generate noise for "full-length" spectrum */
1075 99346986 : for ( i = 0; i < max_noise_line; i++ )
1076 : {
1077 99093190 : *rnd = own_random( rnd );
1078 99093190 : *rnd_c = own_random( rnd_c );
1079 :
1080 99093190 : concealment_noise[i] = ( c_inv * *rnd + c * *rnd_c ) * noise_shape_buffer[i];
1081 99093190 : hTonalMDCTConc->curr_noise_nrg += concealment_noise[i] * concealment_noise[i];
1082 : }
1083 : }
1084 : else /* ( ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 1 ) ) */
1085 : {
1086 : /* current channel is TCX10 and the other is TCX20 -> generate noise for "half-length" spectrum, but "increment" mid seed twice, to have the same seed in mid as the other (TCX20) channel for next frame */
1087 205145 : for ( i = 0; i < max_noise_line; i++ )
1088 : {
1089 204560 : *rnd = own_random( rnd );
1090 204560 : *rnd_c = own_random( rnd_c );
1091 :
1092 204560 : concealment_noise[i] = ( c_inv * *rnd + c * *rnd_c ) * noise_shape_buffer[i];
1093 204560 : hTonalMDCTConc->curr_noise_nrg += concealment_noise[i] * concealment_noise[i];
1094 :
1095 204560 : *rnd_c = own_random( rnd_c );
1096 : }
1097 : }
1098 :
1099 254381 : if ( st->tonal_mdct_plc_active )
1100 : {
1101 282235 : for ( i = crossOverFreq; i < max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i )
1102 : {
1103 261211 : concealment_noise[i] *= 0.0f;
1104 : }
1105 : }
1106 :
1107 : /* restore common seed
1108 : - after finishing the first channel
1109 : - after a first subframe if the current channel is TCX10 */
1110 254381 : if ( ( idchan == 0 && ( core == TCX_20 || ( core == TCX_10 && subframe_idx == 1 ) ) ) || ( core == TCX_10 && subframe_idx == 0 ) )
1111 : {
1112 126652 : *rnd_c = save_rnd_c;
1113 : }
1114 :
1115 254381 : st->seed_tcx_plc = *rnd;
1116 :
1117 254381 : pop_wmops();
1118 :
1119 254381 : return;
1120 : }
1121 :
1122 221073 : void TonalMdctConceal_whiten_noise_shape(
1123 : Decoder_State *st,
1124 : const int16_t L_frame,
1125 : const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode )
1126 : {
1127 : int16_t inc, start_idx, stop_idx;
1128 : float *noiseLevelPtr, *scfs_bg, *scfs_for_shaping;
1129 : HANDLE_FD_CNG_COM hFdCngCom;
1130 : float whitenend_noise_shape[L_FRAME16k];
1131 : float scfs_int[FDNS_NPTS];
1132 : const PsychoacousticParameters *psychParams;
1133 :
1134 221073 : push_wmops( "apply_sns_on_noise_shape" );
1135 :
1136 221073 : scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0];
1137 221073 : psychParams = st->hTonalMDCTConc->psychParams;
1138 221073 : hFdCngCom = st->hFdCngDec->hFdCngCom;
1139 :
1140 221073 : inc = ( ( whitening_mode == ON_FIRST_LOST_FRAME ? st->core : st->last_core ) > TCX_20_CORE ) ? 2 : 1;
1141 221073 : start_idx = hFdCngCom->startBand / inc;
1142 221073 : stop_idx = L_frame / inc;
1143 221073 : noiseLevelPtr = hFdCngCom->cngNoiseLevel;
1144 :
1145 221073 : set_zero( whitenend_noise_shape, start_idx );
1146 69745572 : for ( int16_t j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc )
1147 : {
1148 69524499 : whitenend_noise_shape[j] = *noiseLevelPtr;
1149 : }
1150 :
1151 221073 : if ( whitening_mode == ON_FIRST_LOST_FRAME )
1152 : {
1153 : float scf[SNS_NPTS];
1154 :
1155 61232 : sns_compute_scf( whitenend_noise_shape, psychParams, L_frame, scf );
1156 61232 : sns_interpolate_scalefactors( scfs_int, scf, ENC );
1157 61232 : sns_interpolate_scalefactors( scfs_bg, scf, DEC );
1158 61232 : scfs_for_shaping = &scfs_int[0];
1159 : }
1160 : else /* whitening_mode == ON_FIRST_GOOD_FRAME */
1161 : {
1162 159841 : scfs_for_shaping = &scfs_bg[0];
1163 : }
1164 :
1165 221073 : if ( sum_f( scfs_for_shaping, FDNS_NPTS ) > 0.0f )
1166 : {
1167 121954 : sns_shape_spectrum( whitenend_noise_shape, psychParams, scfs_for_shaping, L_frame );
1168 121954 : mvr2r( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, stop_idx - start_idx );
1169 : }
1170 : else
1171 : {
1172 99119 : set_zero( hFdCngCom->cngNoiseLevel, stop_idx - start_idx );
1173 : }
1174 :
1175 221073 : pop_wmops();
1176 221073 : }
|