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 664154 : 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 664154 : 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 664154 : assert( ( hTonalMDCTConc->nScaleFactors == nScaleFactors ) || ( hTonalMDCTConc->nSamples != nSamples ) ); /* If nSamples doesn't change then also nScaleFactors must stay the same */
69 :
70 664154 : hTonalMDCTConc->tcx_cfg = hTcxCfg;
71 664154 : hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
72 664154 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
73 664154 : hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
74 664154 : hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
75 664154 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
76 664154 : hTonalMDCTConc->lastBlockData.blockIsValid = 0;
77 664154 : hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
78 664154 : hTonalMDCTConc->nSamples = 0;
79 664154 : hTonalMDCTConc->nScaleFactors = 0;
80 :
81 664154 : hTonalMDCTConc->lastBlockData.blockIsConcealed = 0;
82 664154 : hTonalMDCTConc->secondLastBlockData.blockIsConcealed = 0;
83 664154 : hTonalMDCTConc->pTCI = (TonalComponentsInfo *) hTonalMDCTConc->timeDataBuffer;
84 :
85 664154 : hTonalMDCTConc->lastPitchLag = 0;
86 :
87 664154 : if ( hTonalMDCTConc->nSamples != nSamples )
88 : {
89 664154 : hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
90 664154 : hTonalMDCTConc->lastBlockData.blockIsValid = 0;
91 : }
92 664154 : hTonalMDCTConc->nSamples = nSamples;
93 664154 : hTonalMDCTConc->nSamplesCore = nSamplesCore;
94 664154 : hTonalMDCTConc->nScaleFactors = nScaleFactors;
95 :
96 664154 : set_zero( hTonalMDCTConc->scaleFactorsBackground, FDNS_NPTS );
97 664154 : hTonalMDCTConc->scf_fadeout = 1.0f;
98 664154 : PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k, 64, 1, 1, &hTonalMDCTConc->psychParamsTCX20 );
99 664154 : PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k / 2, 64, 0, 1, &hTonalMDCTConc->psychParamsTCX10 );
100 664154 : hTonalMDCTConc->psychParams = NULL;
101 :
102 664154 : hTonalMDCTConc->last_block_nrg = 0.0f;
103 664154 : hTonalMDCTConc->curr_noise_nrg = 0.0f;
104 664154 : 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 664154 : hTonalMDCTConc->secondLastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - ( 3 * min( L_FRAME_MAX, nSamples ) ) / 2];
110 664154 : 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 664154 : assert( sizeof( *hTonalMDCTConc->pTCI ) <= ( hTonalMDCTConc->lastPcmOut - hTonalMDCTConc->timeDataBuffer ) * sizeof( hTonalMDCTConc->timeDataBuffer[0] ) );
115 :
116 664154 : return IVAS_ERR_OK;
117 : }
118 :
119 :
120 32796957 : 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 32796957 : 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 32796957 : if ( !hTonalMDCTConc->lastBlockData.tonalConcealmentActive || ( hTonalMDCTConc->lastBlockData.nSamples != nNewSamples ) )
137 : {
138 32746134 : if ( nNewSamples <= L_FRAME_MAX )
139 : {
140 : /* Shift the buffers */
141 32558599 : temp = hTonalMDCTConc->secondLastBlockData.spectralData; /* Save the pointer */
142 32558599 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->lastBlockData.spectralData;
143 32558599 : hTonalMDCTConc->lastBlockData.spectralData = temp;
144 32558599 : temp = hTonalMDCTConc->secondLastBlockData.scaleFactors;
145 32558599 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->lastBlockData.scaleFactors;
146 32558599 : 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 187535 : hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
152 187535 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
153 187535 : hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
154 187535 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
155 : }
156 32746134 : nOldSamples = hTonalMDCTConc->lastBlockData.nSamples;
157 32746134 : hTonalMDCTConc->lastBlockData.nSamples = nNewSamples;
158 32746134 : hTonalMDCTConc->secondLastBlockData.nSamples = nOldSamples;
159 32746134 : nOldSamples = hTonalMDCTConc->lastBlockData.nSamplesCore;
160 32746134 : hTonalMDCTConc->lastBlockData.nSamplesCore = nNewSamplesCore;
161 32746134 : hTonalMDCTConc->secondLastBlockData.nSamplesCore = nOldSamples;
162 : }
163 :
164 32796957 : if ( ( nNewSamples > 0 ) && ( nNewSamples <= 2 * L_FRAME_MAX ) )
165 : {
166 : /* Store new data */
167 : int16_t i;
168 :
169 32796957 : hTonalMDCTConc->last_block_nrg = 0.0f;
170 15064633467 : for ( i = 0; i < infoIGFStartLine; i++ )
171 : {
172 15031836510 : hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i];
173 15031836510 : hTonalMDCTConc->last_block_nrg += mdctSpectrum[i] * mdctSpectrum[i];
174 : }
175 11876614327 : for ( ; i < nNewSamples; i++ )
176 : {
177 11843817370 : hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i];
178 : }
179 :
180 32796957 : mvr2r( scaleFactors, hTonalMDCTConc->lastBlockData.scaleFactors, hTonalMDCTConc->nScaleFactors );
181 : }
182 :
183 32796957 : return;
184 : }
185 :
186 :
187 37167842 : 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 37167842 : assert( !( !badBlock && tonalConcealmentActive ) );
197 :
198 37167842 : if ( badBlock )
199 : {
200 1241294 : newBlockIsValid = hTonalMDCTConc->lastBlockData.blockIsValid;
201 : }
202 : else
203 : {
204 35926548 : newBlockIsValid = ( nNewSamples <= 2 * L_FRAME_MAX ) && ( nNewSamples > 0 );
205 : }
206 :
207 : /* Shift old state */
208 37167842 : hTonalMDCTConc->secondLastBlockData.blockIsConcealed = hTonalMDCTConc->lastBlockData.blockIsConcealed;
209 37167842 : hTonalMDCTConc->secondLastBlockData.blockIsValid = hTonalMDCTConc->lastBlockData.blockIsValid;
210 37167842 : hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive = hTonalMDCTConc->lastBlockData.tonalConcealmentActive;
211 :
212 : /* Store new state */
213 37167842 : hTonalMDCTConc->lastBlockData.blockIsConcealed = badBlock;
214 37167842 : hTonalMDCTConc->lastBlockData.blockIsValid = newBlockIsValid;
215 37167842 : hTonalMDCTConc->lastBlockData.tonalConcealmentActive = tonalConcealmentActive;
216 37167842 : hTonalMDCTConc->lastPitchLag = pitchLag;
217 :
218 37167842 : return;
219 : }
220 :
221 :
222 180160 : 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 180160 : pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
232 : /* for each index/index group */
233 471778 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
234 : {
235 2327529 : for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
236 : {
237 2035911 : *pCurrentPhase++ = (float) atan2( secondLastMDST[l], secondLastMDCT[l] );
238 : }
239 : }
240 :
241 180160 : 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 180160 : 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 180160 : phaseDiff = hTonalMDCTConc->pTCI->phaseDiff;
264 471778 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
265 : {
266 291618 : k = hTonalMDCTConc->pTCI->indexOfTonalPeak[i];
267 291618 : odft_left = powerSpectrum[k - 1];
268 291618 : odft_right = powerSpectrum[k + 1];
269 291618 : if ( odft_left >= CNST_maxRatio * odft_right )
270 : {
271 2428 : a = (float) tan( 0.0f * EVS_PI / CNST_bandwidth );
272 : }
273 : else
274 : {
275 289190 : if ( odft_right >= CNST_maxRatio * odft_left )
276 : {
277 2628 : a = (float) tan( 2.0f * EVS_PI / CNST_bandwidth );
278 : }
279 : else
280 : {
281 286562 : Q = (float) pow( odft_left / odft_right, CNST_G );
282 286562 : a = ( CNST_m - Q * CNST_s ) / ( CNST_n + Q * CNST_j );
283 : }
284 : }
285 291618 : fractional = (float) atan( a ) * ( CNST_bandwidth / 2.0f );
286 291618 : assert( ( fractional >= 0 ) && ( fractional <= EVS_PI + 1.192092896e-07F ) );
287 291618 : phaseDiff[i] = fractional + EVS_PI * ( k % 4 );
288 : }
289 :
290 180160 : return;
291 : }
292 :
293 180160 : 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 95784467 : for ( k = 1; k <= nSamples - 2; k++ )
304 : {
305 95604307 : x = mdctSpec[k] * mdctSpec[k] + mdstSpec[k] * mdstSpec[k];
306 95604307 : powerSpec[k] = max( floorPowerSpectrum, x );
307 : }
308 180160 : powerSpec[0] = 0.5f * powerSpec[1];
309 180160 : powerSpec[nSamples - 1] = 0.5f * powerSpec[nSamples - 2];
310 :
311 180160 : return;
312 : }
313 :
314 180160 : 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 180160 : nSamples = hTonalMDCTConc->nNonZeroSamples;
328 :
329 : /* It is taken into account that the MDCT is not normalized. */
330 180160 : floorPowerSpectrum = hTonalMDCTConc->nSamples * hTonalMDCTConc->nSamples / 400.0f;
331 180160 : 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 180160 : 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 180160 : if ( hTonalMDCTConc->nSamplesCore > hTonalMDCTConc->nSamples )
341 : {
342 2413 : set_zero( powerSpectrum + hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamplesCore - hTonalMDCTConc->nSamples );
343 : }
344 :
345 180160 : DetectTonalComponents( hTonalMDCTConc->pTCI->indexOfTonalPeak, hTonalMDCTConc->pTCI->lowerIndex, hTonalMDCTConc->pTCI->upperIndex, &hTonalMDCTConc->pTCI->numIndexes, hTonalMDCTConc->lastPitchLag, pitchLag,
346 180160 : hTonalMDCTConc->lastBlockData.spectralData, hTonalMDCTConc->lastBlockData.scaleFactors, powerSpectrum, nSamples, hTonalMDCTConc->nSamplesCore, floorPowerSpectrum, psychParamsCurrent );
347 :
348 180160 : FindPhases( hTonalMDCTConc, secondLastMDCT, secondLastMDST );
349 :
350 180160 : FindPhaseDifferences( hTonalMDCTConc, powerSpectrum );
351 :
352 180160 : if ( hTonalMDCTConc->pTCI->numIndexes > 0 )
353 : {
354 70483 : hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
355 :
356 36931608 : for ( i = 0; i < nSamples; i++ )
357 : {
358 36861125 : powerSpectrum[i] = (float) sqrt( powerSpectrum[i] );
359 : }
360 :
361 4581395 : for ( i = 0; i < hTonalMDCTConc->nScaleFactors; i++ )
362 : {
363 4510912 : invScaleFactors[i] = 1.0f / hTonalMDCTConc->secondLastBlockData.scaleFactors[i];
364 : }
365 :
366 70483 : if ( psychParamsCurrent == NULL )
367 : {
368 22039 : nBands = FDNS_NPTS;
369 22039 : mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, invScaleFactors, nBands );
370 : }
371 : else
372 : {
373 48444 : sns_shape_spectrum( powerSpectrum, psychParamsCurrent, invScaleFactors, hTonalMDCTConc->nSamplesCore );
374 48444 : nBands = psychParamsCurrent->nBands;
375 : }
376 :
377 70483 : v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, invScaleFactors[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples - hTonalMDCTConc->nSamplesCore );
378 70483 : mvr2r( powerSpectrum, hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamples ); /* 16 bits are now enough for storing the power spectrum */
379 : }
380 :
381 180160 : return;
382 : }
383 :
384 :
385 360320 : 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 360320 : L_frame = hTonalMDCTConc->nSamples;
396 360320 : 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 360320 : if ( type == 'S' )
399 : {
400 180160 : TCX_MDST( windowedTimeSignal, mdxtOutput, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, EVS_MONO );
401 : }
402 : else
403 : {
404 180160 : TCX_MDCT( windowedTimeSignal, mdxtOutput, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, EVS_MONO );
405 : }
406 :
407 360320 : return;
408 : }
409 :
410 :
411 253587 : 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 253587 : float *powerSpectrum = secondLastMDST;
420 : int16_t i, nSamples;
421 : int16_t nBands;
422 :
423 253587 : nSamples = hTonalMDCTConc->nSamples;
424 253587 : 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 188956 : if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
429 : {
430 188956 : if ( !hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
431 : {
432 180160 : CalcMDXT( hTonalMDCTConc, 'S', hTonalMDCTConc->secondLastPcmOut, secondLastMDST );
433 180160 : CalcMDXT( hTonalMDCTConc, 'C', hTonalMDCTConc->secondLastPcmOut, secondLastMDCT );
434 180160 : hTonalMDCTConc->nNonZeroSamples = 0;
435 131160160 : for ( i = 0; i < hTonalMDCTConc->nSamples; i++ )
436 : {
437 130980000 : if ( hTonalMDCTConc->secondLastBlockData.spectralData[i] != 0 )
438 : {
439 84446936 : hTonalMDCTConc->nNonZeroSamples = i;
440 : }
441 : }
442 : /* 23 is the maximum length of the MA filter in getEnvelope */
443 180160 : hTonalMDCTConc->nNonZeroSamples = min( hTonalMDCTConc->nSamples, hTonalMDCTConc->nNonZeroSamples + 23 );
444 180160 : 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 8796 : nSamples = hTonalMDCTConc->nNonZeroSamples;
451 8796 : mvr2r( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples ); /* Convert from 16 bits to 32 bits */
452 8796 : if ( psychParamsCurrent == NULL )
453 : {
454 2301 : nBands = FDNS_NPTS;
455 2301 : mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors, nBands );
456 : }
457 : else
458 : {
459 6495 : sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore );
460 6495 : nBands = psychParamsCurrent->nBands;
461 : }
462 :
463 8796 : v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, nSamples - hTonalMDCTConc->nSamplesCore );
464 8796 : v_mult( powerSpectrum, powerSpectrum, powerSpectrum, nSamples );
465 :
466 8796 : RefineTonalComponents( hTonalMDCTConc->pTCI->indexOfTonalPeak, hTonalMDCTConc->pTCI->lowerIndex, hTonalMDCTConc->pTCI->upperIndex, hTonalMDCTConc->pTCI->phaseDiff,
467 8796 : hTonalMDCTConc->pTCI->phase_currentFramePredicted, &hTonalMDCTConc->pTCI->numIndexes, hTonalMDCTConc->lastPitchLag, pitchLag,
468 8796 : hTonalMDCTConc->lastBlockData.spectralData, hTonalMDCTConc->lastBlockData.scaleFactors, powerSpectrum,
469 8796 : nSamples, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples * hTonalMDCTConc->nSamples / 400.0f /* floorPowerSpectrum */, psychParamsCurrent );
470 : }
471 : }
472 : }
473 : else
474 : {
475 64631 : hTonalMDCTConc->pTCI->numIndexes = 0;
476 : }
477 :
478 253587 : *numIndices = hTonalMDCTConc->pTCI->numIndexes;
479 :
480 253587 : return;
481 : }
482 :
483 :
484 921206 : 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 921206 : push_wmops( "InsertNoise" );
502 :
503 921206 : g = 1.0f - crossfadeGain;
504 921206 : if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
505 : {
506 444173 : rnd = 1977;
507 : }
508 : else
509 : {
510 477033 : rnd = *pSeed;
511 : }
512 :
513 : /* based on what is done in tcx_noise_filling() */
514 : /* always initialize these to avoid compiler warnings */
515 921206 : tiltFactor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / hTonalMDCTConc->lastBlockData.nSamples );
516 921206 : tilt = 1.0f;
517 921206 : nrgNoiseInLastFrame = 0.0f;
518 921206 : nrgWhiteNoise = 0.0f;
519 921206 : hTonalMDCTConc->faded_signal_nrg = 0.0f;
520 921206 : last_block_nrg_correct = 0.0f;
521 :
522 921206 : 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 921206 : else if ( concealment_noise != NULL )
528 : {
529 284049 : if ( !tonalConcealmentActive )
530 : {
531 : /* if fadeout has not started yet, only apply sign scrambling */
532 250920 : if ( crossfadeGain == 1.0f )
533 : {
534 49007082 : for ( i = 0; i < crossOverFreq; i++ )
535 : {
536 48880476 : if ( concealment_noise[i] > 0 )
537 : {
538 25498833 : mdctSpectrum[i] = hTonalMDCTConc->lastBlockData.spectralData[i];
539 : }
540 : else
541 : {
542 23381643 : mdctSpectrum[i] = -hTonalMDCTConc->lastBlockData.spectralData[i];
543 : }
544 : }
545 :
546 35037090 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
547 : {
548 34910484 : mdctSpectrum[l] = 0.0f;
549 : }
550 : }
551 : /* actual fadeout is done in this case */
552 : else
553 : {
554 124314 : g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg );
555 :
556 46517130 : for ( i = 0; i < crossOverFreq; i++ )
557 : {
558 46392816 : x = hTonalMDCTConc->lastBlockData.spectralData[i];
559 46392816 : y = concealment_noise[i];
560 :
561 46392816 : if ( y > 0 )
562 : {
563 12707931 : mdctSpectrum[i] = g * y + crossfadeGain * x;
564 : }
565 : else
566 : {
567 33684885 : mdctSpectrum[i] = g * y - crossfadeGain * x;
568 : }
569 :
570 46392816 : hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[i] * mdctSpectrum[i];
571 : }
572 33142458 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
573 : {
574 33018144 : mdctSpectrum[l] = 0.0f;
575 : }
576 : }
577 : }
578 : else
579 : {
580 33129 : 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 183870 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
587 : {
588 1203186 : for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
589 : {
590 1052445 : mdctSpectrum[l] = 0;
591 1052445 : if ( l < crossOverFreq )
592 : {
593 1011225 : last_block_nrg_correct += hTonalMDCTConc->lastBlockData.spectralData[l] * hTonalMDCTConc->lastBlockData.spectralData[l];
594 1011225 : 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 33129 : if ( crossfadeGain == 1.0f )
601 : {
602 1162671 : for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
603 : {
604 1147998 : if ( concealment_noise[l] > 0 )
605 : {
606 571011 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
607 : }
608 : else
609 : {
610 576987 : mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l];
611 : }
612 : }
613 65763 : for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
614 : {
615 1217712 : for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
616 : {
617 1166622 : if ( concealment_noise[l] > 0 )
618 : {
619 609171 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
620 : }
621 : else
622 : {
623 557451 : mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l];
624 : }
625 : }
626 : }
627 :
628 3098847 : for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
629 : {
630 3084174 : if ( concealment_noise[l] > 0 )
631 : {
632 1621752 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
633 : }
634 : else
635 : {
636 1462422 : mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l];
637 : }
638 : }
639 :
640 3908961 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
641 : {
642 3894288 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
643 : }
644 : }
645 : /* actual fadeout is done in this case */
646 : else
647 : {
648 18456 : g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg );
649 :
650 2026866 : for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
651 : {
652 2008410 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
653 2008410 : y = concealment_noise[l];
654 :
655 2008410 : if ( y > 0 )
656 : {
657 418212 : mdctSpectrum[l] = g * y + crossfadeGain * x;
658 : }
659 : else
660 : {
661 1590198 : mdctSpectrum[l] = g * y - crossfadeGain * x;
662 : }
663 2008410 : hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l];
664 : }
665 84978 : for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
666 : {
667 1609728 : for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
668 : {
669 1543206 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
670 1543206 : y = concealment_noise[l];
671 :
672 1543206 : if ( y > 0 )
673 : {
674 473073 : mdctSpectrum[l] = g * y + crossfadeGain * x;
675 : }
676 : else
677 : {
678 1070133 : mdctSpectrum[l] = g * y - crossfadeGain * x;
679 : }
680 1543206 : hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l];
681 : }
682 : }
683 :
684 3112668 : for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
685 : {
686 3094212 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
687 3094212 : y = concealment_noise[l];
688 :
689 3094212 : if ( y > 0 )
690 : {
691 895296 : mdctSpectrum[l] = g * y + crossfadeGain * x;
692 : }
693 : else
694 : {
695 2198916 : mdctSpectrum[l] = g * y - crossfadeGain * x;
696 : }
697 3094212 : hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l];
698 : }
699 :
700 4459992 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
701 : {
702 4441536 : mdctSpectrum[l] = 0.0f;
703 : }
704 : }
705 : }
706 :
707 284049 : 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 80805 : nrg_corr_factor = sqrtf( ( hTonalMDCTConc->last_block_nrg - last_block_nrg_correct ) / hTonalMDCTConc->faded_signal_nrg );
712 80805 : v_multc( mdctSpectrum, nrg_corr_factor, mdctSpectrum, crossOverFreq );
713 : }
714 : }
715 : else
716 : {
717 637157 : if ( !tonalConcealmentActive )
718 : {
719 238653600 : for ( i = 0; i < crossOverFreq; i++ )
720 : {
721 238110184 : x = hTonalMDCTConc->lastBlockData.spectralData[i];
722 238110184 : nrgNoiseInLastFrame += x * x;
723 238110184 : rnd = own_random( &rnd );
724 238110184 : mdctSpectrum[i] = tilt * rnd;
725 238110184 : tilt *= tiltFactor;
726 238110184 : nrgWhiteNoise += mdctSpectrum[i] * mdctSpectrum[i];
727 : }
728 543416 : if ( nrgWhiteNoise > 0 )
729 : {
730 543416 : g *= (float) sqrt( nrgNoiseInLastFrame / nrgWhiteNoise );
731 : }
732 238653600 : for ( i = 0; i < crossOverFreq; i++ )
733 : {
734 238110184 : x = hTonalMDCTConc->lastBlockData.spectralData[i];
735 238110184 : y = mdctSpectrum[i];
736 :
737 238110184 : if ( y > 0 )
738 : {
739 119393223 : mdctSpectrum[i] = g * y + crossfadeGain * x;
740 : }
741 : else
742 : {
743 118716961 : mdctSpectrum[i] = g * y - crossfadeGain * x;
744 : }
745 : }
746 :
747 136099392 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
748 : {
749 135555976 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
750 : }
751 : }
752 : else
753 : {
754 93741 : assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
755 9051123 : for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
756 : {
757 8957382 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
758 8957382 : rnd = own_random( &rnd );
759 8957382 : mdctSpectrum[l] = tilt * rnd;
760 8957382 : tilt *= tiltFactor;
761 8957382 : nrgNoiseInLastFrame += x * x;
762 8957382 : nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l];
763 : }
764 :
765 413322 : for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
766 : {
767 319581 : tilt *= (float) pow( tiltFactor, hTonalMDCTConc->pTCI->upperIndex[i - 1] - hTonalMDCTConc->pTCI->lowerIndex[i - 1] + 1 );
768 7132460 : for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
769 : {
770 6812879 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
771 6812879 : rnd = own_random( &rnd );
772 6812879 : mdctSpectrum[l] = tilt * rnd;
773 6812879 : tilt *= tiltFactor;
774 6812879 : nrgNoiseInLastFrame += x * x;
775 6812879 : nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l];
776 : }
777 : }
778 93741 : tilt *= (float) pow( tiltFactor, hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] - hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1 );
779 :
780 21129416 : for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
781 : {
782 21035675 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
783 21035675 : rnd = own_random( &rnd );
784 21035675 : mdctSpectrum[l] = tilt * rnd;
785 21035675 : tilt *= tiltFactor;
786 21035675 : nrgNoiseInLastFrame += x * x;
787 21035675 : nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l];
788 : }
789 93741 : if ( nrgWhiteNoise > 0 )
790 : {
791 93741 : g *= (float) sqrt( nrgNoiseInLastFrame / nrgWhiteNoise );
792 : }
793 9051123 : for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
794 : {
795 8957382 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
796 8957382 : y = mdctSpectrum[l];
797 :
798 8957382 : if ( y > 0 )
799 : {
800 4563835 : mdctSpectrum[l] = g * y + crossfadeGain * x;
801 : }
802 : else
803 : {
804 4393547 : mdctSpectrum[l] = g * y - crossfadeGain * x;
805 : }
806 : }
807 413322 : for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
808 : {
809 7132460 : for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
810 : {
811 6812879 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
812 6812879 : y = mdctSpectrum[l];
813 :
814 6812879 : if ( y > 0 )
815 : {
816 3493420 : mdctSpectrum[l] = g * y + crossfadeGain * x;
817 : }
818 : else
819 : {
820 3319459 : 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 507063 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
829 : {
830 3303409 : for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
831 : {
832 2890087 : mdctSpectrum[l] = 0;
833 : }
834 : }
835 21129416 : for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
836 : {
837 21035675 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
838 21035675 : y = mdctSpectrum[l];
839 :
840 21035675 : if ( y > 0 )
841 : {
842 10393247 : mdctSpectrum[l] = g * y + crossfadeGain * x;
843 : }
844 : else
845 : {
846 10642428 : mdctSpectrum[l] = g * y - crossfadeGain * x;
847 : }
848 : }
849 :
850 22663601 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
851 : {
852 22569860 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
853 : }
854 : }
855 : }
856 :
857 921206 : *pSeed = rnd;
858 :
859 921206 : pop_wmops();
860 :
861 921206 : return;
862 : }
863 :
864 :
865 126870 : 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 126870 : if ( hTonalMDCTConc->lastBlockData.blockIsValid & hTonalMDCTConc->secondLastBlockData.blockIsValid )
878 : {
879 126870 : assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
880 :
881 126870 : nSamples = hTonalMDCTConc->nNonZeroSamples;
882 126870 : assert( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] < nSamples );
883 126870 : mvr2r( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples ); /* Convert from 16 bits to 32 bits */
884 126870 : if ( psychParamsCurrent == NULL )
885 : {
886 33690 : nBands = FDNS_NPTS;
887 33690 : mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors, nBands );
888 : }
889 : else
890 : {
891 93180 : sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore );
892 93180 : nBands = psychParamsCurrent->nBands;
893 : }
894 :
895 126870 : v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, nSamples - hTonalMDCTConc->nSamplesCore );
896 :
897 126870 : phaseDiff = hTonalMDCTConc->pTCI->phaseDiff; /* if multiple frame loss occurs use the phase from the last frame and continue rotating */
898 126870 : pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
899 :
900 126870 : if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
901 : {
902 52322 : if ( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
903 : {
904 3786 : hTonalMDCTConc->nFramesLost += 1;
905 : }
906 : else
907 : {
908 48536 : hTonalMDCTConc->nFramesLost = 1.5;
909 : }
910 : }
911 :
912 : /* for each index group */
913 690933 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
914 : {
915 564063 : phaseToAdd = hTonalMDCTConc->nFramesLost * phaseDiff[i];
916 :
917 : /* Move phaseToAdd to range -EVS_PI..EVS_PI */
918 7704614 : while ( phaseToAdd > EVS_PI )
919 : {
920 7140551 : phaseToAdd -= PI2;
921 : }
922 :
923 564063 : while ( phaseToAdd < -EVS_PI )
924 : {
925 : /* should never occur in flt - kept for safety reasons */
926 0 : phaseToAdd += PI2;
927 : }
928 :
929 4506595 : for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
930 : {
931 3942532 : const float currentPhase = ( *pCurrentPhase++ ) + phaseToAdd; /* *pCurrentPhase and phaseToAdd are in range -EVS_PI..EVS_PI */
932 3942532 : mdctSpectrum[l] = (float) cos( currentPhase ) * powerSpectrum[l];
933 : }
934 : }
935 : }
936 :
937 126870 : hTonalMDCTConc->nFramesLost++;
938 :
939 126870 : return;
940 : }
941 :
942 :
943 35554776 : void TonalMDCTConceal_SaveTimeSignal(
944 : TonalMDCTConcealPtr hTonalMDCTConc,
945 : float *timeSignal,
946 : const int16_t nNewSamples )
947 : {
948 35554776 : if ( nNewSamples == hTonalMDCTConc->nSamples )
949 : {
950 34896651 : assert( nNewSamples <= L_FRAME_MAX );
951 :
952 34896651 : if ( !hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
953 : {
954 34845336 : mvr2r( hTonalMDCTConc->lastPcmOut + hTonalMDCTConc->nSamples / 2, hTonalMDCTConc->secondLastPcmOut, hTonalMDCTConc->nSamples / 2 );
955 : }
956 :
957 34896651 : mvr2r( timeSignal, hTonalMDCTConc->lastPcmOut, hTonalMDCTConc->nSamples );
958 : }
959 :
960 35554776 : return;
961 : }
962 :
963 284049 : 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 284049 : push_wmops( "create_conc_noise" );
987 :
988 284049 : hStereoMdct = hCPE->hStereoMdct;
989 284049 : st = hCPE->hCoreCoder[idchan];
990 284049 : hTonalMDCTConc = st->hTonalMDCTConc;
991 284049 : hFdCngCom = st->hFdCngDec->hFdCngCom;
992 284049 : rnd = &hStereoMdct->noise_seeds_channels[idchan];
993 284049 : rnd_c = &hStereoMdct->noise_seed_common;
994 :
995 : /* determine start bin for IGF */
996 284049 : if ( st->igf == 0 )
997 : {
998 97767 : if ( st->narrowBand == 0 )
999 : {
1000 : /* minimum needed for output with sampling rates lower then the
1001 : nominal sampling rate */
1002 97767 : crossOverFreq = min( L_frameTCX, L_frame );
1003 : }
1004 : else
1005 : {
1006 0 : crossOverFreq = L_frameTCX;
1007 : }
1008 : }
1009 : else
1010 : {
1011 186282 : 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 284049 : max_noise_line = crossOverFreq;
1016 284049 : if ( st->tonal_mdct_plc_active )
1017 : {
1018 33129 : 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 284049 : if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
1023 : {
1024 141279 : *rnd = 1977 + idchan;
1025 : /* will be set twice when looping over two channels, but does not matter */
1026 141279 : *rnd_c = 1979;
1027 : }
1028 :
1029 284049 : 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 54879855 : for ( i = 0; i < max_noise_line; i++ )
1033 : {
1034 54738576 : *rnd = own_random( rnd );
1035 54738576 : concealment_noise[i] = *rnd;
1036 : }
1037 :
1038 141279 : pop_wmops();
1039 :
1040 141279 : return;
1041 : }
1042 :
1043 142770 : save_rnd_c = *rnd_c;
1044 :
1045 142770 : c = sqrtf( hStereoMdct->lastCoh );
1046 142770 : c_inv = sqrtf( 1 - hStereoMdct->lastCoh );
1047 :
1048 : /* pre-compute the noise shape for later weighting of the noise spectra */
1049 142770 : cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0];
1050 142770 : inc = ( st->core > TCX_20_CORE ) ? 2 : 1;
1051 142770 : start_idx = hFdCngCom->startBand / inc;
1052 142770 : stop_idx = hFdCngCom->stopFFTbin / inc;
1053 :
1054 421146 : for ( i = 0; i < start_idx; i++ )
1055 : {
1056 278376 : noise_shape_buffer[i] = 0.0f;
1057 : }
1058 44404554 : for ( ; i < stop_idx; i++, cngNoiseLevelPtr += inc )
1059 : {
1060 44261784 : noise_shape_buffer[i] = sqrtf( *( cngNoiseLevelPtr ) );
1061 : }
1062 :
1063 142770 : last_scf = sqrtf( *( cngNoiseLevelPtr - inc ) );
1064 :
1065 9234393 : for ( ; i < max_noise_line; i++ )
1066 : {
1067 9091623 : noise_shape_buffer[i] = last_scf;
1068 : }
1069 :
1070 : /* fill the noise vector */
1071 142770 : hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG;
1072 142770 : 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 53555778 : for ( i = 0; i < max_noise_line; i++ )
1076 : {
1077 53413623 : *rnd = own_random( rnd );
1078 53413623 : *rnd_c = own_random( rnd_c );
1079 :
1080 53413623 : concealment_noise[i] = ( c_inv * *rnd + c * *rnd_c ) * noise_shape_buffer[i];
1081 53413623 : 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 218775 : for ( i = 0; i < max_noise_line; i++ )
1088 : {
1089 218160 : *rnd = own_random( rnd );
1090 218160 : *rnd_c = own_random( rnd_c );
1091 :
1092 218160 : concealment_noise[i] = ( c_inv * *rnd + c * *rnd_c ) * noise_shape_buffer[i];
1093 218160 : hTonalMDCTConc->curr_noise_nrg += concealment_noise[i] * concealment_noise[i];
1094 :
1095 218160 : *rnd_c = own_random( rnd_c );
1096 : }
1097 : }
1098 :
1099 142770 : if ( st->tonal_mdct_plc_active )
1100 : {
1101 288513 : for ( i = crossOverFreq; i < max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i )
1102 : {
1103 270057 : 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 142770 : if ( ( idchan == 0 && ( core == TCX_20 || ( core == TCX_10 && subframe_idx == 1 ) ) ) || ( core == TCX_10 && subframe_idx == 0 ) )
1111 : {
1112 70959 : *rnd_c = save_rnd_c;
1113 : }
1114 :
1115 142770 : st->seed_tcx_plc = *rnd;
1116 :
1117 142770 : pop_wmops();
1118 :
1119 142770 : return;
1120 : }
1121 :
1122 225651 : 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 225651 : push_wmops( "apply_sns_on_noise_shape" );
1135 :
1136 225651 : scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0];
1137 225651 : psychParams = st->hTonalMDCTConc->psychParams;
1138 225651 : hFdCngCom = st->hFdCngDec->hFdCngCom;
1139 :
1140 225651 : inc = ( ( whitening_mode == ON_FIRST_LOST_FRAME ? st->core : st->last_core ) > TCX_20_CORE ) ? 2 : 1;
1141 225651 : start_idx = hFdCngCom->startBand / inc;
1142 225651 : stop_idx = L_frame / inc;
1143 225651 : noiseLevelPtr = hFdCngCom->cngNoiseLevel;
1144 :
1145 225651 : set_zero( whitenend_noise_shape, start_idx );
1146 71060151 : for ( int16_t j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc )
1147 : {
1148 70834500 : whitenend_noise_shape[j] = *noiseLevelPtr;
1149 : }
1150 :
1151 225651 : if ( whitening_mode == ON_FIRST_LOST_FRAME )
1152 : {
1153 : float scf[SNS_NPTS];
1154 :
1155 90567 : sns_compute_scf( whitenend_noise_shape, psychParams, L_frame, scf );
1156 90567 : sns_interpolate_scalefactors( scfs_int, scf, ENC );
1157 90567 : sns_interpolate_scalefactors( scfs_bg, scf, DEC );
1158 90567 : scfs_for_shaping = &scfs_int[0];
1159 : }
1160 : else /* whitening_mode == ON_FIRST_GOOD_FRAME */
1161 : {
1162 135084 : scfs_for_shaping = &scfs_bg[0];
1163 : }
1164 :
1165 225651 : if ( sum_f( scfs_for_shaping, FDNS_NPTS ) > 0.0f )
1166 : {
1167 179865 : sns_shape_spectrum( whitenend_noise_shape, psychParams, scfs_for_shaping, L_frame );
1168 179865 : mvr2r( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, stop_idx - start_idx );
1169 : }
1170 : else
1171 : {
1172 45786 : set_zero( hFdCngCom->cngNoiseLevel, stop_idx - start_idx );
1173 : }
1174 :
1175 225651 : pop_wmops();
1176 225651 : }
|