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 664166 : 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 664166 : 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 664166 : assert( ( hTonalMDCTConc->nScaleFactors == nScaleFactors ) || ( hTonalMDCTConc->nSamples != nSamples ) ); /* If nSamples doesn't change then also nScaleFactors must stay the same */
69 :
70 664166 : hTonalMDCTConc->tcx_cfg = hTcxCfg;
71 664166 : hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
72 664166 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
73 664166 : hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
74 664166 : hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
75 664166 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
76 664166 : hTonalMDCTConc->lastBlockData.blockIsValid = 0;
77 664166 : hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
78 664166 : hTonalMDCTConc->nSamples = 0;
79 664166 : hTonalMDCTConc->nScaleFactors = 0;
80 :
81 664166 : hTonalMDCTConc->lastBlockData.blockIsConcealed = 0;
82 664166 : hTonalMDCTConc->secondLastBlockData.blockIsConcealed = 0;
83 664166 : hTonalMDCTConc->pTCI = (TonalComponentsInfo *) hTonalMDCTConc->timeDataBuffer;
84 :
85 664166 : hTonalMDCTConc->lastPitchLag = 0;
86 :
87 664166 : if ( hTonalMDCTConc->nSamples != nSamples )
88 : {
89 664166 : hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
90 664166 : hTonalMDCTConc->lastBlockData.blockIsValid = 0;
91 : }
92 664166 : hTonalMDCTConc->nSamples = nSamples;
93 664166 : hTonalMDCTConc->nSamplesCore = nSamplesCore;
94 664166 : hTonalMDCTConc->nScaleFactors = nScaleFactors;
95 :
96 664166 : set_zero( hTonalMDCTConc->scaleFactorsBackground, FDNS_NPTS );
97 664166 : hTonalMDCTConc->scf_fadeout = 1.0f;
98 664166 : PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k, 64, 1, 1, &hTonalMDCTConc->psychParamsTCX20 );
99 664166 : PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k / 2, 64, 0, 1, &hTonalMDCTConc->psychParamsTCX10 );
100 664166 : hTonalMDCTConc->psychParams = NULL;
101 :
102 664166 : hTonalMDCTConc->last_block_nrg = 0.0f;
103 664166 : hTonalMDCTConc->curr_noise_nrg = 0.0f;
104 664166 : 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 664166 : hTonalMDCTConc->secondLastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - ( 3 * min( L_FRAME_MAX, nSamples ) ) / 2];
110 664166 : 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 664166 : assert( sizeof( *hTonalMDCTConc->pTCI ) <= ( hTonalMDCTConc->lastPcmOut - hTonalMDCTConc->timeDataBuffer ) * sizeof( hTonalMDCTConc->timeDataBuffer[0] ) );
115 :
116 664166 : return IVAS_ERR_OK;
117 : }
118 :
119 :
120 32854935 : 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 32854935 : 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 32854935 : if ( !hTonalMDCTConc->lastBlockData.tonalConcealmentActive || ( hTonalMDCTConc->lastBlockData.nSamples != nNewSamples ) )
137 : {
138 32804049 : if ( nNewSamples <= L_FRAME_MAX )
139 : {
140 : /* Shift the buffers */
141 32616433 : temp = hTonalMDCTConc->secondLastBlockData.spectralData; /* Save the pointer */
142 32616433 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->lastBlockData.spectralData;
143 32616433 : hTonalMDCTConc->lastBlockData.spectralData = temp;
144 32616433 : temp = hTonalMDCTConc->secondLastBlockData.scaleFactors;
145 32616433 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->lastBlockData.scaleFactors;
146 32616433 : 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 187616 : hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
152 187616 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
153 187616 : hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
154 187616 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
155 : }
156 32804049 : nOldSamples = hTonalMDCTConc->lastBlockData.nSamples;
157 32804049 : hTonalMDCTConc->lastBlockData.nSamples = nNewSamples;
158 32804049 : hTonalMDCTConc->secondLastBlockData.nSamples = nOldSamples;
159 32804049 : nOldSamples = hTonalMDCTConc->lastBlockData.nSamplesCore;
160 32804049 : hTonalMDCTConc->lastBlockData.nSamplesCore = nNewSamplesCore;
161 32804049 : hTonalMDCTConc->secondLastBlockData.nSamplesCore = nOldSamples;
162 : }
163 :
164 32854935 : if ( ( nNewSamples > 0 ) && ( nNewSamples <= 2 * L_FRAME_MAX ) )
165 : {
166 : /* Store new data */
167 : int16_t i;
168 :
169 32854935 : hTonalMDCTConc->last_block_nrg = 0.0f;
170 15087458091 : for ( i = 0; i < infoIGFStartLine; i++ )
171 : {
172 15054603156 : hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i];
173 15054603156 : hTonalMDCTConc->last_block_nrg += mdctSpectrum[i] * mdctSpectrum[i];
174 : }
175 11909056459 : for ( ; i < nNewSamples; i++ )
176 : {
177 11876201524 : hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i];
178 : }
179 :
180 32854935 : mvr2r( scaleFactors, hTonalMDCTConc->lastBlockData.scaleFactors, hTonalMDCTConc->nScaleFactors );
181 : }
182 :
183 32854935 : return;
184 : }
185 :
186 :
187 37230716 : 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 37230716 : assert( !( !badBlock && tonalConcealmentActive ) );
197 :
198 37230716 : if ( badBlock )
199 : {
200 1245023 : newBlockIsValid = hTonalMDCTConc->lastBlockData.blockIsValid;
201 : }
202 : else
203 : {
204 35985693 : newBlockIsValid = ( nNewSamples <= 2 * L_FRAME_MAX ) && ( nNewSamples > 0 );
205 : }
206 :
207 : /* Shift old state */
208 37230716 : hTonalMDCTConc->secondLastBlockData.blockIsConcealed = hTonalMDCTConc->lastBlockData.blockIsConcealed;
209 37230716 : hTonalMDCTConc->secondLastBlockData.blockIsValid = hTonalMDCTConc->lastBlockData.blockIsValid;
210 37230716 : hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive = hTonalMDCTConc->lastBlockData.tonalConcealmentActive;
211 :
212 : /* Store new state */
213 37230716 : hTonalMDCTConc->lastBlockData.blockIsConcealed = badBlock;
214 37230716 : hTonalMDCTConc->lastBlockData.blockIsValid = newBlockIsValid;
215 37230716 : hTonalMDCTConc->lastBlockData.tonalConcealmentActive = tonalConcealmentActive;
216 37230716 : hTonalMDCTConc->lastPitchLag = pitchLag;
217 :
218 37230716 : return;
219 : }
220 :
221 :
222 180796 : 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 180796 : pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
232 : /* for each index/index group */
233 472810 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
234 : {
235 2330679 : for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
236 : {
237 2038665 : *pCurrentPhase++ = (float) atan2( secondLastMDST[l], secondLastMDCT[l] );
238 : }
239 : }
240 :
241 180796 : 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 180796 : 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 180796 : phaseDiff = hTonalMDCTConc->pTCI->phaseDiff;
264 472810 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
265 : {
266 292014 : k = hTonalMDCTConc->pTCI->indexOfTonalPeak[i];
267 292014 : odft_left = powerSpectrum[k - 1];
268 292014 : odft_right = powerSpectrum[k + 1];
269 292014 : if ( odft_left >= CNST_maxRatio * odft_right )
270 : {
271 2425 : a = (float) tan( 0.0f * EVS_PI / CNST_bandwidth );
272 : }
273 : else
274 : {
275 289589 : if ( odft_right >= CNST_maxRatio * odft_left )
276 : {
277 2643 : a = (float) tan( 2.0f * EVS_PI / CNST_bandwidth );
278 : }
279 : else
280 : {
281 286946 : Q = (float) pow( odft_left / odft_right, CNST_G );
282 286946 : a = ( CNST_m - Q * CNST_s ) / ( CNST_n + Q * CNST_j );
283 : }
284 : }
285 292014 : fractional = (float) atan( a ) * ( CNST_bandwidth / 2.0f );
286 292014 : assert( ( fractional >= 0 ) && ( fractional <= EVS_PI + 1.192092896e-07F ) );
287 292014 : phaseDiff[i] = fractional + EVS_PI * ( k % 4 );
288 : }
289 :
290 180796 : return;
291 : }
292 :
293 180796 : 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 96258620 : for ( k = 1; k <= nSamples - 2; k++ )
304 : {
305 96077824 : x = mdctSpec[k] * mdctSpec[k] + mdstSpec[k] * mdstSpec[k];
306 96077824 : powerSpec[k] = max( floorPowerSpectrum, x );
307 : }
308 180796 : powerSpec[0] = 0.5f * powerSpec[1];
309 180796 : powerSpec[nSamples - 1] = 0.5f * powerSpec[nSamples - 2];
310 :
311 180796 : return;
312 : }
313 :
314 180796 : 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 180796 : nSamples = hTonalMDCTConc->nNonZeroSamples;
328 :
329 : /* It is taken into account that the MDCT is not normalized. */
330 180796 : floorPowerSpectrum = hTonalMDCTConc->nSamples * hTonalMDCTConc->nSamples / 400.0f;
331 180796 : 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 180796 : 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 180796 : if ( hTonalMDCTConc->nSamplesCore > hTonalMDCTConc->nSamples )
341 : {
342 2413 : set_zero( powerSpectrum + hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamplesCore - hTonalMDCTConc->nSamples );
343 : }
344 :
345 180796 : DetectTonalComponents( hTonalMDCTConc->pTCI->indexOfTonalPeak, hTonalMDCTConc->pTCI->lowerIndex, hTonalMDCTConc->pTCI->upperIndex, &hTonalMDCTConc->pTCI->numIndexes, hTonalMDCTConc->lastPitchLag, pitchLag,
346 180796 : hTonalMDCTConc->lastBlockData.spectralData, hTonalMDCTConc->lastBlockData.scaleFactors, powerSpectrum, nSamples, hTonalMDCTConc->nSamplesCore, floorPowerSpectrum, psychParamsCurrent );
347 :
348 180796 : FindPhases( hTonalMDCTConc, secondLastMDCT, secondLastMDST );
349 :
350 180796 : FindPhaseDifferences( hTonalMDCTConc, powerSpectrum );
351 :
352 180796 : if ( hTonalMDCTConc->pTCI->numIndexes > 0 )
353 : {
354 70642 : hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
355 :
356 37058898 : for ( i = 0; i < nSamples; i++ )
357 : {
358 36988256 : powerSpectrum[i] = (float) sqrt( powerSpectrum[i] );
359 : }
360 :
361 4591730 : for ( i = 0; i < hTonalMDCTConc->nScaleFactors; i++ )
362 : {
363 4521088 : invScaleFactors[i] = 1.0f / hTonalMDCTConc->secondLastBlockData.scaleFactors[i];
364 : }
365 :
366 70642 : if ( psychParamsCurrent == NULL )
367 : {
368 22015 : nBands = FDNS_NPTS;
369 22015 : mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, invScaleFactors, nBands );
370 : }
371 : else
372 : {
373 48627 : sns_shape_spectrum( powerSpectrum, psychParamsCurrent, invScaleFactors, hTonalMDCTConc->nSamplesCore );
374 48627 : nBands = psychParamsCurrent->nBands;
375 : }
376 :
377 70642 : v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, invScaleFactors[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples - hTonalMDCTConc->nSamplesCore );
378 70642 : mvr2r( powerSpectrum, hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamples ); /* 16 bits are now enough for storing the power spectrum */
379 : }
380 :
381 180796 : return;
382 : }
383 :
384 :
385 361592 : 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 361592 : L_frame = hTonalMDCTConc->nSamples;
396 361592 : 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 361592 : if ( type == 'S' )
399 : {
400 180796 : TCX_MDST( windowedTimeSignal, mdxtOutput, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, EVS_MONO );
401 : }
402 : else
403 : {
404 180796 : TCX_MDCT( windowedTimeSignal, mdxtOutput, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, EVS_MONO );
405 : }
406 :
407 361592 : return;
408 : }
409 :
410 :
411 254226 : 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 254226 : float *powerSpectrum = secondLastMDST;
420 : int16_t i, nSamples;
421 : int16_t nBands;
422 :
423 254226 : nSamples = hTonalMDCTConc->nSamples;
424 254226 : 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 189592 : if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
429 : {
430 189592 : if ( !hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
431 : {
432 180796 : CalcMDXT( hTonalMDCTConc, 'S', hTonalMDCTConc->secondLastPcmOut, secondLastMDST );
433 180796 : CalcMDXT( hTonalMDCTConc, 'C', hTonalMDCTConc->secondLastPcmOut, secondLastMDCT );
434 180796 : hTonalMDCTConc->nNonZeroSamples = 0;
435 131771356 : for ( i = 0; i < hTonalMDCTConc->nSamples; i++ )
436 : {
437 131590560 : if ( hTonalMDCTConc->secondLastBlockData.spectralData[i] != 0 )
438 : {
439 84878222 : hTonalMDCTConc->nNonZeroSamples = i;
440 : }
441 : }
442 : /* 23 is the maximum length of the MA filter in getEnvelope */
443 180796 : hTonalMDCTConc->nNonZeroSamples = min( hTonalMDCTConc->nSamples, hTonalMDCTConc->nNonZeroSamples + 23 );
444 180796 : 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 64634 : hTonalMDCTConc->pTCI->numIndexes = 0;
476 : }
477 :
478 254226 : *numIndices = hTonalMDCTConc->pTCI->numIndexes;
479 :
480 254226 : return;
481 : }
482 :
483 :
484 923918 : 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 923918 : push_wmops( "InsertNoise" );
502 :
503 923918 : g = 1.0f - crossfadeGain;
504 923918 : if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
505 : {
506 445451 : rnd = 1977;
507 : }
508 : else
509 : {
510 478467 : rnd = *pSeed;
511 : }
512 :
513 : /* based on what is done in tcx_noise_filling() */
514 : /* always initialize these to avoid compiler warnings */
515 923918 : tiltFactor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / hTonalMDCTConc->lastBlockData.nSamples );
516 923918 : tilt = 1.0f;
517 923918 : nrgNoiseInLastFrame = 0.0f;
518 923918 : nrgWhiteNoise = 0.0f;
519 923918 : hTonalMDCTConc->faded_signal_nrg = 0.0f;
520 923918 : last_block_nrg_correct = 0.0f;
521 :
522 923918 : 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 923918 : else if ( concealment_noise != NULL )
528 : {
529 286860 : if ( !tonalConcealmentActive )
530 : {
531 : /* if fadeout has not started yet, only apply sign scrambling */
532 253461 : if ( crossfadeGain == 1.0f )
533 : {
534 49482057 : for ( i = 0; i < crossOverFreq; i++ )
535 : {
536 49354236 : if ( concealment_noise[i] > 0 )
537 : {
538 25749138 : mdctSpectrum[i] = hTonalMDCTConc->lastBlockData.spectralData[i];
539 : }
540 : else
541 : {
542 23605098 : mdctSpectrum[i] = -hTonalMDCTConc->lastBlockData.spectralData[i];
543 : }
544 : }
545 :
546 35707905 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
547 : {
548 35580084 : mdctSpectrum[l] = 0.0f;
549 : }
550 : }
551 : /* actual fadeout is done in this case */
552 : else
553 : {
554 125640 : g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg );
555 :
556 47033496 : for ( i = 0; i < crossOverFreq; i++ )
557 : {
558 46907856 : x = hTonalMDCTConc->lastBlockData.spectralData[i];
559 46907856 : y = concealment_noise[i];
560 :
561 46907856 : if ( y > 0 )
562 : {
563 12947592 : mdctSpectrum[i] = g * y + crossfadeGain * x;
564 : }
565 : else
566 : {
567 33960264 : mdctSpectrum[i] = g * y - crossfadeGain * x;
568 : }
569 :
570 46907856 : hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[i] * mdctSpectrum[i];
571 : }
572 33872904 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
573 : {
574 33747264 : mdctSpectrum[l] = 0.0f;
575 : }
576 : }
577 : }
578 : else
579 : {
580 33399 : 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 185319 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
587 : {
588 1212588 : for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
589 : {
590 1060668 : mdctSpectrum[l] = 0;
591 1060668 : if ( l < crossOverFreq )
592 : {
593 1019196 : last_block_nrg_correct += hTonalMDCTConc->lastBlockData.spectralData[l] * hTonalMDCTConc->lastBlockData.spectralData[l];
594 1019196 : 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 33399 : if ( crossfadeGain == 1.0f )
601 : {
602 1168740 : for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
603 : {
604 1153953 : if ( concealment_noise[l] > 0 )
605 : {
606 573795 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
607 : }
608 : else
609 : {
610 580158 : mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l];
611 : }
612 : }
613 66261 : for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
614 : {
615 1229214 : for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
616 : {
617 1177740 : if ( concealment_noise[l] > 0 )
618 : {
619 615069 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
620 : }
621 : else
622 : {
623 562671 : mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l];
624 : }
625 : }
626 : }
627 :
628 3123723 : for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
629 : {
630 3108936 : if ( concealment_noise[l] > 0 )
631 : {
632 1635105 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
633 : }
634 : else
635 : {
636 1473831 : mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l];
637 : }
638 : }
639 :
640 3973635 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
641 : {
642 3958848 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
643 : }
644 : }
645 : /* actual fadeout is done in this case */
646 : else
647 : {
648 18612 : g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg );
649 :
650 2033823 : for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
651 : {
652 2015211 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
653 2015211 : y = concealment_noise[l];
654 :
655 2015211 : if ( y > 0 )
656 : {
657 421137 : mdctSpectrum[l] = g * y + crossfadeGain * x;
658 : }
659 : else
660 : {
661 1594074 : mdctSpectrum[l] = g * y - crossfadeGain * x;
662 : }
663 2015211 : hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l];
664 : }
665 85659 : for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
666 : {
667 1624086 : for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
668 : {
669 1557039 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
670 1557039 : y = concealment_noise[l];
671 :
672 1557039 : if ( y > 0 )
673 : {
674 479400 : mdctSpectrum[l] = g * y + crossfadeGain * x;
675 : }
676 : else
677 : {
678 1077639 : mdctSpectrum[l] = g * y - crossfadeGain * x;
679 : }
680 1557039 : hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l];
681 : }
682 : }
683 :
684 3147864 : for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
685 : {
686 3129252 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
687 3129252 : y = concealment_noise[l];
688 :
689 3129252 : if ( y > 0 )
690 : {
691 912408 : mdctSpectrum[l] = g * y + crossfadeGain * x;
692 : }
693 : else
694 : {
695 2216844 : mdctSpectrum[l] = g * y - crossfadeGain * x;
696 : }
697 3129252 : hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l];
698 : }
699 :
700 4549908 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
701 : {
702 4531296 : mdctSpectrum[l] = 0.0f;
703 : }
704 : }
705 : }
706 :
707 286860 : 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 82281 : nrg_corr_factor = sqrtf( ( hTonalMDCTConc->last_block_nrg - last_block_nrg_correct ) / hTonalMDCTConc->faded_signal_nrg );
712 82281 : v_multc( mdctSpectrum, nrg_corr_factor, mdctSpectrum, crossOverFreq );
713 : }
714 : }
715 : else
716 : {
717 637058 : if ( !tonalConcealmentActive )
718 : {
719 238657605 : for ( i = 0; i < crossOverFreq; i++ )
720 : {
721 238114168 : x = hTonalMDCTConc->lastBlockData.spectralData[i];
722 238114168 : nrgNoiseInLastFrame += x * x;
723 238114168 : rnd = own_random( &rnd );
724 238114168 : mdctSpectrum[i] = tilt * rnd;
725 238114168 : tilt *= tiltFactor;
726 238114168 : nrgWhiteNoise += mdctSpectrum[i] * mdctSpectrum[i];
727 : }
728 543437 : if ( nrgWhiteNoise > 0 )
729 : {
730 543437 : g *= (float) sqrt( nrgNoiseInLastFrame / nrgWhiteNoise );
731 : }
732 238657605 : for ( i = 0; i < crossOverFreq; i++ )
733 : {
734 238114168 : x = hTonalMDCTConc->lastBlockData.spectralData[i];
735 238114168 : y = mdctSpectrum[i];
736 :
737 238114168 : if ( y > 0 )
738 : {
739 119395326 : mdctSpectrum[i] = g * y + crossfadeGain * x;
740 : }
741 : else
742 : {
743 118718842 : mdctSpectrum[i] = g * y - crossfadeGain * x;
744 : }
745 : }
746 :
747 136110309 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
748 : {
749 135566872 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
750 : }
751 : }
752 : else
753 : {
754 93621 : assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
755 9050124 : for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
756 : {
757 8956503 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
758 8956503 : rnd = own_random( &rnd );
759 8956503 : mdctSpectrum[l] = tilt * rnd;
760 8956503 : tilt *= tiltFactor;
761 8956503 : nrgNoiseInLastFrame += x * x;
762 8956503 : nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l];
763 : }
764 :
765 412530 : for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
766 : {
767 318909 : tilt *= (float) pow( tiltFactor, hTonalMDCTConc->pTCI->upperIndex[i - 1] - hTonalMDCTConc->pTCI->lowerIndex[i - 1] + 1 );
768 7129370 : for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
769 : {
770 6810461 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
771 6810461 : rnd = own_random( &rnd );
772 6810461 : mdctSpectrum[l] = tilt * rnd;
773 6810461 : tilt *= tiltFactor;
774 6810461 : nrgNoiseInLastFrame += x * x;
775 6810461 : nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l];
776 : }
777 : }
778 93621 : tilt *= (float) pow( tiltFactor, hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] - hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1 );
779 :
780 21114242 : for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
781 : {
782 21020621 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
783 21020621 : rnd = own_random( &rnd );
784 21020621 : mdctSpectrum[l] = tilt * rnd;
785 21020621 : tilt *= tiltFactor;
786 21020621 : nrgNoiseInLastFrame += x * x;
787 21020621 : nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l];
788 : }
789 93621 : if ( nrgWhiteNoise > 0 )
790 : {
791 93621 : g *= (float) sqrt( nrgNoiseInLastFrame / nrgWhiteNoise );
792 : }
793 9050124 : for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
794 : {
795 8956503 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
796 8956503 : y = mdctSpectrum[l];
797 :
798 8956503 : if ( y > 0 )
799 : {
800 4563406 : mdctSpectrum[l] = g * y + crossfadeGain * x;
801 : }
802 : else
803 : {
804 4393097 : mdctSpectrum[l] = g * y - crossfadeGain * x;
805 : }
806 : }
807 412530 : for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
808 : {
809 7129370 : for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
810 : {
811 6810461 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
812 6810461 : y = mdctSpectrum[l];
813 :
814 6810461 : if ( y > 0 )
815 : {
816 3492376 : mdctSpectrum[l] = g * y + crossfadeGain * x;
817 : }
818 : else
819 : {
820 3318085 : 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 506151 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
829 : {
830 3297073 : for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
831 : {
832 2884543 : mdctSpectrum[l] = 0;
833 : }
834 : }
835 21114242 : for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
836 : {
837 21020621 : x = hTonalMDCTConc->lastBlockData.spectralData[l];
838 21020621 : y = mdctSpectrum[l];
839 :
840 21020621 : if ( y > 0 )
841 : {
842 10384934 : mdctSpectrum[l] = g * y + crossfadeGain * x;
843 : }
844 : else
845 : {
846 10635687 : mdctSpectrum[l] = g * y - crossfadeGain * x;
847 : }
848 : }
849 :
850 22572197 : for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
851 : {
852 22478576 : mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
853 : }
854 : }
855 : }
856 :
857 923918 : *pSeed = rnd;
858 :
859 923918 : pop_wmops();
860 :
861 923918 : return;
862 : }
863 :
864 :
865 127020 : 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 127020 : if ( hTonalMDCTConc->lastBlockData.blockIsValid & hTonalMDCTConc->secondLastBlockData.blockIsValid )
878 : {
879 127020 : assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
880 :
881 127020 : nSamples = hTonalMDCTConc->nNonZeroSamples;
882 127020 : assert( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] < nSamples );
883 127020 : mvr2r( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples ); /* Convert from 16 bits to 32 bits */
884 127020 : if ( psychParamsCurrent == NULL )
885 : {
886 33570 : nBands = FDNS_NPTS;
887 33570 : mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors, nBands );
888 : }
889 : else
890 : {
891 93450 : sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore );
892 93450 : nBands = psychParamsCurrent->nBands;
893 : }
894 :
895 127020 : v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, nSamples - hTonalMDCTConc->nSamplesCore );
896 :
897 127020 : phaseDiff = hTonalMDCTConc->pTCI->phaseDiff; /* if multiple frame loss occurs use the phase from the last frame and continue rotating */
898 127020 : pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
899 :
900 127020 : if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
901 : {
902 52373 : if ( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
903 : {
904 3786 : hTonalMDCTConc->nFramesLost += 1;
905 : }
906 : else
907 : {
908 48587 : hTonalMDCTConc->nFramesLost = 1.5;
909 : }
910 : }
911 :
912 : /* for each index group */
913 691470 : for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
914 : {
915 564450 : phaseToAdd = hTonalMDCTConc->nFramesLost * phaseDiff[i];
916 :
917 : /* Move phaseToAdd to range -EVS_PI..EVS_PI */
918 7706441 : while ( phaseToAdd > EVS_PI )
919 : {
920 7141991 : phaseToAdd -= PI2;
921 : }
922 :
923 564450 : while ( phaseToAdd < -EVS_PI )
924 : {
925 : /* should never occur in flt - kept for safety reasons */
926 0 : phaseToAdd += PI2;
927 : }
928 :
929 4509661 : for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
930 : {
931 3945211 : const float currentPhase = ( *pCurrentPhase++ ) + phaseToAdd; /* *pCurrentPhase and phaseToAdd are in range -EVS_PI..EVS_PI */
932 3945211 : mdctSpectrum[l] = (float) cos( currentPhase ) * powerSpectrum[l];
933 : }
934 : }
935 : }
936 :
937 127020 : hTonalMDCTConc->nFramesLost++;
938 :
939 127020 : return;
940 : }
941 :
942 :
943 35612754 : void TonalMDCTConceal_SaveTimeSignal(
944 : TonalMDCTConcealPtr hTonalMDCTConc,
945 : float *timeSignal,
946 : const int16_t nNewSamples )
947 : {
948 35612754 : if ( nNewSamples == hTonalMDCTConc->nSamples )
949 : {
950 34953501 : assert( nNewSamples <= L_FRAME_MAX );
951 :
952 34953501 : if ( !hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
953 : {
954 34902138 : mvr2r( hTonalMDCTConc->lastPcmOut + hTonalMDCTConc->nSamples / 2, hTonalMDCTConc->secondLastPcmOut, hTonalMDCTConc->nSamples / 2 );
955 : }
956 :
957 34953501 : mvr2r( timeSignal, hTonalMDCTConc->lastPcmOut, hTonalMDCTConc->nSamples );
958 : }
959 :
960 35612754 : return;
961 : }
962 :
963 286860 : 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 286860 : push_wmops( "create_conc_noise" );
987 :
988 286860 : hStereoMdct = hCPE->hStereoMdct;
989 286860 : st = hCPE->hCoreCoder[idchan];
990 286860 : hTonalMDCTConc = st->hTonalMDCTConc;
991 286860 : hFdCngCom = st->hFdCngDec->hFdCngCom;
992 286860 : rnd = &hStereoMdct->noise_seeds_channels[idchan];
993 286860 : rnd_c = &hStereoMdct->noise_seed_common;
994 :
995 : /* determine start bin for IGF */
996 286860 : if ( st->igf == 0 )
997 : {
998 97881 : if ( st->narrowBand == 0 )
999 : {
1000 : /* minimum needed for output with sampling rates lower then the
1001 : nominal sampling rate */
1002 97881 : crossOverFreq = min( L_frameTCX, L_frame );
1003 : }
1004 : else
1005 : {
1006 0 : crossOverFreq = L_frameTCX;
1007 : }
1008 : }
1009 : else
1010 : {
1011 188979 : 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 286860 : max_noise_line = crossOverFreq;
1016 286860 : if ( st->tonal_mdct_plc_active )
1017 : {
1018 33399 : 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 286860 : if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
1023 : {
1024 142608 : *rnd = 1977 + idchan;
1025 : /* will be set twice when looping over two channels, but does not matter */
1026 142608 : *rnd_c = 1979;
1027 : }
1028 :
1029 286860 : 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 55400250 : for ( i = 0; i < max_noise_line; i++ )
1033 : {
1034 55257642 : *rnd = own_random( rnd );
1035 55257642 : concealment_noise[i] = *rnd;
1036 : }
1037 :
1038 142608 : pop_wmops();
1039 :
1040 142608 : return;
1041 : }
1042 :
1043 144252 : save_rnd_c = *rnd_c;
1044 :
1045 144252 : c = sqrtf( hStereoMdct->lastCoh );
1046 144252 : c_inv = sqrtf( 1 - hStereoMdct->lastCoh );
1047 :
1048 : /* pre-compute the noise shape for later weighting of the noise spectra */
1049 144252 : cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0];
1050 144252 : inc = ( st->core > TCX_20_CORE ) ? 2 : 1;
1051 144252 : start_idx = hFdCngCom->startBand / inc;
1052 144252 : stop_idx = hFdCngCom->stopFFTbin / inc;
1053 :
1054 425532 : for ( i = 0; i < start_idx; i++ )
1055 : {
1056 281280 : noise_shape_buffer[i] = 0.0f;
1057 : }
1058 44867772 : for ( ; i < stop_idx; i++, cngNoiseLevelPtr += inc )
1059 : {
1060 44723520 : noise_shape_buffer[i] = sqrtf( *( cngNoiseLevelPtr ) );
1061 : }
1062 :
1063 144252 : last_scf = sqrtf( *( cngNoiseLevelPtr - inc ) );
1064 :
1065 9346701 : for ( ; i < max_noise_line; i++ )
1066 : {
1067 9202449 : noise_shape_buffer[i] = last_scf;
1068 : }
1069 :
1070 : /* fill the noise vector */
1071 144252 : hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG;
1072 144252 : 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 54132726 : for ( i = 0; i < max_noise_line; i++ )
1076 : {
1077 53989089 : *rnd = own_random( rnd );
1078 53989089 : *rnd_c = own_random( rnd_c );
1079 :
1080 53989089 : concealment_noise[i] = ( c_inv * *rnd + c * *rnd_c ) * noise_shape_buffer[i];
1081 53989089 : 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 144252 : if ( st->tonal_mdct_plc_active )
1100 : {
1101 289011 : for ( i = crossOverFreq; i < max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i )
1102 : {
1103 270399 : 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 144252 : if ( ( idchan == 0 && ( core == TCX_20 || ( core == TCX_10 && subframe_idx == 1 ) ) ) || ( core == TCX_10 && subframe_idx == 0 ) )
1111 : {
1112 71712 : *rnd_c = save_rnd_c;
1113 : }
1114 :
1115 144252 : st->seed_tcx_plc = *rnd;
1116 :
1117 144252 : pop_wmops();
1118 :
1119 144252 : return;
1120 : }
1121 :
1122 228261 : 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 228261 : push_wmops( "apply_sns_on_noise_shape" );
1135 :
1136 228261 : scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0];
1137 228261 : psychParams = st->hTonalMDCTConc->psychParams;
1138 228261 : hFdCngCom = st->hFdCngDec->hFdCngCom;
1139 :
1140 228261 : inc = ( ( whitening_mode == ON_FIRST_LOST_FRAME ? st->core : st->last_core ) > TCX_20_CORE ) ? 2 : 1;
1141 228261 : start_idx = hFdCngCom->startBand / inc;
1142 228261 : stop_idx = L_frame / inc;
1143 228261 : noiseLevelPtr = hFdCngCom->cngNoiseLevel;
1144 :
1145 228261 : set_zero( whitenend_noise_shape, start_idx );
1146 71885109 : for ( int16_t j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc )
1147 : {
1148 71656848 : whitenend_noise_shape[j] = *noiseLevelPtr;
1149 : }
1150 :
1151 228261 : if ( whitening_mode == ON_FIRST_LOST_FRAME )
1152 : {
1153 : float scf[SNS_NPTS];
1154 :
1155 91866 : sns_compute_scf( whitenend_noise_shape, psychParams, L_frame, scf );
1156 91866 : sns_interpolate_scalefactors( scfs_int, scf, ENC );
1157 91866 : sns_interpolate_scalefactors( scfs_bg, scf, DEC );
1158 91866 : scfs_for_shaping = &scfs_int[0];
1159 : }
1160 : else /* whitening_mode == ON_FIRST_GOOD_FRAME */
1161 : {
1162 136395 : scfs_for_shaping = &scfs_bg[0];
1163 : }
1164 :
1165 228261 : if ( sum_f( scfs_for_shaping, FDNS_NPTS ) > 0.0f )
1166 : {
1167 182466 : sns_shape_spectrum( whitenend_noise_shape, psychParams, scfs_for_shaping, L_frame );
1168 182466 : mvr2r( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, stop_idx - start_idx );
1169 : }
1170 : else
1171 : {
1172 45795 : set_zero( hFdCngCom->cngNoiseLevel, stop_idx - start_idx );
1173 : }
1174 :
1175 228261 : pop_wmops();
1176 228261 : }
|