Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #define _USE_MATH_DEFINES
6 :
7 : #include <assert.h>
8 : #include <stdint.h>
9 : #include <math.h>
10 : #include "options.h"
11 : #include "basop_util.h"
12 : #include "options.h"
13 : #include "typedef.h"
14 : #include "cnst.h"
15 : #include "prot_fx.h"
16 : #include "stat_com.h"
17 : #include "ivas_prot_fx.h"
18 :
19 : #define CROSSFADE_THRESHOLD ( 32762 ) // close to 1.0f in Q15 such that (x == 1.0f) is true
20 :
21 : /************************************************************************************
22 : * local functions
23 : ************************************************************************************/
24 :
25 : static void CalcMDXT( const TonalMDCTConcealPtr hTonalMDCTConc, const Word16 type, const Word16 *timeSignal, Word32 *mdxtOutput, Word16 *mdxtOutput_e );
26 : static void CalcPowerSpec( const Word32 *mdctSpec, const Word16 mdctSpec_exp, const Word32 *mdstSpec, const Word16 mdstSpec_exp, const Word16 nSamples, const Word16 floorPowerSpectrum, Word32 *powerSpec, Word16 *powerSpec_exp );
27 : static void CalcPowerSpecAndDetectTonalComponents( TonalMDCTConcealPtr const hTonalMDCTConc, Word32 secondLastMDST[], Word16 secondLastMDST_exp, Word32 secondLastMDCT[], Word16 secondLastMDCT_exp, Word32 const pitchLag, Word16 element_mode );
28 : static void FindPhases( TonalMDCTConcealPtr const hTonalMDCTConc, Word32 secondLastMDCT[], Word32 secondLastMDST[], Word16 diff_exp );
29 : static void FindPhaseDifferences( TonalMDCTConcealPtr const hTonalMDCTConc, Word32 powerSpectrum[] );
30 :
31 :
32 : /*******************************************************/
33 : /*-------------- public functions -------------------- */
34 : /*******************************************************/
35 :
36 38 : ivas_error TonalMDCTConceal_Init(
37 : TonalMDCTConcealPtr hTonalMDCTConc,
38 : const Word16 nSamples,
39 : const Word16 nSamplesCore,
40 : const Word16 nScaleFactors,
41 : TCX_CONFIG_HANDLE hTcxCfg /* TCX config */
42 : )
43 : {
44 38 : test();
45 38 : IF( GT_16( nSamples, L_FRAME_MAX ) || GT_16( nScaleFactors, FDNS_NPTS ) )
46 : {
47 0 : assert( nSamples <= L_FRAME_MAX );
48 0 : assert( nScaleFactors <= FDNS_NPTS );
49 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "TonalMDCT FEC: Number of samples larger than max. block size\n" ) );
50 : }
51 38 : assert( ( hTonalMDCTConc->nScaleFactors == nScaleFactors ) || ( hTonalMDCTConc->nSamples != nSamples ) ); /* If nSamples doesn't change then also nScaleFactors must stay the same */
52 :
53 38 : hTonalMDCTConc->tcx_cfg = hTcxCfg;
54 :
55 38 : hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
56 38 : move16();
57 38 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
58 38 : move16();
59 38 : hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
60 38 : move16();
61 :
62 38 : hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
63 38 : move16();
64 38 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
65 38 : move16();
66 38 : hTonalMDCTConc->lastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[0];
67 38 : move16();
68 38 : hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[1];
69 38 : move16();
70 :
71 38 : hTonalMDCTConc->lastBlockData.blockIsValid = 0;
72 38 : move16();
73 38 : hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
74 38 : move16();
75 38 : hTonalMDCTConc->nSamples = 0;
76 38 : move16();
77 38 : hTonalMDCTConc->nScaleFactors = 0;
78 38 : move16();
79 :
80 38 : hTonalMDCTConc->lastBlockData.blockIsConcealed = 0;
81 38 : move16();
82 38 : hTonalMDCTConc->secondLastBlockData.blockIsConcealed = 0;
83 38 : move16();
84 :
85 38 : hTonalMDCTConc->pTCI = (TonalComponentsInfo *) hTonalMDCTConc->timeDataBuffer;
86 38 : move16();
87 :
88 :
89 38 : hTonalMDCTConc->lastPitchLag = L_deposit_l( 0 );
90 :
91 38 : IF( NE_16( hTonalMDCTConc->nSamples, nSamples ) )
92 : {
93 38 : hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
94 38 : move16();
95 38 : hTonalMDCTConc->lastBlockData.blockIsValid = 0;
96 38 : move16();
97 : }
98 :
99 38 : hTonalMDCTConc->nSamples = nSamples;
100 38 : move16();
101 38 : hTonalMDCTConc->nSamplesCore = nSamplesCore;
102 38 : move16();
103 :
104 38 : hTonalMDCTConc->nScaleFactors = nScaleFactors;
105 38 : move16();
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 38 : move16();
109 38 : move16();
110 : /* just the second half of the second last pcm output is needed */
111 38 : hTonalMDCTConc->secondLastPcmOut = &hTonalMDCTConc->timeDataBuffer[sub( ( 3 * L_FRAME_MAX ) / 2, 3 * ( s_min( L_FRAME_MAX, nSamples ) ) / 2 )];
112 38 : hTonalMDCTConc->lastPcmOut = &hTonalMDCTConc->timeDataBuffer[sub( ( 3 * L_FRAME_MAX ) / 2, s_min( L_FRAME_MAX, nSamples ) )];
113 :
114 : /* If the second last frame was lost, we reuse saved TonalComponentsInfo and don't update pcm buffers */
115 38 : assert( sizeof( *hTonalMDCTConc->pTCI ) <= ( hTonalMDCTConc->lastPcmOut - hTonalMDCTConc->timeDataBuffer ) * sizeof( hTonalMDCTConc->timeDataBuffer[0] ) );
116 :
117 38 : return IVAS_ERR_OK;
118 : }
119 14781 : ivas_error TonalMDCTConceal_Init_ivas_fx(
120 : TonalMDCTConcealPtr hTonalMDCTConc,
121 : const UWord16 nSamples,
122 : const UWord16 nSamplesCore,
123 : const UWord16 nScaleFactors,
124 : TCX_CONFIG_HANDLE hTcxCfg )
125 : {
126 14781 : test();
127 14781 : IF( GT_16( nSamples, L_FRAME_MAX ) || GT_16( nScaleFactors, FDNS_NPTS ) )
128 : {
129 0 : assert( LE_16( nSamples, L_FRAME_MAX ) );
130 0 : assert( LE_16( nScaleFactors, FDNS_NPTS ) );
131 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "TonalMDCT FEC: Number of samples larger than max. block size\n" ) );
132 : }
133 14781 : assert( EQ_16( hTonalMDCTConc->nScaleFactors, nScaleFactors ) || NE_16( hTonalMDCTConc->nSamples, nSamples ) ); /* If nSamples doesn't change then also nScaleFactors must stay the same */
134 :
135 14781 : hTonalMDCTConc->tcx_cfg = hTcxCfg;
136 14781 : hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
137 14781 : set16_fx( hTonalMDCTConc->lastBlockData.spectralData, 0, L_FRAME_MAX );
138 14781 : move16();
139 14781 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
140 14781 : set16_fx( hTonalMDCTConc->secondLastBlockData.spectralData, 0, L_FRAME_MAX );
141 14781 : move16();
142 14781 : hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
143 14781 : move16();
144 14781 : hTonalMDCTConc->secondLastPowerSpectrum_exp = hTonalMDCTConc->secondLastBlockData.spectralData_exp;
145 14781 : move16();
146 14781 : hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
147 14781 : set16_fx( hTonalMDCTConc->lastBlockData.scaleFactors, 0, FDNS_NPTS );
148 14781 : move16();
149 14781 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
150 14781 : set16_fx( hTonalMDCTConc->secondLastBlockData.scaleFactors, 0, FDNS_NPTS );
151 14781 : move16();
152 14781 : hTonalMDCTConc->lastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[0];
153 14781 : move16();
154 14781 : hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[1];
155 14781 : move16();
156 :
157 14781 : hTonalMDCTConc->lastBlockData.blockIsValid = 0;
158 14781 : move16();
159 14781 : hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
160 14781 : move16();
161 14781 : hTonalMDCTConc->nSamples = 0;
162 14781 : move16();
163 14781 : hTonalMDCTConc->nScaleFactors = 0;
164 14781 : move16();
165 :
166 14781 : hTonalMDCTConc->lastBlockData.blockIsConcealed = 0;
167 14781 : move16();
168 14781 : hTonalMDCTConc->secondLastBlockData.blockIsConcealed = 0;
169 14781 : move16();
170 14781 : hTonalMDCTConc->pTCI = (TonalComponentsInfo *) hTonalMDCTConc->timeDataBuffer;
171 :
172 14781 : move16();
173 14781 : hTonalMDCTConc->lastPitchLag = L_deposit_l( 0 );
174 :
175 14781 : IF( NE_16( hTonalMDCTConc->nSamples, nSamples ) )
176 : {
177 14781 : hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
178 14781 : move16();
179 14781 : hTonalMDCTConc->lastBlockData.blockIsValid = 0;
180 14781 : move16();
181 : }
182 14781 : hTonalMDCTConc->nSamples = nSamples;
183 14781 : move16();
184 14781 : hTonalMDCTConc->nSamplesCore = nSamplesCore;
185 14781 : move16();
186 14781 : hTonalMDCTConc->nScaleFactors = nScaleFactors;
187 14781 : move16();
188 :
189 14781 : set32_fx( hTonalMDCTConc->scaleFactorsBackground_fx, 0, FDNS_NPTS );
190 14781 : hTonalMDCTConc->scf_fadeout = 16384 /*1.000000 Q14*/;
191 14781 : PsychoacousticParameters_Init_fx( INT_FS_16k, L_FRAME16k, 64, 1, 1, &hTonalMDCTConc->psychParamsTCX20 );
192 14781 : PsychoacousticParameters_Init_fx( INT_FS_16k, L_FRAME16k / 2, 64, 0, 1, &hTonalMDCTConc->psychParamsTCX10 );
193 14781 : hTonalMDCTConc->psychParams = NULL;
194 :
195 14781 : hTonalMDCTConc->last_block_nrg = 0;
196 14781 : move16();
197 14781 : hTonalMDCTConc->last_block_nrg_exp = 0;
198 14781 : move16();
199 14781 : hTonalMDCTConc->curr_noise_nrg = 0;
200 14781 : move16();
201 14781 : hTonalMDCTConc->curr_noise_nrg_exp = 0;
202 14781 : move16();
203 14781 : hTonalMDCTConc->faded_signal_nrg = 0;
204 14781 : move16();
205 14781 : hTonalMDCTConc->faded_signal_nrg_exp = 0;
206 14781 : move16();
207 :
208 : /* Offset the pointer to the end of buffer, so that pTCI is not destroyed when
209 : new time samples are stored in lastPcmOut */
210 14781 : move16();
211 14781 : move16();
212 : /* just the second half of the second last pcm output is needed */
213 :
214 14781 : set16_fx( hTonalMDCTConc->timeDataBuffer, 0, ( 3 * L_FRAME_MAX ) / 2 );
215 14781 : hTonalMDCTConc->secondLastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - ( 3 * min( L_FRAME_MAX, nSamples ) / 2 )];
216 14781 : hTonalMDCTConc->lastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - min( L_FRAME_MAX, nSamples )];
217 : /* If the second last frame was lost, we reuse saved TonalComponentsInfo and don't update pcm buffers */
218 14781 : assert( sizeof( *hTonalMDCTConc->pTCI ) <= ( hTonalMDCTConc->lastPcmOut - hTonalMDCTConc->timeDataBuffer ) * sizeof( hTonalMDCTConc->timeDataBuffer[0] ) );
219 :
220 14781 : return IVAS_ERR_OK;
221 : }
222 634 : void TonalMDCTConceal_SaveFreqSignal(
223 : TonalMDCTConcealPtr hTonalMDCTConc,
224 : const Word32 *mdctSpectrum, // Q31-mdctSpectrum_exp
225 : const Word16 mdctSpectrum_exp,
226 : Word16 nNewSamples, // Q0
227 : Word16 nNewSamplesCore, // Q0
228 : const Word16 *scaleFactors, // Q31-scaleFactors_exp
229 : const Word16 *scaleFactors_exp,
230 : const Word16 gain_tcx_exp )
231 : {
232 : Word16 *temp;
233 : Word16 nOldSamples, tmp_exp, s, i, max_exp;
234 :
235 :
236 634 : assert( nNewSamples > 0 && nNewSamples <= 2 * L_FRAME_MAX );
237 :
238 : /* Avoid overwriting hTonalMDCTConc->secondLastPowerSpectrum stored in spectralData,
239 : because it is needed if the second last and the current frame are lost
240 : and concealed using the Tonal MDCT PLC */
241 634 : test();
242 634 : IF( !hTonalMDCTConc->lastBlockData.tonalConcealmentActive || NE_16( hTonalMDCTConc->lastBlockData.nSamples, nNewSamples ) )
243 : {
244 634 : IF( LE_16( nNewSamples, L_FRAME_MAX ) )
245 : {
246 : /* Shift the buffers */
247 611 : temp = hTonalMDCTConc->secondLastBlockData.spectralData; /* Save the pointer */
248 611 : move16();
249 611 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->lastBlockData.spectralData;
250 611 : move16();
251 611 : hTonalMDCTConc->lastBlockData.spectralData = temp;
252 611 : move16();
253 :
254 611 : tmp_exp = hTonalMDCTConc->secondLastBlockData.spectralData_exp; /* Save the pointer */
255 611 : move16();
256 611 : hTonalMDCTConc->secondLastBlockData.spectralData_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
257 611 : move16();
258 611 : hTonalMDCTConc->lastBlockData.spectralData_exp = tmp_exp;
259 611 : move16();
260 :
261 611 : tmp_exp = hTonalMDCTConc->secondLastBlockData.gain_tcx_exp; /* Save the pointer */
262 611 : move16();
263 611 : hTonalMDCTConc->secondLastBlockData.gain_tcx_exp = hTonalMDCTConc->lastBlockData.gain_tcx_exp;
264 611 : move16();
265 611 : hTonalMDCTConc->lastBlockData.gain_tcx_exp = tmp_exp;
266 611 : move16();
267 :
268 611 : tmp_exp = hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e; /* Save the pointer */
269 611 : move16();
270 611 : hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e = hTonalMDCTConc->lastBlockData.scaleFactors_max_e;
271 611 : move16();
272 611 : hTonalMDCTConc->lastBlockData.scaleFactors_max_e = tmp_exp;
273 611 : move16();
274 :
275 611 : temp = hTonalMDCTConc->secondLastBlockData.scaleFactors;
276 611 : move16();
277 611 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->lastBlockData.scaleFactors;
278 611 : move16();
279 611 : hTonalMDCTConc->lastBlockData.scaleFactors = temp;
280 611 : move16();
281 :
282 611 : temp = hTonalMDCTConc->secondLastBlockData.scaleFactors_exp;
283 611 : move16();
284 611 : hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->lastBlockData.scaleFactors_exp;
285 611 : move16();
286 611 : hTonalMDCTConc->lastBlockData.scaleFactors_exp = temp;
287 611 : move16();
288 : }
289 : ELSE
290 : {
291 23 : hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
292 23 : move16();
293 23 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
294 23 : move16();
295 23 : hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
296 23 : move16();
297 23 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
298 23 : move16();
299 23 : hTonalMDCTConc->lastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[0];
300 23 : move16();
301 23 : hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[1];
302 23 : move16();
303 : }
304 :
305 634 : nOldSamples = hTonalMDCTConc->lastBlockData.nSamples;
306 634 : move16();
307 634 : hTonalMDCTConc->lastBlockData.nSamples = nNewSamples;
308 634 : move16();
309 634 : hTonalMDCTConc->secondLastBlockData.nSamples = nOldSamples;
310 634 : move16();
311 :
312 634 : nOldSamples = hTonalMDCTConc->lastBlockData.nSamplesCore;
313 634 : move16();
314 634 : hTonalMDCTConc->lastBlockData.nSamplesCore = nNewSamplesCore;
315 634 : move16();
316 634 : hTonalMDCTConc->secondLastBlockData.nSamplesCore = nOldSamples;
317 634 : move16();
318 : }
319 :
320 634 : test();
321 634 : IF( ( nNewSamples > 0 ) && ( LE_16( nNewSamples, 2 * L_FRAME_MAX ) ) )
322 : {
323 : /* Store new data */
324 634 : s = getScaleFactor32( mdctSpectrum, nNewSamples );
325 :
326 : /*Copy(scaleFactors_exp, hTonalMDCTConc->lastBlockData.scaleFactors_exp, hTonalMDCTConc->nScaleFactors);*/
327 634 : max_exp = 0;
328 41210 : FOR( i = 0; i < hTonalMDCTConc->nScaleFactors; i++ )
329 : {
330 40576 : hTonalMDCTConc->lastBlockData.scaleFactors_exp[i] = scaleFactors_exp[i];
331 40576 : move16();
332 40576 : max_exp = s_max( max_exp, scaleFactors_exp[i] );
333 : }
334 :
335 : /*s = sub(s, max_exp);*/
336 634 : hTonalMDCTConc->lastBlockData.scaleFactors_max_e = max_exp;
337 :
338 533354 : FOR( i = 0; i < nNewSamples; i++ )
339 : {
340 532720 : hTonalMDCTConc->lastBlockData.spectralData[i] = extract_h( L_shl( mdctSpectrum[i], s ) ); // Q31-(mdctSpectrum_exp-s)
341 532720 : move16();
342 : }
343 634 : hTonalMDCTConc->lastBlockData.spectralData_exp = sub( mdctSpectrum_exp, s );
344 634 : move16();
345 634 : hTonalMDCTConc->lastBlockData.gain_tcx_exp = gain_tcx_exp;
346 :
347 634 : Copy( scaleFactors, hTonalMDCTConc->lastBlockData.scaleFactors, hTonalMDCTConc->nScaleFactors );
348 : }
349 634 : return;
350 : }
351 :
352 829697 : void TonalMDCTConceal_SaveFreqSignal_ivas_fx(
353 : TonalMDCTConcealPtr hTonalMDCTConc,
354 : const Word32 *mdctSpectrum, // Q31-mdctSpectrum_exp
355 : const Word16 mdctSpectrum_exp, // Q0
356 : const Word16 nNewSamples, // Q0
357 : const Word16 nNewSamplesCore, // Q0
358 : const Word16 *scaleFactors, // Q15 - *scaleFactors_exp
359 : const Word16 *scaleFactors_exp, // Q0
360 : const Word16 gain_tcx_exp, // Q0
361 : const Word16 infoIGFStartLine ) // Q0
362 : {
363 : Word16 *temp;
364 : Word16 nOldSamples, temp_exp, s, i, max_exp;
365 :
366 829697 : assert( nNewSamples > 0 && nNewSamples <= 2 * L_FRAME_MAX );
367 :
368 : /* Avoid overwriting hTonalMDCTConc->secondLastPowerSpectrum stored in spectralData,
369 : because it is needed if the second last and the current frame are lost
370 : and concealed using the Tonal MDCT PLC */
371 829697 : test();
372 829697 : IF( !hTonalMDCTConc->lastBlockData.tonalConcealmentActive || NE_16( hTonalMDCTConc->lastBlockData.nSamples, nNewSamples ) )
373 : {
374 829335 : IF( LE_16( nNewSamples, L_FRAME_MAX ) )
375 : {
376 : /* Shift the buffers */
377 823204 : temp = hTonalMDCTConc->secondLastBlockData.spectralData; /* Save the pointer */
378 823204 : move16();
379 823204 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->lastBlockData.spectralData;
380 823204 : move16();
381 823204 : hTonalMDCTConc->lastBlockData.spectralData = temp;
382 823204 : move16();
383 :
384 823204 : temp_exp = hTonalMDCTConc->secondLastBlockData.spectralData_exp;
385 823204 : move16();
386 823204 : hTonalMDCTConc->secondLastBlockData.spectralData_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
387 823204 : move16();
388 823204 : hTonalMDCTConc->lastBlockData.spectralData_exp = temp_exp;
389 823204 : move16();
390 :
391 823204 : temp_exp = hTonalMDCTConc->secondLastBlockData.gain_tcx_exp; /* Save the pointer */
392 823204 : move16();
393 823204 : hTonalMDCTConc->secondLastBlockData.gain_tcx_exp = hTonalMDCTConc->lastBlockData.gain_tcx_exp;
394 823204 : move16();
395 823204 : hTonalMDCTConc->lastBlockData.gain_tcx_exp = temp_exp;
396 823204 : move16();
397 :
398 823204 : temp_exp = hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e; /* Save the pointer */
399 823204 : move16();
400 823204 : hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e = hTonalMDCTConc->lastBlockData.scaleFactors_max_e;
401 823204 : move16();
402 823204 : hTonalMDCTConc->lastBlockData.scaleFactors_max_e = temp_exp;
403 823204 : move16();
404 :
405 823204 : temp = hTonalMDCTConc->secondLastBlockData.scaleFactors;
406 823204 : move16();
407 823204 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->lastBlockData.scaleFactors;
408 823204 : move16();
409 823204 : hTonalMDCTConc->lastBlockData.scaleFactors = temp;
410 823204 : move16();
411 :
412 823204 : temp = hTonalMDCTConc->secondLastBlockData.scaleFactors_exp;
413 823204 : move16();
414 823204 : hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->lastBlockData.scaleFactors_exp;
415 823204 : move16();
416 823204 : hTonalMDCTConc->lastBlockData.scaleFactors_exp = temp;
417 823204 : move16();
418 : }
419 : ELSE
420 : {
421 : /* Order the buffers so that even transition frame can fit in if written into the first buffer */
422 6131 : hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
423 6131 : move16();
424 6131 : hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
425 6131 : move16();
426 6131 : hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
427 6131 : move16();
428 6131 : hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
429 6131 : move16();
430 6131 : hTonalMDCTConc->lastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[0];
431 6131 : move16();
432 6131 : hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[1];
433 6131 : move16();
434 : }
435 829335 : nOldSamples = hTonalMDCTConc->lastBlockData.nSamples;
436 829335 : move16();
437 829335 : hTonalMDCTConc->lastBlockData.nSamples = nNewSamples;
438 829335 : move16();
439 829335 : hTonalMDCTConc->secondLastBlockData.nSamples = nOldSamples;
440 829335 : move16();
441 829335 : nOldSamples = (Word16) hTonalMDCTConc->lastBlockData.nSamplesCore;
442 829335 : move16();
443 829335 : hTonalMDCTConc->lastBlockData.nSamplesCore = (UWord16) nNewSamplesCore;
444 829335 : move16();
445 829335 : hTonalMDCTConc->secondLastBlockData.nSamplesCore = (UWord16) nOldSamples;
446 829335 : move16();
447 : }
448 :
449 829697 : test();
450 829697 : IF( ( nNewSamples > 0 ) && ( LE_16( nNewSamples, 2 * L_FRAME_MAX ) ) )
451 : {
452 : /* Store new data */
453 829697 : Word64 W_tmp = 0;
454 829697 : move64();
455 396969097 : FOR( i = 0; i < infoIGFStartLine; i++ )
456 : {
457 396139400 : W_tmp = W_mac_32_16( W_tmp, Mpy_32_32( mdctSpectrum[i], mdctSpectrum[i] ), 1 ); // exp: mdctSpectrum_exp + mdctSpectrum_exp - 1
458 : }
459 829697 : s = W_norm( W_tmp );
460 829697 : hTonalMDCTConc->last_block_nrg = W_extract_h( W_shl( W_tmp, s ) ); // exp:add( sub( shl( mdctSpectrum_exp, 1 ), s ), 31 )
461 829697 : move32();
462 829697 : hTonalMDCTConc->last_block_nrg_exp = add( sub( shl( mdctSpectrum_exp, 1 ), s ), 31 );
463 829697 : move16();
464 :
465 : /* Store new data */
466 829697 : s = getScaleFactor32( mdctSpectrum, nNewSamples );
467 :
468 829697 : max_exp = 0;
469 829697 : move16();
470 53930305 : FOR( i = 0; i < hTonalMDCTConc->nScaleFactors; i++ )
471 : {
472 53100608 : hTonalMDCTConc->lastBlockData.scaleFactors_exp[i] = scaleFactors_exp[i];
473 53100608 : move16();
474 53100608 : max_exp = s_max( max_exp, scaleFactors_exp[i] );
475 : }
476 :
477 : /*s = sub(s, max_exp);*/
478 829697 : hTonalMDCTConc->lastBlockData.scaleFactors_max_e = max_exp;
479 829697 : move16();
480 :
481 691266337 : FOR( i = 0; i < nNewSamples; i++ )
482 : {
483 690436640 : Word16 tmp = 0;
484 690436640 : if ( mdctSpectrum[i] != 0 )
485 : {
486 494259497 : tmp = 1;
487 494259497 : move16();
488 : }
489 690436640 : hTonalMDCTConc->lastBlockData.spectralData[i] = extract_h( L_shl( mdctSpectrum[i], s ) ); // 31 - mdctSpectrum_exp +s -16 = 15-(mdctSpectrum_exp -s)
490 690436640 : move16();
491 :
492 690436640 : test();
493 690436640 : if ( hTonalMDCTConc->lastBlockData.spectralData[i] == 0 && EQ_16( tmp, 1 ) )
494 : {
495 4957617 : hTonalMDCTConc->lastBlockData.spectralData[i] = 1;
496 4957617 : move16();
497 : }
498 : }
499 829697 : hTonalMDCTConc->lastBlockData.spectralData_exp = sub( mdctSpectrum_exp, s );
500 829697 : move16();
501 :
502 829697 : hTonalMDCTConc->lastBlockData.gain_tcx_exp = gain_tcx_exp;
503 829697 : move16();
504 829697 : Copy( scaleFactors, hTonalMDCTConc->lastBlockData.scaleFactors, hTonalMDCTConc->nScaleFactors );
505 : }
506 :
507 829697 : return;
508 : }
509 :
510 :
511 919587 : void TonalMDCTConceal_UpdateState(
512 : TonalMDCTConcealPtr hTonalMDCTConc,
513 : Word16 nNewSamples, // Q0
514 : Word32 pitchLag, // Qx
515 : Word16 badBlock, // Q0
516 : Word8 tonalConcealmentActive )
517 : {
518 : Word8 newBlockIsValid;
519 :
520 919587 : assert( !( !badBlock && tonalConcealmentActive ) );
521 :
522 919587 : IF( badBlock )
523 : {
524 13206 : newBlockIsValid = (Word8) hTonalMDCTConc->lastBlockData.blockIsValid;
525 13206 : move16();
526 : }
527 : ELSE
528 : {
529 906381 : newBlockIsValid = 0;
530 906381 : move16();
531 906381 : test();
532 906381 : if ( ( LE_16( nNewSamples, 2 * L_FRAME_MAX ) ) && ( nNewSamples > 0 ) )
533 : {
534 900963 : newBlockIsValid = 1;
535 900963 : move16();
536 : }
537 : }
538 :
539 919587 : /* Shift old state */ move16();
540 919587 : move16();
541 919587 : move16();
542 919587 : hTonalMDCTConc->secondLastBlockData.blockIsConcealed = hTonalMDCTConc->lastBlockData.blockIsConcealed;
543 919587 : hTonalMDCTConc->secondLastBlockData.blockIsValid = hTonalMDCTConc->lastBlockData.blockIsValid;
544 919587 : hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive = hTonalMDCTConc->lastBlockData.tonalConcealmentActive;
545 :
546 919587 : /* Store new state */ move16();
547 919587 : move16();
548 919587 : move16();
549 919587 : hTonalMDCTConc->lastBlockData.blockIsConcealed = badBlock;
550 919587 : hTonalMDCTConc->lastBlockData.blockIsValid = newBlockIsValid;
551 919587 : hTonalMDCTConc->lastBlockData.tonalConcealmentActive = tonalConcealmentActive;
552 :
553 919587 : hTonalMDCTConc->lastPitchLag = pitchLag;
554 919587 : move32();
555 :
556 919587 : return;
557 : }
558 :
559 :
560 : /* o: currenc phase [-pi;pi] 2Q13 */
561 1598 : static void FindPhases(
562 : TonalMDCTConcealPtr const hTonalMDCTConc, /* i: pointer to internal structure */
563 : Word32 secondLastMDCT[], /* i: MDST spectrum data Qx +31 -diff_exp */
564 : Word32 secondLastMDST[], /* i: MDCT spectrum data Qx */
565 : Word16 diff_exp ) /* i: exp_MDST - exp_MDCT */
566 : {
567 : Word16 i;
568 : Word16 l;
569 : Word16 *pCurrentPhase;
570 :
571 :
572 1598 : pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
573 : /* for each index/index group */
574 4797 : FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
575 : {
576 25540 : FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
577 : {
578 : /* in contrast to the float code, the parameter secondLastMDST[l]
579 : needs not to be negated - due to a different implementation of
580 : the MDST */
581 22341 : *pCurrentPhase++ = BASOP_util_atan2( secondLastMDST[l], secondLastMDCT[l], diff_exp ); // Q13
582 22341 : move16();
583 : }
584 : }
585 :
586 1598 : return;
587 : }
588 :
589 : #define BANDWIDTH 7.0f
590 : #define G 789516047l /*1.0/(2*1.36) Q31*/
591 : #define MAXRATIO 22938 /*44.8f Q9*/ /* Maximum ratio |ODFT[k-1]|/|ODFT[k+1]| is 16.5 dB, that is maximum ratio (for fractional = 0) is (cos(PI/bandwidth)/cos(3PI/bandwidth))^1.36 */
592 : #define MM 1934815907 /* FL2WORD32(cos(EVS_PI/BANDWIDTH)); */
593 : #define SS 29166 /* FL2WORD16(cos((3*EVS_PI)/BANDWIDTH)*4); Q17*/
594 : #define N 931758243 /* FL2WORD32(sin(EVS_PI/BANDWIDTH)); */
595 : #define J 31946 /* FL2WORD16(sin((3*EVS_PI)/BANDWIDTH)); */
596 :
597 : /* o: Phase difference [-pi;pi] 2Q13*/
598 1598 : static void FindPhaseDifferences(
599 : TonalMDCTConcealPtr const hTonalMDCTConc, /* i: Pointer to internal structure */
600 : Word32 powerSpectrum[] ) /* i: Power spectrum data Qx */
601 : {
602 : Word16 i, k;
603 : Word16 *phaseDiff;
604 : Word16 fractional, sf, sfn, sfd;
605 : Word16 divi, s, j;
606 : Word32 a, Q, L_tmp, m, n;
607 :
608 1598 : s = SS;
609 1598 : move16();
610 1598 : j = J;
611 1598 : move16();
612 :
613 1598 : phaseDiff = hTonalMDCTConc->pTCI->phaseDiff;
614 :
615 4797 : FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
616 : {
617 3199 : m = MM;
618 3199 : move16();
619 3199 : n = N;
620 3199 : move16();
621 :
622 3199 : k = hTonalMDCTConc->pTCI->indexOfTonalPeak[i];
623 3199 : move16();
624 :
625 3199 : IF( GE_32( Mpy_32_16_1( powerSpectrum[k - 1], 512 /*1.0f Q9*/ ), Mpy_32_16_1( powerSpectrum[k + 1], MAXRATIO ) ) )
626 : {
627 15 : phaseDiff[i] = 0; /*(float)tan(0.0f*EVS_PI/bandwidth);*/
628 15 : move16();
629 15 : if ( s_and( k, 1 ) != 0 )
630 : {
631 6 : phaseDiff[i] = -12868 /*-EVS_PI 3Q12*/;
632 6 : move16();
633 : }
634 : }
635 : ELSE
636 : {
637 3184 : IF( GE_32( Mpy_32_16_1( powerSpectrum[k + 1], 512 /*1.0f Q9*/ ), Mpy_32_16_1( powerSpectrum[k - 1], MAXRATIO ) ) )
638 : {
639 33 : phaseDiff[i] = 12868 /*EVS_PI 3Q12*/; /*(float)tan(2.0f*PI/bandwidth);*/
640 33 : move16();
641 33 : if ( s_and( k, 1 ) != 0 )
642 : {
643 15 : phaseDiff[i] = 0 /*0 Q13*/; /*2Q13*/
644 15 : move16();
645 : }
646 : }
647 : ELSE
648 : {
649 : /*Q = (float)pow(odft_left/odft_right, G);
650 : a = (m - Q * s) / (n + Q * j);
651 : phaseDiff[i] = (float)atan(a) * (bandwidth/2.0f);*/
652 : /*max divi=44.8 & sf=6*/
653 3151 : divi = BASOP_Util_Divide3232_uu_1616_Scale( powerSpectrum[k - 1], powerSpectrum[k + 1], &sf );
654 3151 : Q = BASOP_Util_fPow( L_deposit_h( divi ), sf, G, 0, &sf ); // Q31-sf
655 3151 : L_tmp = Mpy_32_16_1( Q, s );
656 3151 : sfn = sub( sf, 2 );
657 :
658 3151 : if ( sfn > 0 )
659 : {
660 120 : m = L_shr( m, sfn );
661 : }
662 3151 : IF( sfn < 0 )
663 : {
664 2343 : L_tmp = L_shl( L_tmp, sfn );
665 2343 : sfn = 0;
666 2343 : move16();
667 : }
668 :
669 3151 : a = L_sub( m, L_tmp ); /*sf*/
670 :
671 3151 : L_tmp = Mpy_32_16_1( Q, j );
672 3151 : IF( sf >= 0 )
673 : {
674 2989 : L_tmp = L_shr( L_tmp, 1 );
675 2989 : sfd = add( sf, 1 );
676 2989 : n = L_shr( n, sfd );
677 : }
678 : ELSE
679 : {
680 162 : sfd = 0;
681 162 : move16();
682 162 : L_tmp = L_shl( L_tmp, sf );
683 : }
684 :
685 3151 : L_tmp = L_add( n, L_tmp );
686 3151 : fractional = BASOP_util_atan2( a, L_tmp, sub( sfn, sfd ) ); /*2Q13*/
687 3151 : L_tmp = L_mult( fractional, 28672 /*BANDWIDTH/2.0f Q13*/ ); /*2Q13*2Q13=4Q27*/
688 :
689 : /* fractional is in the range 0..+pi */
690 : /* we need to stay in the range -2pi..+2pi */
691 3151 : if ( EQ_16( s_and( k, 3 ), 1 ) )
692 : {
693 710 : L_tmp = L_add( L_tmp, 421657440l /*+1*EVS_PI Q27*/ );
694 : }
695 3151 : if ( EQ_16( s_and( k, 3 ), 2 ) )
696 : {
697 765 : L_tmp = L_sub( L_tmp, 843314880l /*+2*EVS_PI=-2*EVS_PI Q27*/ );
698 : }
699 3151 : if ( EQ_16( s_and( k, 3 ), 3 ) )
700 : {
701 1087 : L_tmp = L_sub( L_tmp, 421657440l /*+3*EVS_PI=-1*EVS_PI Q27*/ );
702 : }
703 3151 : phaseDiff[i] = round_fx( L_shl( L_tmp, 1 ) ); /*3Q12*/
704 3151 : move16();
705 : }
706 : }
707 : }
708 1598 : }
709 :
710 1598 : static void ivas_CalcPowerSpecAndDetectTonalComponents_fx(
711 : TonalMDCTConcealPtr const hTonalMDCTConc,
712 : Word32 secondLastMDST[], // Q31 - secondLastMDST_exp
713 : Word16 secondLastMDST_exp,
714 : Word32 secondLastMDCT[], // Q31 - secondLastMDCT_exp
715 : Word16 secondLastMDCT_exp,
716 : Word32 const pitchLag, /*15Q16*/
717 : const PsychoacousticParameters *psychParamsCurrent,
718 : Word16 element_mode )
719 : {
720 : Word16 nSamples;
721 : Word16 i;
722 : Word16 floorPowerSpectrum; /* Minimum significant value of a spectral line in the power spectrum */
723 : Word32 powerSpectrum[L_FRAME_MAX];
724 : Word16 invScaleFactors[FDNS_NPTS];
725 : Word16 invScaleFactors_exp[FDNS_NPTS];
726 : Word16 powerSpectrum_exp, tmp_exp, old_exp;
727 :
728 : Word16 nBands;
729 : Word32 invScaleFactors_fx[FDNS_NPTS];
730 : Word16 old_power_spectrum_q, power_spectrum_q;
731 :
732 1598 : set32_fx( powerSpectrum, 0, L_FRAME_MAX );
733 :
734 1598 : nSamples = hTonalMDCTConc->nNonZeroSamples;
735 1598 : move16();
736 :
737 : /* It is taken into account that the MDCT is not normalized. */
738 1598 : floorPowerSpectrum /*Q0*/ = extract_l( Mpy_32_32( L_mult0( hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamples ), 5368709 ) ); /*1/400 = 5368709 Q31*/
739 1598 : powerSpectrum_exp = 0;
740 1598 : move16();
741 :
742 1598 : CalcPowerSpec( secondLastMDCT,
743 : secondLastMDCT_exp,
744 : secondLastMDST,
745 : secondLastMDST_exp,
746 : nSamples,
747 : floorPowerSpectrum,
748 : powerSpectrum,
749 : &powerSpectrum_exp );
750 :
751 : /* This setting to minimal level is required because the power spectrum is used in the threshold adaptation using the pitch up to hTonalMDCTConc->nSamples. */
752 1598 : set32_fx( powerSpectrum + nSamples, floorPowerSpectrum, sub( hTonalMDCTConc->nSamples, nSamples ) );
753 : /* this setting to zero is needed since the FDNS needs to be called
754 : with hTonalMDCTConc->nSamplesCore; it relevant only for nb; it has no effect
755 : to the output, but memory checker may complain otherwise due to the
756 : usage of uninitialized values */
757 1598 : IF( GT_16( hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples ) )
758 : {
759 61 : set32_fx( powerSpectrum + hTonalMDCTConc->nSamples, 0, sub( hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples ) );
760 : }
761 :
762 1598 : ivas_DetectTonalComponents_fx( (Word16 *) hTonalMDCTConc->pTCI->indexOfTonalPeak,
763 1598 : (Word16 *) hTonalMDCTConc->pTCI->lowerIndex,
764 1598 : (Word16 *) hTonalMDCTConc->pTCI->upperIndex,
765 1598 : (Word16 *) &hTonalMDCTConc->pTCI->numIndexes,
766 : hTonalMDCTConc->lastPitchLag,
767 : pitchLag,
768 1598 : hTonalMDCTConc->lastBlockData.spectralData,
769 1598 : hTonalMDCTConc->lastBlockData.spectralData_exp,
770 1598 : hTonalMDCTConc->lastBlockData.scaleFactors,
771 1598 : hTonalMDCTConc->lastBlockData.scaleFactors_exp,
772 1598 : hTonalMDCTConc->lastBlockData.scaleFactors_max_e,
773 : powerSpectrum,
774 : powerSpectrum_exp,
775 : nSamples,
776 1598 : hTonalMDCTConc->nSamplesCore,
777 : floorPowerSpectrum, psychParamsCurrent, element_mode );
778 1598 : FindPhases( hTonalMDCTConc, secondLastMDCT, secondLastMDST, sub( secondLastMDST_exp, secondLastMDCT_exp ) );
779 :
780 1598 : FindPhaseDifferences( hTonalMDCTConc, powerSpectrum );
781 :
782 1598 : IF( hTonalMDCTConc->pTCI->numIndexes > 0 )
783 : {
784 608 : hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
785 :
786 : /*sqrtFLOAT(powerSpectrum, powerSpectrum, nSamples);*/
787 608 : old_exp = powerSpectrum_exp;
788 608 : move16();
789 608 : powerSpectrum_exp = mult_r( sub( powerSpectrum_exp, 2 ), ( 1 << 14 ) ); /*remove 2 bits of headroom from CalcPowerSpec*/
790 339133 : FOR( i = 0; i < nSamples; i++ )
791 : {
792 338525 : tmp_exp = old_exp;
793 338525 : move16();
794 338525 : powerSpectrum[i] = Sqrt32( powerSpectrum[i], &tmp_exp );
795 338525 : move32();
796 338525 : powerSpectrum[i] = L_shr( powerSpectrum[i], sub( powerSpectrum_exp, tmp_exp ) ); // Q31-(powerSpectrum_exp-tmp_exp)
797 338525 : move32();
798 : }
799 :
800 39520 : FOR( i = 0; i < hTonalMDCTConc->nScaleFactors; i++ )
801 : {
802 38912 : invScaleFactors_exp[i] = hTonalMDCTConc->secondLastBlockData.scaleFactors_exp[i];
803 38912 : move16();
804 38912 : invScaleFactors[i] = Inv16( hTonalMDCTConc->secondLastBlockData.scaleFactors[i], &invScaleFactors_exp[i] ); // Q31-invScaleFactors_exp[i]
805 38912 : move16();
806 : }
807 :
808 608 : power_spectrum_q = sub( 31, powerSpectrum_exp );
809 608 : old_power_spectrum_q = power_spectrum_q;
810 608 : move16();
811 608 : Word16 length = 0;
812 608 : move16();
813 : /* here mdct_shaping() is intentionally used rather then mdct_shaping_16() */
814 608 : IF( psychParamsCurrent == NULL )
815 : {
816 235 : nBands = FDNS_NPTS;
817 235 : move16();
818 235 : mdct_shaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, invScaleFactors, invScaleFactors_exp );
819 : }
820 : ELSE
821 : {
822 24245 : FOR( i = 0; i < FDNS_NPTS; i++ )
823 : {
824 23872 : invScaleFactors_fx[i] = L_shl( invScaleFactors[i], add( 1, invScaleFactors_exp[i] ) ); // Q16
825 23872 : move32();
826 : }
827 373 : sns_shape_spectrum_fx( powerSpectrum, &power_spectrum_q, psychParamsCurrent, invScaleFactors_fx, 16, hTonalMDCTConc->nSamplesCore, &length );
828 373 : power_spectrum_q = add( power_spectrum_q, 1 );
829 373 : nBands = psychParamsCurrent->nBands;
830 373 : move16();
831 : }
832 608 : IF( LT_16( old_power_spectrum_q, power_spectrum_q ) )
833 : {
834 369 : Scale_sig32( powerSpectrum, length, sub( old_power_spectrum_q, power_spectrum_q ) ); // Q(old_power_spectrum_q-power_spectrum_q)
835 : }
836 : ELSE
837 : {
838 239 : Scale_sig32( powerSpectrum + length, sub( nSamples, length ), sub( power_spectrum_q, old_power_spectrum_q ) ); // Q(power_spectrum_q - old_power_spectrum_q)
839 239 : powerSpectrum_exp = sub( 31, power_spectrum_q );
840 : }
841 608 : Scale_sig32( powerSpectrum, nSamples, -3 ); /*Adding guard bits*/ // Q(31 - powerSpectrum_exp )-3
842 608 : powerSpectrum_exp = add( powerSpectrum_exp, 3 );
843 65969 : FOR( i = hTonalMDCTConc->nSamplesCore; i < nSamples; i++ )
844 : {
845 65361 : powerSpectrum[i] = L_shl_sat( Mpy_32_16_1( powerSpectrum[i], invScaleFactors[nBands - 1] ), invScaleFactors_exp[nBands - 1] ); // Q(31 - powerSpectrum_exp)
846 65361 : move32();
847 : }
848 :
849 608 : Word16 shift = Find_Max_Norm32( powerSpectrum, nSamples );
850 608 : scale_sig32( powerSpectrum, nSamples, shift );
851 608 : powerSpectrum_exp = sub( powerSpectrum_exp, shift );
852 :
853 : /* 16 bits are now enough for storing the power spectrum */
854 339133 : FOR( i = 0; i < nSamples; i++ )
855 : {
856 338525 : hTonalMDCTConc->secondLastPowerSpectrum[i] = round_fx_sat( powerSpectrum[i] ); // Q31 - powerSpectrum_exp
857 338525 : move32();
858 : }
859 :
860 608 : hTonalMDCTConc->secondLastPowerSpectrum_exp = powerSpectrum_exp;
861 608 : move16();
862 : }
863 1598 : }
864 :
865 0 : static void CalcPowerSpecAndDetectTonalComponents(
866 : TonalMDCTConcealPtr const hTonalMDCTConc,
867 : Word32 secondLastMDST[], // Q31-secondLastMDST_exp
868 : Word16 secondLastMDST_exp,
869 : Word32 secondLastMDCT[], // Q31-secondLastMDCT_exp
870 : Word16 secondLastMDCT_exp,
871 : Word32 const pitchLag, /*15Q16*/
872 : Word16 element_mode )
873 : {
874 : Word16 nSamples;
875 : Word16 i;
876 : Word16 floorPowerSpectrum; /* Minimum significant value of a spectral line in the power spectrum */
877 : Word32 powerSpectrum[L_FRAME_MAX];
878 : Word16 invScaleFactors[FDNS_NPTS];
879 : Word16 invScaleFactors_exp[FDNS_NPTS];
880 : Word16 powerSpectrum_exp, tmp_exp, old_exp;
881 :
882 :
883 0 : nSamples = hTonalMDCTConc->nNonZeroSamples;
884 0 : move16();
885 :
886 : /* It is taken into account that the MDCT is not normalized. */
887 0 : floorPowerSpectrum /*Q0*/ = extract_l( Mpy_32_16_1( L_mult0( hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamples ), 82 ) ); /*1/400 = 82 Q15*/
888 0 : powerSpectrum_exp = 0;
889 0 : move16();
890 :
891 0 : CalcPowerSpec( secondLastMDCT,
892 : secondLastMDCT_exp,
893 : secondLastMDST,
894 : secondLastMDST_exp,
895 : nSamples,
896 : floorPowerSpectrum,
897 : powerSpectrum,
898 : &powerSpectrum_exp );
899 :
900 : /* This setting to minimal level is required because the power spectrum is used in the threshold adaptation using the pitch up to hTonalMDCTConc->nSamples. */
901 0 : set32_fx( powerSpectrum + nSamples, floorPowerSpectrum, sub( hTonalMDCTConc->nSamples, nSamples ) );
902 : /* this setting to zero is needed since the FDNS needs to be called
903 : with hTonalMDCTConc->nSamplesCore; it relevant only for nb; it has no effect
904 : to the output, but memory checker may complain otherwise due to the
905 : usage of uninitialized values */
906 0 : IF( GT_16( hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples ) )
907 : {
908 0 : set32_fx( powerSpectrum + hTonalMDCTConc->nSamples, 0, sub( hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples ) );
909 : }
910 :
911 0 : DetectTonalComponents( (Word16 *) hTonalMDCTConc->pTCI->indexOfTonalPeak,
912 0 : (Word16 *) hTonalMDCTConc->pTCI->lowerIndex,
913 0 : (Word16 *) hTonalMDCTConc->pTCI->upperIndex,
914 0 : (Word16 *) &hTonalMDCTConc->pTCI->numIndexes,
915 : hTonalMDCTConc->lastPitchLag,
916 : pitchLag,
917 0 : hTonalMDCTConc->lastBlockData.spectralData,
918 0 : add( hTonalMDCTConc->lastBlockData.spectralData_exp, hTonalMDCTConc->lastBlockData.gain_tcx_exp ),
919 0 : hTonalMDCTConc->lastBlockData.scaleFactors,
920 0 : hTonalMDCTConc->lastBlockData.scaleFactors_exp,
921 0 : hTonalMDCTConc->lastBlockData.scaleFactors_max_e,
922 : powerSpectrum,
923 : nSamples,
924 0 : hTonalMDCTConc->nSamplesCore,
925 : floorPowerSpectrum, element_mode );
926 0 : FindPhases( hTonalMDCTConc, secondLastMDCT, secondLastMDST, sub( secondLastMDST_exp, secondLastMDCT_exp ) );
927 :
928 0 : FindPhaseDifferences( hTonalMDCTConc, powerSpectrum );
929 :
930 0 : IF( hTonalMDCTConc->pTCI->numIndexes > 0 )
931 : {
932 :
933 0 : hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
934 :
935 : /*sqrtFLOAT(powerSpectrum, powerSpectrum, nSamples);*/
936 0 : old_exp = powerSpectrum_exp;
937 0 : move16();
938 0 : powerSpectrum_exp = mult_r( sub( powerSpectrum_exp, 2 ), 1 << 14 ); /*remove 2 bits of headroom from CalcPowerSpec*/
939 0 : FOR( i = 0; i < nSamples; i++ )
940 : {
941 0 : tmp_exp = old_exp;
942 0 : move16();
943 0 : powerSpectrum[i] = Sqrt32( powerSpectrum[i], &tmp_exp ); // Q31- tmp_exp
944 0 : powerSpectrum[i] = L_shr( powerSpectrum[i], sub( powerSpectrum_exp, tmp_exp ) ); // Q31- tmp_exp
945 0 : move32();
946 : }
947 :
948 0 : FOR( i = 0; i < hTonalMDCTConc->nScaleFactors; i++ )
949 : {
950 0 : move16();
951 0 : move16();
952 0 : invScaleFactors_exp[i] = hTonalMDCTConc->secondLastBlockData.scaleFactors_exp[i];
953 0 : invScaleFactors[i] = Inv16( hTonalMDCTConc->secondLastBlockData.scaleFactors[i], &invScaleFactors_exp[i] ); // Q31 - invScaleFactors_exp[i]
954 : }
955 :
956 :
957 : /* here mdct_shaping() is intentionally used rather then mdct_shaping_16() */
958 : {
959 0 : mdct_shaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, invScaleFactors, invScaleFactors_exp );
960 : }
961 0 : FOR( i = hTonalMDCTConc->nSamplesCore; i < nSamples; i++ )
962 : {
963 0 : powerSpectrum[i] = L_shl_sat( Mpy_32_16_1( powerSpectrum[i], invScaleFactors[FDNS_NPTS - 1] ), invScaleFactors_exp[FDNS_NPTS - 1] ); // powerSpectrum_exp+ 2*invScaleFactors_exp -15
964 0 : move32();
965 : }
966 :
967 : /* 16 bits are now enough for storing the power spectrum */
968 0 : FOR( i = 0; i < nSamples; i++ )
969 : {
970 0 : hTonalMDCTConc->secondLastPowerSpectrum[i] = round_fx_sat( powerSpectrum[i] ); // Q31-powerSpectrum_exp
971 0 : move32();
972 : }
973 :
974 0 : powerSpectrum_exp = sub( powerSpectrum_exp, hTonalMDCTConc->secondLastBlockData.gain_tcx_exp );
975 0 : hTonalMDCTConc->secondLastPowerSpectrum_exp = powerSpectrum_exp;
976 0 : move16();
977 : }
978 0 : }
979 :
980 :
981 3196 : static void CalcMDXT(
982 : const TonalMDCTConcealPtr hTonalMDCTConc,
983 : const Word16 type,
984 : const Word16 *timeSignal, // Qx
985 : Word32 *mdxtOutput, // Q31-mdxtOutput_e
986 : Word16 *mdxtOutput_e )
987 : {
988 : Word16 windowedTimeSignal[L_FRAME_PLUS + 2 * L_MDCT_OVLP_MAX];
989 : Word16 left_overlap, right_overlap, L_frame;
990 :
991 3196 : L_frame = hTonalMDCTConc->nSamples;
992 3196 : move16();
993 :
994 3196 : WindowSignal( hTonalMDCTConc->tcx_cfg, hTonalMDCTConc->tcx_cfg->tcx_offsetFB, FULL_OVERLAP,
995 : FULL_OVERLAP, &left_overlap, &right_overlap, timeSignal, &L_frame, windowedTimeSignal, 1, 1 );
996 :
997 3196 : IF( type == 0 )
998 : {
999 1598 : TCX_MDST( windowedTimeSignal, mdxtOutput, mdxtOutput_e, left_overlap,
1000 1598 : sub( L_frame, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, EVS_MONO );
1001 : }
1002 : ELSE
1003 : {
1004 1598 : TCX_MDCT( windowedTimeSignal, mdxtOutput, mdxtOutput_e, left_overlap,
1005 1598 : sub( L_frame, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, EVS_MONO );
1006 : }
1007 3196 : }
1008 :
1009 0 : void TonalMDCTConceal_Detect(
1010 : const TonalMDCTConcealPtr hTonalMDCTConc,
1011 : const Word32 pitchLag, /*15Q16*/
1012 : Word16 *numIndices,
1013 : Word16 element_mode )
1014 : {
1015 : Word32 secondLastMDST[L_FRAME_MAX];
1016 : Word32 secondLastMDCT[L_FRAME_MAX];
1017 : Word16 secondLastMDCT_exp;
1018 0 : Word32 *powerSpectrum = secondLastMDST;
1019 : Word16 i, powerSpectrum_exp, secondLastMDST_exp, s;
1020 : Word16 nSamples;
1021 :
1022 :
1023 0 : nSamples = hTonalMDCTConc->nSamples;
1024 0 : move16();
1025 0 : secondLastMDST_exp = 16; /*time signal Q-1*/
1026 0 : move16();
1027 0 : secondLastMDCT_exp = 16; /*time signal Q-1*/
1028 0 : move16();
1029 0 : test();
1030 0 : test();
1031 0 : test();
1032 0 : test();
1033 0 : test();
1034 0 : IF( hTonalMDCTConc->lastBlockData.blockIsValid && hTonalMDCTConc->secondLastBlockData.blockIsValid && ( EQ_16( hTonalMDCTConc->lastBlockData.nSamples, nSamples ) ) && ( EQ_16( hTonalMDCTConc->secondLastBlockData.nSamples, nSamples ) ) && ( !hTonalMDCTConc->secondLastBlockData.blockIsConcealed || hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive || ( pitchLag != 0 ) ) )
1035 : {
1036 : /* Safety if the second last frame was concealed and tonal concealment was inactive */
1037 :
1038 0 : IF( hTonalMDCTConc->lastBlockData.blockIsConcealed == 0 )
1039 : {
1040 0 : IF( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive == 0 )
1041 : {
1042 0 : CalcMDXT( hTonalMDCTConc, 0, hTonalMDCTConc->secondLastPcmOut, secondLastMDST, &secondLastMDST_exp );
1043 0 : CalcMDXT( hTonalMDCTConc, 1, hTonalMDCTConc->secondLastPcmOut, secondLastMDCT, &secondLastMDCT_exp );
1044 0 : hTonalMDCTConc->nNonZeroSamples = 0;
1045 0 : move16();
1046 0 : FOR( i = 0; i < hTonalMDCTConc->nSamples; i++ )
1047 : {
1048 0 : if ( hTonalMDCTConc->secondLastBlockData.spectralData[i] != 0 )
1049 : {
1050 0 : hTonalMDCTConc->nNonZeroSamples = i;
1051 0 : move16();
1052 : }
1053 : }
1054 :
1055 : /* 23 is the maximum length of the MA filter in getEnvelope */
1056 0 : hTonalMDCTConc->nNonZeroSamples = s_min( hTonalMDCTConc->nSamples, add( hTonalMDCTConc->nNonZeroSamples, 23 ) );
1057 0 : move16();
1058 0 : nSamples = hTonalMDCTConc->nNonZeroSamples;
1059 0 : move16();
1060 :
1061 0 : s = getScaleFactor32( secondLastMDST, nSamples );
1062 :
1063 0 : FOR( i = 0; i < nSamples; i++ )
1064 : {
1065 0 : secondLastMDST[i] = L_shl( secondLastMDST[i], s );
1066 0 : move32();
1067 : }
1068 0 : secondLastMDST_exp = sub( secondLastMDST_exp, s );
1069 0 : move16();
1070 0 : s = getScaleFactor32( secondLastMDCT, nSamples );
1071 :
1072 0 : FOR( i = 0; i < nSamples; i++ )
1073 : {
1074 0 : secondLastMDCT[i] = L_shl( secondLastMDCT[i], s );
1075 0 : move32();
1076 : }
1077 0 : secondLastMDCT_exp = sub( secondLastMDCT_exp, s );
1078 0 : move16();
1079 0 : CalcPowerSpecAndDetectTonalComponents( hTonalMDCTConc, secondLastMDST, secondLastMDST_exp, secondLastMDCT, secondLastMDCT_exp, pitchLag, element_mode );
1080 : }
1081 : ELSE
1082 : {
1083 : /* 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. */
1084 : /* That is why we reuse the already stored information about the concealed spectrum in the second last frame */
1085 : {
1086 0 : nSamples = hTonalMDCTConc->nNonZeroSamples;
1087 0 : move16();
1088 0 : mdct_shaping_16( hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamplesCore, nSamples,
1089 0 : hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp,
1090 0 : hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e, powerSpectrum );
1091 : }
1092 0 : powerSpectrum_exp = getScaleFactor32( powerSpectrum, nSamples );
1093 0 : powerSpectrum_exp = sub( powerSpectrum_exp, 3 ); /*extra 3 bits of headroom for MA filter in getEnvelope*/
1094 :
1095 : /* multFLOAT(powerSpectrum, powerSpectrum, powerSpectrum, nSamples); */
1096 0 : FOR( i = 0; i < nSamples; i++ )
1097 : {
1098 0 : Word32 const t = L_shl( powerSpectrum[i], powerSpectrum_exp ); // Q(31-secondLastMDST_exp+powerSpectrum_exp)
1099 0 : powerSpectrum[i] = Mpy_32_32( t, t ); // Q2*(31-secondLastMDST_exp+powerSpectrum_exp) -31
1100 0 : move32();
1101 : }
1102 :
1103 0 : RefineTonalComponents( (Word16 *) hTonalMDCTConc->pTCI->indexOfTonalPeak,
1104 0 : (Word16 *) hTonalMDCTConc->pTCI->lowerIndex,
1105 0 : (Word16 *) hTonalMDCTConc->pTCI->upperIndex,
1106 0 : hTonalMDCTConc->pTCI->phaseDiff,
1107 0 : hTonalMDCTConc->pTCI->phase_currentFramePredicted,
1108 0 : (Word16 *) &hTonalMDCTConc->pTCI->numIndexes,
1109 : hTonalMDCTConc->lastPitchLag,
1110 : pitchLag,
1111 0 : hTonalMDCTConc->lastBlockData.spectralData,
1112 0 : add( hTonalMDCTConc->lastBlockData.spectralData_exp, hTonalMDCTConc->lastBlockData.gain_tcx_exp ),
1113 0 : hTonalMDCTConc->lastBlockData.scaleFactors,
1114 0 : hTonalMDCTConc->lastBlockData.scaleFactors_exp,
1115 0 : hTonalMDCTConc->lastBlockData.scaleFactors_max_e,
1116 : powerSpectrum,
1117 : nSamples,
1118 0 : hTonalMDCTConc->nSamplesCore,
1119 0 : extract_l( Mpy_32_16_1( L_mult0( hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamples ), 82 ) ), element_mode ); /* floorPowerSpectrum */
1120 : }
1121 : }
1122 : }
1123 : ELSE
1124 : {
1125 0 : hTonalMDCTConc->pTCI->numIndexes = 0;
1126 0 : move16();
1127 : }
1128 :
1129 0 : *numIndices = hTonalMDCTConc->pTCI->numIndexes;
1130 0 : move16();
1131 :
1132 :
1133 0 : return;
1134 : }
1135 :
1136 1860 : void TonalMDCTConceal_Detect_ivas_fx(
1137 : const TonalMDCTConcealPtr hTonalMDCTConc,
1138 : const Word32 pitchLag, /*15Q16*/
1139 : Word16 *numIndices,
1140 : const PsychoacousticParameters *psychParamsCurrent,
1141 : Word16 element_mode )
1142 : {
1143 : Word32 secondLastMDST[L_FRAME_MAX];
1144 1860 : set32_fx( secondLastMDST, 0, L_FRAME_MAX );
1145 : Word32 secondLastMDCT[L_FRAME_MAX];
1146 : Word16 secondLastMDCT_exp;
1147 1860 : Word32 *powerSpectrum = secondLastMDST;
1148 : Word16 i, powerSpectrum_exp, secondLastMDST_exp, s;
1149 : Word16 nSamples;
1150 : // Word16 nBands;
1151 : Word32 sns_int_scf_fx[FDNS_NPTS];
1152 1860 : set32_fx( sns_int_scf_fx, 0, FDNS_NPTS );
1153 :
1154 1860 : nSamples = hTonalMDCTConc->nSamples;
1155 1860 : move16();
1156 1860 : secondLastMDST_exp = sub( 16, hTonalMDCTConc->q_lastPcmOut ); /*time signal Q-1 - hTonalMDCTConc->q_lastPcmOut*/
1157 1860 : move16();
1158 1860 : secondLastMDCT_exp = sub( 16, hTonalMDCTConc->q_lastPcmOut ); /*time signal Q-1 - hTonalMDCTConc->q_lastPcmOut*/
1159 1860 : move16();
1160 1860 : test();
1161 1860 : test();
1162 1860 : test();
1163 1860 : test();
1164 1860 : test();
1165 1860 : IF( hTonalMDCTConc->lastBlockData.blockIsValid && hTonalMDCTConc->secondLastBlockData.blockIsValid && ( EQ_16( hTonalMDCTConc->lastBlockData.nSamples, nSamples ) ) && ( EQ_16( hTonalMDCTConc->secondLastBlockData.nSamples, nSamples ) ) && ( !hTonalMDCTConc->secondLastBlockData.blockIsConcealed || hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive || ( pitchLag != 0 ) ) )
1166 : {
1167 : /* Safety if the second last frame was concealed and tonal concealment was inactive */
1168 :
1169 1598 : IF( hTonalMDCTConc->lastBlockData.blockIsConcealed == 0 )
1170 : {
1171 1598 : IF( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive == 0 )
1172 : {
1173 1598 : CalcMDXT( hTonalMDCTConc, 0, hTonalMDCTConc->secondLastPcmOut, secondLastMDST, &secondLastMDST_exp );
1174 1598 : CalcMDXT( hTonalMDCTConc, 1, hTonalMDCTConc->secondLastPcmOut, secondLastMDCT, &secondLastMDCT_exp );
1175 1598 : hTonalMDCTConc->nNonZeroSamples = 0;
1176 1598 : move16();
1177 1249598 : FOR( i = 0; i < hTonalMDCTConc->nSamples; i++ )
1178 : {
1179 1248000 : if ( hTonalMDCTConc->secondLastBlockData.spectralData[i] != 0 )
1180 : {
1181 756365 : hTonalMDCTConc->nNonZeroSamples = i;
1182 756365 : move16();
1183 : }
1184 : }
1185 :
1186 : /* 23 is the maximum length of the MA filter in getEnvelope */
1187 1598 : hTonalMDCTConc->nNonZeroSamples = s_min( hTonalMDCTConc->nSamples, add( hTonalMDCTConc->nNonZeroSamples, 23 ) );
1188 1598 : move16();
1189 1598 : nSamples = hTonalMDCTConc->nNonZeroSamples;
1190 1598 : move16();
1191 :
1192 1598 : s = sub( getScaleFactor32( secondLastMDST, nSamples ), 1 );
1193 :
1194 832816 : FOR( i = 0; i < nSamples; i++ )
1195 : {
1196 831218 : secondLastMDST[i] = L_shl( secondLastMDST[i], s );
1197 831218 : move32();
1198 : }
1199 1598 : secondLastMDST_exp = sub( secondLastMDST_exp, s );
1200 1598 : move16();
1201 1598 : s = sub( getScaleFactor32( secondLastMDCT, nSamples ), 1 );
1202 :
1203 832816 : FOR( i = 0; i < nSamples; i++ )
1204 : {
1205 831218 : secondLastMDCT[i] = L_shl( secondLastMDCT[i], s );
1206 831218 : move32();
1207 : }
1208 1598 : secondLastMDCT_exp = sub( secondLastMDCT_exp, s );
1209 1598 : move16();
1210 1598 : ivas_CalcPowerSpecAndDetectTonalComponents_fx( hTonalMDCTConc, secondLastMDST, secondLastMDST_exp, secondLastMDCT, secondLastMDCT_exp, pitchLag, psychParamsCurrent, element_mode );
1211 : }
1212 : ELSE
1213 : {
1214 : /* 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. */
1215 : /* That is why we reuse the already stored information about the concealed spectrum in the second last frame */
1216 0 : Word16 temp_power_spectrum_q = 0;
1217 0 : nSamples = hTonalMDCTConc->nNonZeroSamples;
1218 0 : move16();
1219 0 : Copy_Scale_sig_16_32_DEPREC( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples, Q15 );
1220 0 : temp_power_spectrum_q = add( Q15, sub( 15, hTonalMDCTConc->secondLastPowerSpectrum_exp ) );
1221 0 : IF( psychParamsCurrent == NULL )
1222 : {
1223 0 : mdct_shaping_16( hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamplesCore, nSamples,
1224 0 : hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp,
1225 0 : hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e, powerSpectrum );
1226 :
1227 0 : powerSpectrum_exp = getScaleFactor32( powerSpectrum, nSamples );
1228 0 : powerSpectrum_exp = sub( powerSpectrum_exp, 3 ); /*extra 3 bits of headroom for MA filter in getEnvelope*/
1229 :
1230 : /* multFLOAT(powerSpectrum, powerSpectrum, powerSpectrum, nSamples); */
1231 0 : FOR( i = 0; i < nSamples; i++ )
1232 : {
1233 0 : Word32 const t = L_shl( powerSpectrum[i], powerSpectrum_exp ); // Q(31-secondLastMDST_exp+powerSpectrum_exp)
1234 0 : powerSpectrum[i] = Mpy_32_32( t, t ); // Q(31-secondLastMDST_exp+powerSpectrum_exp)
1235 0 : move32();
1236 : }
1237 0 : powerSpectrum_exp = 0;
1238 0 : move16();
1239 : }
1240 : ELSE
1241 : {
1242 0 : FOR( i = 0; i < FDNS_NPTS; i++ )
1243 : {
1244 0 : sns_int_scf_fx[i] = L_shl( hTonalMDCTConc->secondLastBlockData.scaleFactors[i], add( 1, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp[i] ) ); // Q16
1245 0 : move32();
1246 : }
1247 0 : sns_shape_spectrum_fx( powerSpectrum, &temp_power_spectrum_q, psychParamsCurrent, sns_int_scf_fx, 16, hTonalMDCTConc->nSamplesCore, NULL );
1248 0 : powerSpectrum_exp = sub( 31, temp_power_spectrum_q );
1249 :
1250 0 : FOR( i = 0; i < nSamples; i++ )
1251 : {
1252 0 : Word32 const t = L_shl( powerSpectrum[i], -3 ); // Q31 - powerSpectrum_exp -3
1253 0 : powerSpectrum[i] = Mpy_32_32( t, t ); // 2*(Q31 - powerSpectrum_exp -3)-31
1254 0 : move32();
1255 : }
1256 0 : powerSpectrum_exp = sub( 31, sub( shl( sub( Q31 - 3, powerSpectrum_exp ), 1 ), 31 ) );
1257 : }
1258 :
1259 0 : ivas_RefineTonalComponents_fx( (Word16 *) hTonalMDCTConc->pTCI->indexOfTonalPeak,
1260 0 : (Word16 *) hTonalMDCTConc->pTCI->lowerIndex,
1261 0 : (Word16 *) hTonalMDCTConc->pTCI->upperIndex,
1262 0 : hTonalMDCTConc->pTCI->phaseDiff,
1263 0 : hTonalMDCTConc->pTCI->phase_currentFramePredicted,
1264 0 : (Word16 *) &hTonalMDCTConc->pTCI->numIndexes,
1265 : hTonalMDCTConc->lastPitchLag,
1266 : pitchLag,
1267 0 : hTonalMDCTConc->lastBlockData.spectralData,
1268 0 : add( hTonalMDCTConc->lastBlockData.spectralData_exp, hTonalMDCTConc->lastBlockData.gain_tcx_exp ),
1269 0 : hTonalMDCTConc->lastBlockData.scaleFactors,
1270 0 : hTonalMDCTConc->lastBlockData.scaleFactors_exp,
1271 0 : hTonalMDCTConc->lastBlockData.scaleFactors_max_e,
1272 : powerSpectrum,
1273 : powerSpectrum_exp,
1274 : nSamples,
1275 0 : hTonalMDCTConc->nSamplesCore,
1276 0 : extract_l( Mpy_32_16_1( L_mult0( hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamples ), 82 ) ), element_mode, psychParamsCurrent ); /* floorPowerSpectrum */
1277 : }
1278 : }
1279 : }
1280 : ELSE
1281 : {
1282 262 : hTonalMDCTConc->pTCI->numIndexes = 0;
1283 262 : move16();
1284 : }
1285 :
1286 1860 : *numIndices = hTonalMDCTConc->pTCI->numIndexes;
1287 1860 : move16();
1288 :
1289 :
1290 1860 : return;
1291 : }
1292 :
1293 8707 : void TonalMDCTConceal_InsertNoise_ivas_fx(
1294 : const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */
1295 : Word32 *mdctSpectrum, // Q31-mdctSpectrum_exp
1296 : Word16 *mdctSpectrum_exp,
1297 : const Word16 tonalConcealmentActive,
1298 : Word16 *pSeed, /*IN/OUT*/
1299 : const Word16 tiltCompFactor, // Q15
1300 : const Word16 crossfadeGain_const, // Q15
1301 : const Word32 concealment_noise[L_FRAME48k], // Q31-concealment_noise_e
1302 : const Word16 concealment_noise_e,
1303 : const Word32 cngLevelBackgroundTrace_bfi, // Q31-cngLevelBackgroundTrace_bfi_e
1304 : const Word16 cngLevelBackgroundTrace_bfi_e,
1305 : const Word16 crossOverFreq ) // Q0
1306 : {
1307 : Word16 i, l, ld, fac;
1308 : Word16 rnd;
1309 : #ifdef FIX_1944_CRASH_FOR_STEREO
1310 : Word16 tmp, g, tilt, exp_last, exp_noise, tiltFactor, crossfadeGain, e_crossfadeGain, scaleFactor;
1311 : #else
1312 : Word16 tmp, g, tilt, exp_last, exp_noise, tiltFactor, crossfadeGain, e_crossfadeGain;
1313 : #endif
1314 : Word32 L_tmp, L_tmp1, L_tmp2, nrgNoiseInLastFrame, nrgWhiteNoise;
1315 : Word16 inv_exp, inv_samples, exp;
1316 : Word32 last_block_nrg_correct;
1317 : Word16 last_block_nrg_correct_e;
1318 : Word32 max_concealment_value;
1319 : Word16 max_spectral_value;
1320 : Word64 sum1, sum2;
1321 : Word16 num16, den16, exp1, exp2;
1322 : Word16 shift1, shift2;
1323 :
1324 8707 : crossfadeGain = crossfadeGain_const;
1325 8707 : move16();
1326 8707 : e_crossfadeGain = 0;
1327 8707 : move16();
1328 8707 : push_wmops( "InsertNoise" );
1329 :
1330 8707 : g = sub( MAX16B, crossfadeGain );
1331 :
1332 8707 : IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
1333 : {
1334 4941 : rnd = 1977;
1335 4941 : move16();
1336 : }
1337 : ELSE
1338 : {
1339 3766 : rnd = *pSeed;
1340 3766 : move16();
1341 : }
1342 :
1343 : /* based on what is done in tcx_noise_filling() */
1344 : /* always initialize these to avoid compiler warnings */
1345 8707 : hTonalMDCTConc->faded_signal_nrg = L_deposit_h( 0 );
1346 8707 : move32();
1347 :
1348 8707 : L_tmp = 805306368l /*0.375f Q31*/;
1349 8707 : move32();
1350 8707 : inv_exp = 15;
1351 8707 : move16();
1352 8707 : inv_samples = Inv16( hTonalMDCTConc->lastBlockData.nSamples, &inv_exp ); // Q31-inv_exp
1353 8707 : tiltFactor = round_fx( BASOP_Util_fPow( L_max( L_tmp, L_deposit_h( tiltCompFactor ) ), 0, L_deposit_h( inv_samples ), inv_exp, &exp ) ); // Q15 - exp
1354 : BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/
1355 8707 : tiltFactor = shl_sat( tiltFactor, exp ); // Q15
1356 : BASOP_SATURATE_WARNING_ON_EVS
1357 8707 : tilt = MAX16B;
1358 8707 : move16();
1359 8707 : nrgNoiseInLastFrame = L_deposit_h( 0 );
1360 8707 : nrgWhiteNoise = L_deposit_h( 0 );
1361 8707 : last_block_nrg_correct = L_deposit_h( 0 );
1362 8707 : last_block_nrg_correct_e = 0;
1363 8707 : move16();
1364 8707 : exp_last = exp_noise = 0;
1365 8707 : move16();
1366 8707 : move16();
1367 :
1368 8707 : IF( !hTonalMDCTConc->lastBlockData.blockIsValid )
1369 : {
1370 : /* may just become active if the very first frame is lost */
1371 0 : set32_fx( mdctSpectrum, 0, hTonalMDCTConc->nSamples );
1372 : }
1373 8707 : ELSE IF( concealment_noise != NULL )
1374 : {
1375 3201 : IF( !tonalConcealmentActive )
1376 : {
1377 : /* if fadeout has not started yet, only apply sign scrambling */
1378 3103 : IF( GE_16( crossfadeGain_const, CROSSFADE_THRESHOLD ) )
1379 : {
1380 620986 : FOR( i = 0; i < crossOverFreq; i++ )
1381 : {
1382 619392 : IF( concealment_noise[i] > 0 )
1383 : {
1384 323208 : mdctSpectrum[i] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[i] ), 16 ); // Q31-spectralData_exp
1385 323208 : move32();
1386 : }
1387 : ELSE
1388 : {
1389 296184 : mdctSpectrum[i] = L_negate( L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[i] ), 16 ) ); // Q31-spectralData_exp
1390 296184 : move32();
1391 : }
1392 : }
1393 :
1394 414522 : FOR( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
1395 : {
1396 412928 : mdctSpectrum[l] = 0;
1397 412928 : move32();
1398 : }
1399 :
1400 1594 : *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
1401 1594 : move16();
1402 : }
1403 : /* actual fadeout is done in this case */
1404 : ELSE
1405 : {
1406 : Word32 num, den;
1407 : Word16 exp_num, exp_den;
1408 :
1409 1509 : exp_num = cngLevelBackgroundTrace_bfi_e;
1410 1509 : move16();
1411 1509 : exp_den = hTonalMDCTConc->curr_noise_nrg_exp;
1412 1509 : move16();
1413 :
1414 1509 : ld = norm_l( cngLevelBackgroundTrace_bfi );
1415 1509 : num = L_shl( cngLevelBackgroundTrace_bfi, ld );
1416 1509 : exp_num = sub( exp_num, ld );
1417 1509 : ld = norm_l( hTonalMDCTConc->curr_noise_nrg );
1418 1509 : den = L_shl( hTonalMDCTConc->curr_noise_nrg, ld ); // Q31- curr_noise_nrg_exp + ld
1419 1509 : exp_den = sub( exp_den, ld );
1420 :
1421 1509 : exp = sub( exp_num, exp_den );
1422 :
1423 1509 : IF( GT_32( num, den ) )
1424 : {
1425 1431 : num = L_shr( num, 1 ); // Q31-exp -1
1426 1431 : exp = add( exp, 1 );
1427 : }
1428 1509 : tmp = div_l( num, round_fx_sat( den ) );
1429 1509 : tmp = Sqrt16( tmp, &exp );
1430 1509 : g = mult_r( g, tmp ); // exponent of g = exp
1431 :
1432 1509 : L_tmp = L_deposit_h( 0 );
1433 1509 : exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, add( concealment_noise_e, exp ) );
1434 1509 : (void) maximum_abs_32_fx( concealment_noise, crossOverFreq, &max_concealment_value );
1435 1509 : IF( GT_32( max_concealment_value, 0 ) )
1436 : {
1437 189 : IF( exp > 0 )
1438 : {
1439 171 : g = shr( g, exp ); // Q15-exp
1440 171 : *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
1441 171 : move16();
1442 : }
1443 : ELSE
1444 : {
1445 18 : crossfadeGain = shl( crossfadeGain, exp ); // Q15 - e_crossfadeGain + exp
1446 18 : e_crossfadeGain = sub( e_crossfadeGain, exp );
1447 18 : *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp );
1448 18 : move16();
1449 : }
1450 : /*make a headroom for mdct_shaping*/
1451 189 : exp = sub( *mdctSpectrum_exp, SPEC_EXP_DEC );
1452 : /* assert(exp < 0);*/
1453 189 : IF( exp < 0 )
1454 : {
1455 179 : *mdctSpectrum_exp = SPEC_EXP_DEC;
1456 179 : move16();
1457 : }
1458 : ELSE
1459 : {
1460 10 : exp = 0;
1461 10 : move16();
1462 : }
1463 : }
1464 : ELSE
1465 : {
1466 1320 : (void) maximum_abs_16_fx( hTonalMDCTConc->lastBlockData.spectralData, crossOverFreq, &max_spectral_value );
1467 1320 : exp = sub( norm_l( L_mult( max_spectral_value, crossfadeGain ) ), find_guarded_bits_fx( crossOverFreq ) );
1468 1320 : *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp );
1469 1320 : move16();
1470 : }
1471 :
1472 572133 : FOR( i = 0; i < crossOverFreq; i++ )
1473 : {
1474 570624 : Word16 x = hTonalMDCTConc->lastBlockData.spectralData[i]; // Q15 - spectralData_exp
1475 570624 : move16();
1476 570624 : Word32 y = concealment_noise[i]; // Q31-concealment_noise_e
1477 570624 : move32();
1478 :
1479 570624 : IF( g > 0 )
1480 : {
1481 561696 : L_tmp = Mpy_32_16_1( y, g ); // Q31-concealment_noise_e- spectralData_exp
1482 : }
1483 :
1484 570624 : L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
1485 570624 : IF( y > 0 )
1486 : {
1487 33918 : L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
1488 : }
1489 570624 : mdctSpectrum[i] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
1490 570624 : move32();
1491 : #ifndef FIX_1944_CRASH_FOR_STEREO
1492 : hTonalMDCTConc->faded_signal_nrg = L_add( hTonalMDCTConc->faded_signal_nrg, Mpy_32_32( mdctSpectrum[i], mdctSpectrum[i] ) ); // Q31- faded_signal_nrg_exp
1493 : move32();
1494 : #endif
1495 : }
1496 387365 : FOR( i = crossOverFreq; i < hTonalMDCTConc->lastBlockData.nSamples; i++ )
1497 : {
1498 385856 : mdctSpectrum[i] = 0;
1499 385856 : move32();
1500 : }
1501 1509 : *mdctSpectrum_exp = sub( add( e_crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData_exp ), exp );
1502 1509 : move16();
1503 : #ifdef FIX_1944_CRASH_FOR_STEREO
1504 1509 : scaleFactor = getScaleFactor32( mdctSpectrum, crossOverFreq );
1505 1509 : IF( scaleFactor > 8 )
1506 : {
1507 1145 : scaleFactor = sub( scaleFactor, 8 ); // add headroom
1508 : }
1509 : ELSE
1510 : {
1511 364 : scaleFactor = 0;
1512 364 : move16();
1513 : }
1514 :
1515 572133 : FOR( i = 0; i < crossOverFreq; i++ )
1516 : {
1517 570624 : Word32 mdctSpectrumScaled = L_shl( mdctSpectrum[i], scaleFactor );
1518 570624 : hTonalMDCTConc->faded_signal_nrg = L_add( hTonalMDCTConc->faded_signal_nrg, Mpy_32_32( mdctSpectrumScaled, mdctSpectrumScaled ) );
1519 : }
1520 1509 : move32();
1521 1509 : hTonalMDCTConc->faded_signal_nrg_exp = shl( sub( *mdctSpectrum_exp, scaleFactor ), 1 );
1522 : #else
1523 : hTonalMDCTConc->faded_signal_nrg_exp = shl( *mdctSpectrum_exp, 1 );
1524 : #endif
1525 1509 : move16();
1526 : }
1527 : }
1528 : ELSE
1529 : {
1530 98 : assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
1531 :
1532 : /* initialize bins of tonal components with zero: basically not
1533 : necessary, but currently the whole spectrum is rescaled in
1534 : mdct_noiseShaping() and then there would be a processing of
1535 : uninitialized values */
1536 :
1537 98 : ld = sub( 14, norm_s( hTonalMDCTConc->lastBlockData.nSamples ) );
1538 98 : fac = shr( -32768, ld );
1539 :
1540 775 : FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
1541 : {
1542 5416 : FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
1543 : {
1544 4739 : mdctSpectrum[l] = L_deposit_h( 0 );
1545 4739 : IF( LT_16( l, crossOverFreq ) )
1546 : {
1547 4641 : Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l];
1548 4641 : move16();
1549 4641 : Word32 y = concealment_noise[l]; // concealment_noise_e
1550 4641 : move32();
1551 4641 : shift1 = norm_l( y );
1552 4641 : y = L_shl( y, shift1 );
1553 :
1554 4641 : last_block_nrg_correct = L_add( last_block_nrg_correct, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // exp = 2 * x_exp + ld
1555 4641 : y = L_negate( Mpy_32_32( y, y ) ); // Q31-(2* concealment_noise_e + shift1)
1556 4641 : hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, y, shl( sub( concealment_noise_e, shift1 ), 1 ), &hTonalMDCTConc->curr_noise_nrg_exp ); // Q31- hTonalMDCTConc->curr_noise_nrg_exp
1557 4641 : move32();
1558 : }
1559 : }
1560 : }
1561 98 : last_block_nrg_correct_e = add( shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ), ld );
1562 :
1563 : /* if fadeout has not started yet, only apply sign scrambling */
1564 98 : IF( GE_16( crossfadeGain_const, CROSSFADE_THRESHOLD ) )
1565 : {
1566 4931 : FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
1567 : {
1568 4846 : IF( GT_32( concealment_noise[l], 0 ) )
1569 : {
1570 2292 : mdctSpectrum[l] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ); // hTonalMDCTConc->lastBlockData.spectralData_exp
1571 2292 : move32();
1572 : }
1573 : ELSE
1574 : {
1575 2554 : mdctSpectrum[l] = L_negate( L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ) ); // hTonalMDCTConc->lastBlockData.spectralData_exp
1576 2554 : move32();
1577 : }
1578 : }
1579 603 : FOR( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
1580 : {
1581 7694 : FOR( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
1582 : {
1583 7176 : IF( concealment_noise[l] > 0 )
1584 : {
1585 3840 : mdctSpectrum[l] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ); // hTonalMDCTConc->lastBlockData.spectralData_exp
1586 3840 : move32();
1587 : }
1588 : ELSE
1589 : {
1590 3336 : mdctSpectrum[l] = L_negate( L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ) ); // hTonalMDCTConc->lastBlockData.spectralData_exp
1591 3336 : move32();
1592 : }
1593 : }
1594 : }
1595 :
1596 19797 : FOR( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
1597 : {
1598 19712 : IF( concealment_noise[l] > 0 )
1599 : {
1600 10157 : mdctSpectrum[l] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ); // hTonalMDCTConc->lastBlockData.spectralData_exp
1601 10157 : move32();
1602 : }
1603 : ELSE
1604 : {
1605 9555 : mdctSpectrum[l] = L_negate( L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ) ); // hTonalMDCTConc->lastBlockData.spectralData_exp
1606 9555 : move32();
1607 : }
1608 : }
1609 :
1610 23317 : FOR( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
1611 : {
1612 23232 : mdctSpectrum[l] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ); // hTonalMDCTConc->lastBlockData.spectralData_exp
1613 23232 : move32();
1614 : }
1615 :
1616 85 : *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
1617 85 : move16();
1618 : }
1619 : /* actual fadeout is done in this case */
1620 : ELSE
1621 : {
1622 13 : tmp = BASOP_Util_Divide3232_Scale( cngLevelBackgroundTrace_bfi, hTonalMDCTConc->curr_noise_nrg, &exp );
1623 13 : exp = add( exp, sub( cngLevelBackgroundTrace_bfi_e, hTonalMDCTConc->curr_noise_nrg_exp ) );
1624 :
1625 13 : tmp = Sqrt16( tmp, &exp );
1626 13 : g = mult_r( g, tmp ); // exponent of g = exp
1627 :
1628 13 : L_tmp = L_deposit_h( 0 );
1629 13 : exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, add( concealment_noise_e, exp ) );
1630 :
1631 13 : (void) maximum_abs_32_fx( concealment_noise, crossOverFreq, &max_concealment_value );
1632 13 : IF( GT_32( max_concealment_value, 0 ) )
1633 : {
1634 0 : IF( GT_16( exp, 0 ) )
1635 : {
1636 0 : g = shr( g, exp ); // Q15- exp
1637 0 : *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
1638 0 : move16();
1639 : }
1640 : ELSE
1641 : {
1642 0 : crossfadeGain = shl( crossfadeGain, exp ); // Q15 - e_crossfadeGain
1643 0 : e_crossfadeGain = sub( e_crossfadeGain, exp );
1644 0 : *mdctSpectrum_exp = add( e_crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData_exp );
1645 0 : move16();
1646 : }
1647 : /*make a headroom for mdct_shaping*/
1648 0 : exp = sub( *mdctSpectrum_exp, SPEC_EXP_DEC );
1649 : /* assert(exp < 0);*/
1650 0 : IF( exp < 0 )
1651 : {
1652 0 : *mdctSpectrum_exp = SPEC_EXP_DEC;
1653 0 : move16();
1654 : }
1655 : ELSE
1656 : {
1657 0 : exp = 0;
1658 0 : move16();
1659 : }
1660 : }
1661 : ELSE
1662 : {
1663 13 : (void) maximum_abs_16_fx( hTonalMDCTConc->lastBlockData.spectralData, crossOverFreq, &max_spectral_value );
1664 13 : exp = sub( norm_l( L_mult( max_spectral_value, crossfadeGain ) ), find_guarded_bits_fx( crossOverFreq ) );
1665 13 : *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp );
1666 13 : move16();
1667 : }
1668 :
1669 1097 : FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
1670 : {
1671 1084 : Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
1672 1084 : move16();
1673 1084 : Word32 y = concealment_noise[l]; // Q31-concealment_noise_e
1674 1084 : move32();
1675 :
1676 1084 : IF( g > 0 )
1677 : {
1678 1084 : L_tmp = Mpy_32_16_1( y, g ); // Q31-concealment_noise_e- spectralData_exp
1679 : }
1680 :
1681 1084 : L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
1682 1084 : IF( y > 0 )
1683 : {
1684 0 : L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
1685 : }
1686 1084 : mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
1687 1084 : move32();
1688 : #ifndef FIX_1944_CRASH_FOR_STEREO
1689 : hTonalMDCTConc->faded_signal_nrg = L_add( hTonalMDCTConc->faded_signal_nrg, Mpy_32_32( mdctSpectrum[l], mdctSpectrum[l] ) ); // Q31 - 2*mdctSpectrum_exp
1690 : move32();
1691 : #endif
1692 : }
1693 :
1694 74 : FOR( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
1695 : {
1696 1004 : FOR( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
1697 : {
1698 943 : Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
1699 943 : move16();
1700 943 : Word32 y = concealment_noise[l]; // Q31-concealment_noise_e
1701 943 : move32();
1702 :
1703 943 : L_tmp = Mpy_32_16_1( y, g );
1704 943 : L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
1705 943 : IF( y > 0 )
1706 : {
1707 0 : L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
1708 : }
1709 943 : mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
1710 943 : move32();
1711 : #ifndef FIX_1944_CRASH_FOR_STEREO
1712 : hTonalMDCTConc->faded_signal_nrg = L_add( hTonalMDCTConc->faded_signal_nrg, Mpy_32_32( mdctSpectrum[l], mdctSpectrum[l] ) ); // Q31- 2*mdctSpectrum_exp
1713 : #endif
1714 : }
1715 : }
1716 :
1717 3068 : FOR( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
1718 : {
1719 3055 : Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
1720 3055 : move16();
1721 3055 : Word32 y = concealment_noise[l]; // Q31-concealment_noise_e
1722 3055 : move32();
1723 :
1724 3055 : L_tmp = Mpy_32_16_1( y, g ); // Q31-concealment_noise_e- spectralData_exp
1725 3055 : L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
1726 3055 : IF( y > 0 )
1727 : {
1728 0 : L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
1729 : }
1730 3055 : mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
1731 3055 : move32();
1732 : #ifndef FIX_1944_CRASH_FOR_STEREO
1733 : hTonalMDCTConc->faded_signal_nrg = L_add( hTonalMDCTConc->faded_signal_nrg, Mpy_32_32( mdctSpectrum[l], mdctSpectrum[l] ) ); // Q31- 2*mdctSpectrum_exp
1734 : move32();
1735 : #endif
1736 : }
1737 :
1738 2093 : FOR( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
1739 : {
1740 2080 : mdctSpectrum[l] = L_deposit_h( 0 );
1741 2080 : move32();
1742 : }
1743 : #ifdef FIX_1944_CRASH_FOR_STEREO
1744 13 : scaleFactor = getScaleFactor32( mdctSpectrum, crossOverFreq );
1745 13 : IF( scaleFactor > 8 )
1746 : {
1747 13 : scaleFactor = sub( scaleFactor, 8 ); // add headroom
1748 : }
1749 : ELSE
1750 : {
1751 0 : scaleFactor = 0;
1752 0 : move16();
1753 : }
1754 :
1755 5613 : FOR( i = 0; i < crossOverFreq; i++ )
1756 : {
1757 5600 : Word32 mdctSpectrumScaled = L_shl( mdctSpectrum[i], scaleFactor );
1758 5600 : hTonalMDCTConc->faded_signal_nrg = L_add( hTonalMDCTConc->faded_signal_nrg, Mpy_32_32( mdctSpectrumScaled, mdctSpectrumScaled ) );
1759 : }
1760 13 : move32();
1761 13 : hTonalMDCTConc->faded_signal_nrg_exp = shl( sub( *mdctSpectrum_exp, scaleFactor ), 1 );
1762 : #else
1763 : hTonalMDCTConc->faded_signal_nrg_exp = shl( *mdctSpectrum_exp, 1 );
1764 : #endif
1765 13 : move16();
1766 : }
1767 : }
1768 :
1769 : // Compare curr_noise_nrg with MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG
1770 : Flag flag;
1771 3201 : flag = EQ_16( hTonalMDCTConc->curr_noise_nrg_exp, 0 ) && GT_32( hTonalMDCTConc->curr_noise_nrg, MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG_Q31 );
1772 3201 : flag = flag || GT_16( hTonalMDCTConc->curr_noise_nrg_exp, 0 );
1773 3201 : test();
1774 3201 : IF( GT_32( hTonalMDCTConc->faded_signal_nrg, 0 ) && flag )
1775 : {
1776 : Word16 num_exp;
1777 : Word32 num;
1778 :
1779 179 : num = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->last_block_nrg, hTonalMDCTConc->last_block_nrg_exp, L_negate( last_block_nrg_correct ), last_block_nrg_correct_e, &num_exp ); // Q31-num_exp
1780 179 : tmp = BASOP_Util_Divide3232_Scale( num, hTonalMDCTConc->faded_signal_nrg, &exp );
1781 179 : exp = add( exp, sub( num_exp, hTonalMDCTConc->faded_signal_nrg_exp ) );
1782 179 : tmp = Sqrt16( tmp, &exp );
1783 :
1784 68131 : FOR( i = 0; i < crossOverFreq; i++ )
1785 : {
1786 67952 : mdctSpectrum[i] = Mpy_32_16_1( mdctSpectrum[i], tmp ); // Q31-(*mdctSpectrum_exp+exp)
1787 67952 : move32();
1788 : }
1789 179 : *mdctSpectrum_exp = add( *mdctSpectrum_exp, exp );
1790 : }
1791 : }
1792 : ELSE{
1793 5506 : IF( tonalConcealmentActive == 0 ){
1794 5109 : sum1 = 0;
1795 5109 : sum2 = 0;
1796 5109 : move64();
1797 5109 : move64();
1798 2386855 : FOR( i = 0; i < crossOverFreq; i++ )
1799 : {
1800 : Word16 x;
1801 : /*x = hTonalMDCTConc->lastBlockData.spectralData[i];
1802 : nrgNoiseInLastFrame += x * x;*/
1803 2381746 : sum1 = W_mac0_16_16( sum1, hTonalMDCTConc->lastBlockData.spectralData[i], hTonalMDCTConc->lastBlockData.spectralData[i] ); // Q: 2*(15-hTonalMDCTConc->lastBlockData.spectralData_exp)
1804 :
1805 : /* rnd = own_random(&rnd); */
1806 2381746 : rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); /* Q0 */
1807 :
1808 : /* mdctSpectrum[i] = tilt * rnd; */
1809 2381746 : mdctSpectrum[i] = L_mult( tilt, rnd ); // Q16
1810 2381746 : move32();
1811 :
1812 : /* tilt *= tiltFactor; */
1813 2381746 : tilt = mult_r( tilt, tiltFactor ); /* Q15 */
1814 :
1815 : /* nrgWhiteNoise += mdctSpectrum[i] * mdctSpectrum[i]; */
1816 2381746 : x = round_fx( mdctSpectrum[i] ); // Q0
1817 2381746 : sum2 = W_mac0_16_16( sum2, x, x ); // Q0
1818 : }
1819 5109 : *mdctSpectrum_exp = 15;
1820 5109 : move16();
1821 :
1822 5109 : IF( sum1 /* nrgNoiseInLastFrame */ == 0 )
1823 : {
1824 0 : set32_fx( mdctSpectrum, 0, crossOverFreq );
1825 0 : *mdctSpectrum_exp = SPEC_EXP_DEC;
1826 0 : move16();
1827 : }
1828 : ELSE
1829 : {
1830 5109 : IF( g == 0 )
1831 : {
1832 4136 : *mdctSpectrum_exp = add( add( hTonalMDCTConc->lastBlockData.spectralData_exp, e_crossfadeGain ), 31 - SPEC_EXP_DEC );
1833 4136 : move16();
1834 2112744 : FOR( i = 0; i < crossOverFreq; i++ )
1835 : {
1836 : /* mdctSpectrum[i] = g * mdctSpectrum[i] + crossfadeGain * hTonalMDCTConc->lastBlockData.spectralData[i]; */
1837 2108608 : L_tmp = L_mult( crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData[i] ); // exp: hTonalMDCTConc->lastBlockData.spectralData_exp+e_crossfadeGain
1838 2108608 : if ( mdctSpectrum[i] <= 0 )
1839 : {
1840 : /* mdctSpectrum[i] = g * mdctSpectrum[i] - crossfadeGain * hTonalMDCTConc->lastBlockData.spectralData[i]; */
1841 1055148 : L_tmp = L_negate( L_tmp ); // exp: hTonalMDCTConc->lastBlockData.spectralData_exp+e_crossfadeGain
1842 : }
1843 : /* headroom for mdct_shaping */
1844 2108608 : mdctSpectrum[i] = L_shr( L_tmp, 31 - SPEC_EXP_DEC ); // *mdctSpectrum_exp
1845 2108608 : move32();
1846 : }
1847 : }
1848 : ELSE
1849 : {
1850 973 : IF( sum2 /* nrgWhiteNoise */ > 0 )
1851 : {
1852 973 : exp1 = sub( W_norm( sum1 ), 1 );
1853 973 : num16 = extract_h( W_extract_h( W_shl( sum1, exp1 ) ) ); // nrgNoiseInLastFrame -> Q: 2*(15-hTonalMDCTConc->lastBlockData.spectralData_exp)+exp1-48
1854 973 : exp2 = W_norm( sum2 );
1855 973 : den16 = extract_h( W_extract_h( W_shl( sum2, exp2 ) ) ); // nrgWhiteNoise -> Q: exp2-48
1856 :
1857 : /* sqrt( nrgNoiseInLastFrame / nrgWhiteNoise ) */
1858 973 : tmp = div_s( num16, den16 ); // Q: 15+(2*(15-hTonalMDCTConc->lastBlockData.spectralData_exp)+exp1-48)-(exp2-48)
1859 973 : exp = sub( sub( shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ), 30 ), sub( exp1, exp2 ) ); // exp of tmp
1860 973 : tmp = Sqrt16( tmp, &exp );
1861 973 : g = mult_r( g, tmp ); // exponent of g = exp
1862 : }
1863 :
1864 973 : exp1 = add( *mdctSpectrum_exp, exp );
1865 973 : exp2 = add( hTonalMDCTConc->lastBlockData.spectralData_exp, e_crossfadeGain );
1866 973 : exp = add( s_max( exp1, exp2 ), 1 );
1867 973 : shift1 = sub( exp1, exp );
1868 973 : shift2 = sub( exp2, exp );
1869 :
1870 274111 : FOR( i = 0; i < crossOverFreq; i++ )
1871 : {
1872 273138 : L_tmp1 = L_shl( Mpy_32_16_1( mdctSpectrum[i], g ), shift1 ); // g * mdctSpectrum[i]
1873 273138 : L_tmp2 = L_shl( L_mult( crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData[i] ), shift2 ); // exp
1874 :
1875 : /* mdctSpectrum[i] = g * mdctSpectrum[i] - crossfadeGain * hTonalMDCTConc->lastBlockData.spectralData[i]; */
1876 273138 : L_tmp = L_sub( L_tmp1, L_tmp2 ); // exp
1877 273138 : if ( mdctSpectrum[i] > 0 )
1878 : {
1879 : /* mdctSpectrum[i] = g * mdctSpectrum[i] + crossfadeGain * hTonalMDCTConc->lastBlockData.spectralData[i]; */
1880 140817 : L_tmp = L_add( L_tmp1, L_tmp2 ); // exp
1881 : }
1882 273138 : mdctSpectrum[i] = L_shr( L_tmp, 31 - SPEC_EXP_DEC ); // exp+31-SPEC_EXP_DEC
1883 273138 : move32();
1884 : }
1885 : /* headroom for mdct_shaping */
1886 973 : *mdctSpectrum_exp = add( exp, 31 - SPEC_EXP_DEC );
1887 973 : move16();
1888 : }
1889 : }
1890 5109 : exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, *mdctSpectrum_exp );
1891 1312803 : FOR( i = crossOverFreq; i < hTonalMDCTConc->lastBlockData.nSamples; i++ )
1892 : {
1893 1307694 : mdctSpectrum[i] = L_shl( L_deposit_h( hTonalMDCTConc->lastBlockData.spectralData[i] ), exp ); // mdctSpectrum_exp
1894 1307694 : move32();
1895 : }
1896 : }
1897 : ELSE
1898 : {
1899 397 : assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
1900 3167 : FOR( l = hTonalMDCTConc->pTCI->lowerIndex[0]; l <= hTonalMDCTConc->pTCI->upperIndex[0]; l++ )
1901 : {
1902 2770 : mdctSpectrum[l] = L_deposit_l( 0 );
1903 : }
1904 :
1905 397 : ld = sub( 14, norm_s( hTonalMDCTConc->lastBlockData.nSamples ) );
1906 397 : fac = shr( -32768, ld );
1907 24550 : FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
1908 : {
1909 24153 : Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
1910 24153 : move16();
1911 : Word32 y;
1912 :
1913 24153 : rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
1914 24153 : y = L_mult( tilt, rnd ); // 15Q16
1915 :
1916 24153 : nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - x_exp - ld) + Q(15 - x_exp) - 15 = Q(31 - x_exp * 2 - ld)
1917 24153 : x = round_fx( y ); // 15Q16 -> Q15
1918 24153 : nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - (15 - 0) - ld) + Q(0) - 15 = Q(1 - ld)
1919 :
1920 24153 : mdctSpectrum[l] = y; /* 15Q16 L_deposit_l(y);*/
1921 24153 : move32();
1922 :
1923 24153 : tilt = mult_r( tilt, tiltFactor ); /* Q15 */
1924 : }
1925 :
1926 1923 : FOR( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
1927 : {
1928 1526 : tmp = round_fx( BASOP_Util_fPow( L_deposit_h( tiltFactor ), 0, L_deposit_h( (UWord16) L_add( L_sub( hTonalMDCTConc->pTCI->upperIndex[i - 1], hTonalMDCTConc->pTCI->lowerIndex[i - 1] ), 1 ) ), 15, &exp ) );
1929 1526 : tmp = shl_sat( tmp, exp );
1930 1526 : tilt = mult_r( tilt, tmp ); // Q15
1931 :
1932 12178 : FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
1933 : {
1934 10652 : mdctSpectrum[l] = L_deposit_l( 0 );
1935 10652 : move32();
1936 : }
1937 26972 : FOR( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
1938 : {
1939 25446 : Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
1940 25446 : move16();
1941 : Word32 y;
1942 :
1943 25446 : rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
1944 25446 : y = L_mult( tilt, rnd ); // 15Q16
1945 :
1946 25446 : nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - hTonalMDCTConc->lastBlockData.spectralData_exp * 2 - ld)
1947 25446 : x = round_fx( y ); // Q15
1948 25446 : nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(1 - ld)
1949 :
1950 25446 : mdctSpectrum[l] = y; /* 15Q16 L_deposit_l(y);*/
1951 25446 : move32();
1952 :
1953 25446 : tilt = mult_r( tilt, tiltFactor ); // Q15
1954 : }
1955 : }
1956 :
1957 397 : tmp = round_fx( BASOP_Util_fPow( L_deposit_h( tiltFactor ), 0,
1958 397 : L_deposit_h( extract_l( L_add( L_sub( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ), 1 ) ) ), 15, &exp ) );
1959 : BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/
1960 397 : tmp = shl_sat( tmp, exp );
1961 : BASOP_SATURATE_WARNING_ON_EVS
1962 397 : tilt = mult_r( tilt, tmp );
1963 :
1964 107120 : FOR( l = add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ); l < crossOverFreq; l++ )
1965 : {
1966 106723 : Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
1967 106723 : move16();
1968 : Word32 y;
1969 106723 : rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
1970 106723 : y = L_mult( tilt, rnd ); // 15Q16
1971 :
1972 106723 : nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - hTonalMDCTConc->lastBlockData.spectralData_exp * 2 - ld)
1973 106723 : x = round_fx( y ); // Q15
1974 106723 : nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(1 - ld)
1975 :
1976 106723 : mdctSpectrum[l] = y; /* 15Q16 L_deposit_l(y);*/
1977 106723 : move32();
1978 :
1979 106723 : tilt = mult_r( tilt, tiltFactor ); // Q15
1980 : }
1981 :
1982 397 : IF( EQ_32( nrgNoiseInLastFrame, 0 ) )
1983 : {
1984 0 : set32_fx( mdctSpectrum, 0, crossOverFreq );
1985 0 : *mdctSpectrum_exp = SPEC_EXP_DEC;
1986 0 : move16();
1987 : }
1988 : ELSE
1989 : {
1990 397 : exp_last = add( ld, shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) );
1991 397 : exp_noise = add( ld, shl( 15, 1 ) );
1992 :
1993 397 : ld = norm_l( nrgNoiseInLastFrame );
1994 397 : nrgNoiseInLastFrame = L_shl( nrgNoiseInLastFrame, ld ); // Q31-exp_last+ld
1995 397 : exp_last = sub( exp_last, ld );
1996 397 : ld = norm_l( nrgWhiteNoise );
1997 397 : nrgWhiteNoise = L_shl( nrgWhiteNoise, ld ); // Q31 - exp_noise + ld
1998 397 : exp_noise = sub( exp_noise, ld );
1999 :
2000 397 : exp = sub( exp_last, exp_noise );
2001 :
2002 397 : IF( GT_32( nrgNoiseInLastFrame, nrgWhiteNoise ) )
2003 : {
2004 215 : nrgNoiseInLastFrame = L_shr( nrgNoiseInLastFrame, 1 ); // Q31 - Qexp -1
2005 215 : exp = add( exp, 1 );
2006 : }
2007 397 : tmp = div_l( nrgNoiseInLastFrame, extract_h( nrgWhiteNoise ) );
2008 397 : tmp = Sqrt16( tmp, &exp );
2009 397 : g = mult_r( g, tmp );
2010 :
2011 397 : L_tmp = L_deposit_h( 0 );
2012 397 : ld = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, 15 );
2013 397 : exp = sub( ld, exp );
2014 397 : IF( exp > 0 )
2015 : {
2016 397 : g = shr( g, exp ); // Q15 - exp
2017 397 : *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
2018 397 : move16();
2019 : }
2020 : ELSE
2021 : {
2022 0 : crossfadeGain = shl( crossfadeGain, exp );
2023 0 : e_crossfadeGain = sub( e_crossfadeGain, exp );
2024 0 : *mdctSpectrum_exp = add( e_crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData_exp );
2025 0 : move16();
2026 : }
2027 : /*make a headroom for mdct_shaping*/
2028 397 : exp = sub( *mdctSpectrum_exp, SPEC_EXP_DEC );
2029 :
2030 397 : IF( exp < 0 )
2031 : {
2032 397 : *mdctSpectrum_exp = SPEC_EXP_DEC;
2033 397 : move16();
2034 : }
2035 : ELSE
2036 : {
2037 0 : exp = 0;
2038 0 : move16();
2039 : }
2040 :
2041 24550 : FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
2042 : {
2043 24153 : Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
2044 24153 : move16();
2045 24153 : Word32 const y = mdctSpectrum[l]; // Q31-mdctSpectrum_exp
2046 24153 : move32();
2047 :
2048 24153 : IF( g > 0 )
2049 : {
2050 5404 : L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
2051 : }
2052 :
2053 24153 : L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2054 24153 : IF( y > 0 )
2055 : {
2056 12487 : L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2057 : }
2058 24153 : mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
2059 24153 : move32();
2060 : }
2061 :
2062 1923 : FOR( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
2063 : {
2064 26972 : FOR( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
2065 : {
2066 25446 : Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
2067 25446 : move16();
2068 25446 : Word32 const y = mdctSpectrum[l]; // Q31-mdctSpectrum_exp
2069 25446 : move32();
2070 :
2071 25446 : IF( g > 0 )
2072 : {
2073 4335 : L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
2074 : }
2075 :
2076 25446 : L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2077 25446 : IF( y > 0 )
2078 : {
2079 14110 : L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2080 : }
2081 25446 : mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
2082 25446 : move32();
2083 : }
2084 : }
2085 :
2086 : /* initialize bins of tonal components with zero: basically not
2087 : necessary, but currently the whole spectrum is rescaled in
2088 : mdct_noiseShaping() and then there would be a processing of
2089 : uninitialized values */
2090 2320 : FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
2091 : {
2092 15345 : FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
2093 : {
2094 13422 : mdctSpectrum[l] = L_deposit_l( 0 );
2095 13422 : move32();
2096 : }
2097 : }
2098 :
2099 107120 : FOR( l = add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ); l < crossOverFreq; l++ )
2100 : {
2101 106723 : Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
2102 106723 : move16();
2103 106723 : Word32 const y = mdctSpectrum[l]; // Q31-mdctSpectrum_exp
2104 106723 : move32();
2105 :
2106 106723 : IF( GT_16( g, 0 ) )
2107 : {
2108 18572 : L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
2109 : }
2110 :
2111 106723 : L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2112 106723 : IF( GT_32( y, 0 ) )
2113 : {
2114 52645 : L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2115 : }
2116 106723 : mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
2117 106723 : move32();
2118 : }
2119 : }
2120 397 : exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, sub( *mdctSpectrum_exp, 16 ) );
2121 176253 : FOR( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
2122 : {
2123 175856 : mdctSpectrum[l] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), exp ); // Q15 - spectralData_exp
2124 175856 : move32();
2125 : }
2126 : }
2127 : }
2128 :
2129 8707 : *pSeed = rnd;
2130 8707 : move16();
2131 :
2132 8707 : pop_wmops();
2133 :
2134 8707 : return;
2135 : }
2136 :
2137 :
2138 0 : void TonalMDCTConceal_InsertNoise(
2139 : const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */
2140 : Word32 *mdctSpectrum, // Q31- *mdctSpectrum_exp /*OUT*/
2141 : Word16 *mdctSpectrum_exp, /*OUT*/
2142 : const Word16 tonalConcealmentActive,
2143 : Word16 *pSeed, /*IN/OUT*/
2144 : const Word16 tiltCompFactor, // Q15
2145 : Word16 crossfadeGain, // Q15
2146 : const Word16 crossOverFreq )
2147 : {
2148 : Word16 i, ld, fac;
2149 : Word16 rnd, exp, exp_last, exp_noise, inv_samples, inv_exp;
2150 : Word16 g, tiltFactor, tilt, tmp;
2151 : Word32 nrgNoiseInLastFrame, nrgWhiteNoise, L_tmp, L_tmp2;
2152 :
2153 0 : g = sub( 32767 /*1.0f Q15*/, crossfadeGain );
2154 :
2155 0 : rnd = 1977;
2156 0 : move16();
2157 0 : if ( hTonalMDCTConc->lastBlockData.blockIsConcealed )
2158 : {
2159 0 : rnd = *pSeed;
2160 0 : move16();
2161 : }
2162 0 : IF( hTonalMDCTConc->lastBlockData.blockIsValid == 0 )
2163 : {
2164 : /* may just become active if the very first frame is lost */
2165 0 : set32_fx( mdctSpectrum, 0, hTonalMDCTConc->nSamples );
2166 0 : *mdctSpectrum_exp = SPEC_EXP_DEC;
2167 0 : move16();
2168 : }
2169 : ELSE
2170 : {
2171 0 : L_tmp = 805306368l /*0.375f Q31*/;
2172 0 : move32();
2173 0 : inv_exp = 15;
2174 0 : move16();
2175 0 : inv_samples = Inv16( hTonalMDCTConc->lastBlockData.nSamples, &inv_exp );
2176 0 : tiltFactor = round_fx( BASOP_Util_fPow( L_max( L_tmp, L_deposit_h( tiltCompFactor ) ), 0, L_deposit_h( inv_samples ), inv_exp, &exp ) );
2177 : BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/
2178 0 : tiltFactor = shl_sat( tiltFactor, exp ); // Q15- 2*exp
2179 : BASOP_SATURATE_WARNING_ON_EVS
2180 :
2181 0 : tilt = 32767 /*1.0f Q15*/;
2182 0 : move16();
2183 :
2184 0 : nrgNoiseInLastFrame = L_deposit_h( 0 );
2185 0 : nrgWhiteNoise = L_deposit_h( 0 );
2186 0 : exp_last = exp_noise = 0;
2187 0 : move16();
2188 0 : move16();
2189 0 : IF( !tonalConcealmentActive )
2190 : {
2191 0 : ld = sub( 14, norm_s( hTonalMDCTConc->lastBlockData.nSamples ) );
2192 0 : fac = shr( -32768, ld );
2193 :
2194 0 : FOR( i = 0; i < crossOverFreq; i++ )
2195 : {
2196 0 : Word16 x = hTonalMDCTConc->lastBlockData.spectralData[i]; // Q15 - spectralData_exp
2197 0 : move16();
2198 : Word32 y;
2199 0 : rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
2200 0 : y = L_mult( tilt, rnd ); /* 15Q16 */
2201 :
2202 0 : nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - hTonalMDCTConc->lastBlockData.spectralData_exp * 2 - ld)
2203 0 : x = round_fx( y ); // Q15
2204 0 : nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(1 - ld)
2205 :
2206 0 : mdctSpectrum[i] = y; /* 15Q16 */
2207 0 : move32();
2208 :
2209 0 : tilt = mult_r( tilt, tiltFactor ); // Q15
2210 : }
2211 :
2212 0 : IF( nrgNoiseInLastFrame == 0 )
2213 : {
2214 0 : set32_fx( mdctSpectrum, 0, crossOverFreq );
2215 0 : *mdctSpectrum_exp = SPEC_EXP_DEC;
2216 0 : move16();
2217 : }
2218 : ELSE
2219 : {
2220 0 : exp_last = add( ld, shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) );
2221 0 : exp_noise = add( ld, 30 );
2222 :
2223 0 : IF( nrgWhiteNoise > 0 )
2224 : {
2225 0 : ld = norm_l( nrgNoiseInLastFrame );
2226 0 : nrgNoiseInLastFrame = L_shl( nrgNoiseInLastFrame, ld ); // Q31-exp_last + ld
2227 0 : exp_last = sub( exp_last, ld );
2228 0 : ld = norm_l( nrgWhiteNoise );
2229 0 : nrgWhiteNoise = L_shl( nrgWhiteNoise, ld ); // Q31-exp_noise + ld
2230 0 : exp_noise = sub( exp_noise, ld );
2231 :
2232 0 : exp = sub( exp_last, exp_noise );
2233 :
2234 0 : IF( GT_32( nrgNoiseInLastFrame, nrgWhiteNoise ) )
2235 : {
2236 0 : nrgNoiseInLastFrame = L_shr( nrgNoiseInLastFrame, 1 ); // Q31- exp - 1
2237 0 : exp = add( exp, 1 );
2238 : }
2239 0 : tmp = div_l( nrgNoiseInLastFrame, round_fx( nrgWhiteNoise ) );
2240 0 : tmp = Sqrt16( tmp, &exp );
2241 0 : g = mult_r( g, tmp );
2242 :
2243 0 : L_tmp = L_deposit_h( 0 );
2244 0 : ld = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, 15 );
2245 0 : exp = sub( ld, exp );
2246 :
2247 0 : IF( exp > 0 )
2248 : {
2249 0 : g = shr( g, exp );
2250 0 : *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
2251 0 : move16();
2252 : }
2253 : ELSE
2254 : {
2255 0 : crossfadeGain = shl( crossfadeGain, exp );
2256 0 : *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp );
2257 : }
2258 : /*make a headroom for mdct_shaping*/
2259 0 : exp = sub( *mdctSpectrum_exp, SPEC_EXP_DEC );
2260 : /* assert(exp < 0);*/
2261 0 : IF( exp < 0 )
2262 : {
2263 0 : *mdctSpectrum_exp = SPEC_EXP_DEC;
2264 0 : move16();
2265 : }
2266 : ELSE
2267 : {
2268 0 : exp = 0;
2269 0 : move16();
2270 : }
2271 : }
2272 :
2273 0 : FOR( i = 0; i < crossOverFreq; i++ )
2274 : {
2275 0 : Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[i];
2276 0 : move16();
2277 0 : Word32 const y = mdctSpectrum[i]; // Q31-mdctSpectrum_exp
2278 0 : move32();
2279 :
2280 0 : if ( g > 0 )
2281 : {
2282 0 : L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
2283 : }
2284 :
2285 0 : L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2286 0 : if ( y > 0 )
2287 : {
2288 0 : L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2289 : }
2290 0 : mdctSpectrum[i] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
2291 0 : move32();
2292 : }
2293 : }
2294 0 : exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, sub( *mdctSpectrum_exp, 16 ) );
2295 0 : FOR( i = crossOverFreq; i < hTonalMDCTConc->lastBlockData.nSamples; i++ )
2296 : {
2297 0 : mdctSpectrum[i] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[i] ), exp ); // Q15 - spectralData_exp + exp
2298 0 : move32();
2299 : }
2300 : }
2301 : ELSE
2302 : {
2303 : Word16 l;
2304 0 : assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
2305 :
2306 0 : FOR( l = hTonalMDCTConc->pTCI->lowerIndex[0]; l <= hTonalMDCTConc->pTCI->upperIndex[0]; l++ )
2307 : {
2308 0 : mdctSpectrum[l] = L_deposit_l( 0 );
2309 0 : move32();
2310 : }
2311 :
2312 0 : ld = sub( 14, norm_s( hTonalMDCTConc->lastBlockData.nSamples ) );
2313 0 : fac = shr( -32768, ld );
2314 0 : FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
2315 : {
2316 0 : Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
2317 0 : move16();
2318 : Word32 y;
2319 0 : rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
2320 0 : y = L_mult( tilt, rnd ); // 15Q16
2321 :
2322 0 : nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - hTonalMDCTConc->lastBlockData.spectralData_exp * 2 - ld)
2323 0 : x = round_fx( y ); // Q15
2324 0 : nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(1-ld)
2325 :
2326 0 : mdctSpectrum[l] = y; /* 15Q16 L_deposit_l(y);*/
2327 0 : move32();
2328 :
2329 0 : tilt = mult_r( tilt, tiltFactor ); // Q15
2330 : }
2331 :
2332 0 : FOR( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
2333 : {
2334 : /*tilt *= (float)pow(tiltFactor, hTonalMDCTConc->pTCI->upperIndex[i-1]-hTonalMDCTConc->pTCI->lowerIndex[i-1]+1);*/
2335 0 : tmp = round_fx( BASOP_Util_fPow( L_deposit_h( tiltFactor ), 0, L_deposit_h( (UWord16) L_add( L_sub( hTonalMDCTConc->pTCI->upperIndex[i - 1], hTonalMDCTConc->pTCI->lowerIndex[i - 1] ), 1 ) ), 15, &exp ) );
2336 0 : tmp = shl( tmp, exp );
2337 0 : tilt = mult_r( tilt, tmp );
2338 :
2339 0 : FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
2340 : {
2341 0 : mdctSpectrum[l] = L_deposit_l( 0 );
2342 0 : move32();
2343 : }
2344 :
2345 0 : FOR( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
2346 : {
2347 0 : Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
2348 0 : move16();
2349 : Word32 y;
2350 0 : rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
2351 0 : y = L_mult( tilt, rnd ); // 15Q16
2352 :
2353 0 : nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - hTonalMDCTConc->lastBlockData.spectralData_exp * 2 - ld)
2354 0 : x = round_fx( y ); // Q15
2355 0 : nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(1-ld)
2356 :
2357 0 : mdctSpectrum[l] = y; /* 15Q16 L_deposit_l(y);*/
2358 0 : move32();
2359 :
2360 0 : tilt = mult_r( tilt, tiltFactor ); // Q15
2361 : }
2362 : }
2363 :
2364 0 : tmp = round_fx( BASOP_Util_fPow( L_deposit_h( tiltFactor ), 0, L_deposit_h( (UWord16) L_add( L_sub( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ), 1 ) ), 15, &exp ) );
2365 : BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/
2366 0 : tmp = shl_sat( tmp, exp ); // Q15 - 2*exp
2367 : BASOP_SATURATE_WARNING_ON_EVS
2368 0 : tilt = mult_r( tilt, tmp );
2369 :
2370 0 : FOR( l = add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ); l < crossOverFreq; l++ )
2371 : {
2372 0 : Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
2373 0 : move16();
2374 : Word32 y;
2375 0 : rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
2376 0 : y = L_mult( tilt, rnd ); // 15Q16
2377 :
2378 0 : nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - hTonalMDCTConc->lastBlockData.spectralData_exp * 2 - ld)
2379 0 : x = round_fx( y ); // Q15
2380 0 : nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(1-ld)
2381 :
2382 0 : mdctSpectrum[l] = y; /* 15Q16 L_deposit_l(y);*/
2383 0 : move32();
2384 :
2385 0 : tilt = mult_r( tilt, tiltFactor ); // Q15
2386 : }
2387 :
2388 0 : IF( nrgNoiseInLastFrame == 0 )
2389 : {
2390 0 : set32_fx( mdctSpectrum, 0, crossOverFreq );
2391 0 : *mdctSpectrum_exp = SPEC_EXP_DEC;
2392 0 : move16();
2393 : }
2394 : ELSE
2395 : {
2396 0 : exp_last = add( ld, shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) );
2397 0 : exp_noise = add( ld, shl( 15, 1 ) );
2398 :
2399 0 : ld = norm_l( nrgNoiseInLastFrame );
2400 0 : nrgNoiseInLastFrame = L_shl( nrgNoiseInLastFrame, ld ); // Q31 - exp_last + ld
2401 0 : exp_last = sub( exp_last, ld );
2402 0 : ld = norm_l( nrgWhiteNoise );
2403 0 : nrgWhiteNoise = L_shl( nrgWhiteNoise, ld ); // Q31 - exp_last + ld
2404 0 : exp_noise = sub( exp_noise, ld );
2405 :
2406 0 : exp = sub( exp_last, exp_noise );
2407 :
2408 0 : IF( GT_32( nrgNoiseInLastFrame, nrgWhiteNoise ) )
2409 : {
2410 0 : nrgNoiseInLastFrame = L_shr( nrgNoiseInLastFrame, 1 ); // Q31 - exp -1
2411 0 : exp = add( exp, 1 );
2412 : }
2413 0 : tmp = div_l( nrgNoiseInLastFrame, round_fx( nrgWhiteNoise ) );
2414 0 : tmp = Sqrt16( tmp, &exp );
2415 0 : g = mult_r( g, tmp );
2416 :
2417 0 : L_tmp = L_deposit_h( 0 );
2418 0 : ld = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, 15 );
2419 0 : exp = sub( ld, exp );
2420 0 : IF( exp > 0 )
2421 : {
2422 0 : g = shr( g, exp );
2423 0 : *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
2424 0 : move16();
2425 : }
2426 : ELSE
2427 : {
2428 0 : crossfadeGain = shl( crossfadeGain, exp );
2429 0 : *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp );
2430 : }
2431 : /*make a headroom for mdct_shaping*/
2432 0 : exp = sub( *mdctSpectrum_exp, SPEC_EXP_DEC );
2433 :
2434 :
2435 0 : IF( exp < 0 )
2436 : {
2437 0 : *mdctSpectrum_exp = SPEC_EXP_DEC;
2438 0 : move16();
2439 : }
2440 : ELSE
2441 : {
2442 0 : exp = 0;
2443 0 : move16();
2444 : }
2445 :
2446 0 : FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
2447 : {
2448 0 : Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
2449 0 : move16();
2450 0 : Word32 const y = mdctSpectrum[l]; // Q31-mdctSpectrum_exp
2451 0 : move32();
2452 :
2453 0 : if ( g > 0 )
2454 : {
2455 0 : L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
2456 : }
2457 :
2458 0 : L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2459 0 : if ( y > 0 )
2460 : {
2461 0 : L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2462 : }
2463 0 : mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
2464 0 : move32();
2465 : }
2466 :
2467 0 : FOR( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
2468 : {
2469 0 : FOR( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
2470 : {
2471 0 : Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
2472 0 : move16();
2473 0 : Word32 const y = mdctSpectrum[l]; // Q31-mdctSpectrum_exp
2474 0 : move32();
2475 :
2476 0 : if ( g > 0 )
2477 : {
2478 0 : L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
2479 : }
2480 :
2481 0 : L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2482 0 : if ( y > 0 )
2483 : {
2484 0 : L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2485 : }
2486 0 : mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
2487 0 : move32();
2488 : }
2489 : }
2490 :
2491 : /* initialize bins of tonal components with zero: basically not
2492 : necessary, but currently the whole spectrum is rescaled in
2493 : mdct_noiseShaping() and then there would be a processing of
2494 : uninitialized values */
2495 0 : FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
2496 : {
2497 0 : FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
2498 : {
2499 0 : mdctSpectrum[l] = L_deposit_l( 0 );
2500 0 : move32();
2501 : }
2502 : }
2503 :
2504 0 : FOR( l = add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ); l < crossOverFreq; l++ )
2505 : {
2506 0 : Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
2507 0 : move16();
2508 0 : Word32 const y = mdctSpectrum[l]; // Q31-mdctSpectrum_exp
2509 0 : move32();
2510 :
2511 0 : if ( g > 0 )
2512 : {
2513 0 : L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
2514 : }
2515 :
2516 0 : L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2517 0 : if ( y > 0 )
2518 : {
2519 0 : L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
2520 : }
2521 0 : mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
2522 0 : move32();
2523 : }
2524 : }
2525 0 : exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, sub( *mdctSpectrum_exp, 16 ) );
2526 0 : FOR( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
2527 : {
2528 0 : mdctSpectrum[l] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), exp ); // Q15 - spectralData_exp + exp
2529 0 : move32();
2530 : }
2531 : }
2532 : }
2533 :
2534 0 : *pSeed = rnd;
2535 0 : move16();
2536 :
2537 0 : return;
2538 : }
2539 :
2540 0 : void TonalMDCTConceal_Apply(
2541 : const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */
2542 : Word32 *mdctSpectrum, // Q31-*mdctSpectrum_exp /*IN/OUT*/
2543 : Word16 *mdctSpectrum_exp /*IN */
2544 : )
2545 : {
2546 : Word16 i, l, exp;
2547 : Word16 *phaseDiff, *pCurrentPhase;
2548 : Word32 phaseToAdd, currentPhase;
2549 : Word32 powerSpectrum[L_FRAME_MAX];
2550 : Word16 nSamples;
2551 :
2552 :
2553 0 : IF( s_and( hTonalMDCTConc->lastBlockData.blockIsValid, hTonalMDCTConc->secondLastBlockData.blockIsValid ) )
2554 : {
2555 0 : assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
2556 :
2557 0 : nSamples = hTonalMDCTConc->nNonZeroSamples;
2558 0 : move16();
2559 0 : assert( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] < nSamples );
2560 :
2561 : {
2562 :
2563 0 : mdct_shaping_16( hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamplesCore, nSamples,
2564 0 : hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp,
2565 0 : hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e, powerSpectrum );
2566 : }
2567 0 : phaseDiff = hTonalMDCTConc->pTCI->phaseDiff; /* if multiple frame loss occurs use the phase from the last frame and continue rotating */
2568 0 : pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
2569 :
2570 0 : exp = sub( *mdctSpectrum_exp, add( add( hTonalMDCTConc->secondLastPowerSpectrum_exp, add( hTonalMDCTConc->secondLastBlockData.gain_tcx_exp, 1 ) ), hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e ) );
2571 :
2572 0 : IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
2573 : {
2574 0 : if ( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive != 0 )
2575 : {
2576 0 : hTonalMDCTConc->nFramesLost = add( hTonalMDCTConc->nFramesLost, 2 ); /*Q1*/
2577 0 : move16();
2578 : }
2579 0 : if ( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive == 0 )
2580 : {
2581 0 : hTonalMDCTConc->nFramesLost = 3; /*Q1*/
2582 0 : move16();
2583 : }
2584 : }
2585 : /* for each index group */
2586 0 : FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
2587 : {
2588 : /*phaseToAdd = hTonalMDCTConc->nFramesLost*phaseDiff[i]; */
2589 0 : phaseToAdd = L_mult0( hTonalMDCTConc->nFramesLost, phaseDiff[i] ); /*Q1*3Q12=2Q13*/
2590 : /* Move phaseToAdd to range -PI..PI */
2591 :
2592 0 : WHILE( GT_32( phaseToAdd, 25736l /*EVS_PI Q13*/ ) )
2593 : {
2594 0 : phaseToAdd = L_sub( phaseToAdd, 51472l /*2*EVS_PI Q13*/ );
2595 : }
2596 0 : WHILE( LT_32( phaseToAdd, -25736l /*-EVS_PI Q13*/ ) )
2597 : {
2598 0 : phaseToAdd = L_add( phaseToAdd, 51472l /*2*EVS_PI Q13*/ );
2599 : }
2600 :
2601 0 : FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
2602 : {
2603 : /* *pCurrentPhase and phaseToAdd are in range -PI..PI */
2604 0 : currentPhase = L_mac0( phaseToAdd, ( *pCurrentPhase++ ), 1 ); /*2Q13+2Q13=3Q13*/
2605 :
2606 0 : if ( GT_32( currentPhase, 25736l /*EVS_PI Q13*/ ) )
2607 : {
2608 0 : currentPhase = L_sub( currentPhase, 51472l /*2*EVS_PI Q13*/ );
2609 : }
2610 0 : if ( LT_32( currentPhase, -25736l /*-EVS_PI Q13*/ ) )
2611 : {
2612 0 : currentPhase = L_add( currentPhase, 51472l /*2*EVS_PI Q13*/ );
2613 : }
2614 : /* getCosWord16 returns 1Q14*/
2615 0 : mdctSpectrum[l] = Mpy_32_16_1( powerSpectrum[l], getCosWord16( extract_l( currentPhase ) ) );
2616 0 : move32();
2617 0 : mdctSpectrum[l] = L_shr( mdctSpectrum[l], exp );
2618 0 : move32();
2619 : }
2620 : }
2621 : }
2622 :
2623 0 : hTonalMDCTConc->nFramesLost = add( hTonalMDCTConc->nFramesLost, 2 ); /*Q1*/
2624 0 : move16();
2625 :
2626 0 : return;
2627 : }
2628 :
2629 495 : void TonalMDCTConceal_Apply_ivas_fx(
2630 : TonalMDCTConcealPtr hTonalMDCTConc, /*IN */
2631 : Word32 *mdctSpectrum, // Q31-*mdctSpectrum_exp /*IN/OUT*/
2632 : Word16 mdctSpectrum_exp, /*IN */
2633 : const PsychoacousticParameters *psychParamsCurrent )
2634 :
2635 : {
2636 : Word16 i, l;
2637 : Word16 *phaseDiff, *pCurrentPhase;
2638 : Word32 phaseToAdd;
2639 : Word32 powerSpectrum[L_FRAME_MAX];
2640 : Word16 powerSpectrum_exp;
2641 : Word32 scaleFactors[FDNS_NPTS];
2642 : Word16 nSamples;
2643 : Word16 nBands;
2644 :
2645 495 : Word16 *tmp_secondLastPowerSpectrum = hTonalMDCTConc->secondLastPowerSpectrum;
2646 495 : Word16 tmp_secondLastPowerSpectrum_exp = hTonalMDCTConc->secondLastPowerSpectrum_exp;
2647 495 : move16();
2648 :
2649 495 : Word16 max_nSamples = s_max( hTonalMDCTConc->nNonZeroSamples, hTonalMDCTConc->nSamplesCore );
2650 :
2651 : // To avoid garbage values
2652 495 : set32_fx( powerSpectrum, 0, L_FRAME_MAX );
2653 :
2654 : /* Creating 32-bit scaleFactors with common exponent. */
2655 32175 : FOR( i = 0; i < FDNS_NPTS; i++ )
2656 : {
2657 31680 : scaleFactors[i] = L_shr( L_deposit_h( hTonalMDCTConc->secondLastBlockData.scaleFactors[i] ), sub( hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp[i] ) ); // Q31- scaleFactors_max_e+scaleFactors_exp[i]
2658 31680 : move32();
2659 : }
2660 :
2661 495 : IF( s_and( hTonalMDCTConc->lastBlockData.blockIsValid, hTonalMDCTConc->secondLastBlockData.blockIsValid ) )
2662 : {
2663 495 : assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
2664 :
2665 495 : nSamples = hTonalMDCTConc->nNonZeroSamples;
2666 495 : move16();
2667 495 : assert( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] < nSamples );
2668 :
2669 268431 : FOR( i = 0; i < nSamples; i++ )
2670 : {
2671 267936 : powerSpectrum[i] = L_deposit_h( tmp_secondLastPowerSpectrum[i] ); // Q31 - secondLastPowerSpectrum_exp
2672 267936 : move16();
2673 : }
2674 495 : powerSpectrum_exp = tmp_secondLastPowerSpectrum_exp;
2675 495 : move16();
2676 :
2677 495 : Word16 exp1 = powerSpectrum_exp;
2678 495 : move16();
2679 :
2680 495 : IF( psychParamsCurrent == NULL )
2681 : {
2682 201 : nBands = FDNS_NPTS;
2683 201 : move16();
2684 201 : mdct_noiseShaping_ivas_fx( powerSpectrum, &powerSpectrum_exp, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors,
2685 201 : hTonalMDCTConc->secondLastBlockData.scaleFactors_exp );
2686 : }
2687 : ELSE
2688 : {
2689 : Word16 q_ps, q_sf;
2690 294 : q_ps = sub( 31, powerSpectrum_exp );
2691 294 : q_sf = sub( 31, hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e );
2692 :
2693 : /* adding guard bit */
2694 294 : q_ps = sub( q_ps, 1 );
2695 163942 : FOR( Word16 c = 0; c < hTonalMDCTConc->nSamplesCore; c++ )
2696 : {
2697 163648 : powerSpectrum[c] = L_shr( powerSpectrum[c], 1 ); // q_ps -1
2698 163648 : move32();
2699 : }
2700 :
2701 : /* adding guard bit */
2702 294 : q_sf = sub( q_sf, 1 );
2703 19110 : FOR( Word16 c = 0; c < FDNS_NPTS; c++ )
2704 : {
2705 18816 : scaleFactors[c] = L_shr( scaleFactors[c], 1 ); // q_sf - 1
2706 18816 : move32();
2707 : }
2708 :
2709 294 : sns_shape_spectrum_fx( powerSpectrum, &q_ps, psychParamsCurrent, scaleFactors, q_sf, hTonalMDCTConc->nSamplesCore, NULL );
2710 :
2711 294 : powerSpectrum_exp = sub( 31, add( q_ps, 1 ) );
2712 :
2713 294 : nBands = psychParamsCurrent->nBands;
2714 294 : move16();
2715 : }
2716 :
2717 495 : Word16 exp_left = powerSpectrum_exp;
2718 495 : move16();
2719 495 : Word16 exp_right = exp1;
2720 495 : move16();
2721 :
2722 52622 : FOR( Word16 c = hTonalMDCTConc->nSamplesCore; c < nSamples; c++ )
2723 : {
2724 52127 : powerSpectrum[c] = Mpy_32_16_1( powerSpectrum[c], hTonalMDCTConc->secondLastBlockData.scaleFactors[nBands - 1] ); // Q31 -(exp_right + scaleFactors_exp[])
2725 52127 : move32();
2726 : }
2727 495 : exp_right = add( exp_right, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp[nBands - 1] );
2728 :
2729 495 : Word16 max_e = s_max( exp_right, exp_left );
2730 280526 : FOR( Word16 c = 0; c < max_nSamples; c++ )
2731 : {
2732 280031 : test();
2733 280031 : test();
2734 280031 : test();
2735 280031 : test();
2736 280031 : IF( GE_16( c, hTonalMDCTConc->nSamplesCore ) && LT_16( c, nSamples ) && GT_16( max_e, exp_right ) )
2737 : {
2738 39424 : powerSpectrum[c] = L_shr( powerSpectrum[c], sub( max_e, exp_right ) ); // Q31-max_e
2739 39424 : move32();
2740 : }
2741 240607 : ELSE IF( ( LT_16( c, hTonalMDCTConc->nSamplesCore ) || GT_16( c, nSamples ) ) && GT_16( max_e, exp_left ) )
2742 : {
2743 30272 : powerSpectrum[c] = L_shr( powerSpectrum[c], sub( max_e, exp_left ) ); // Q31-max_e
2744 30272 : move32();
2745 : }
2746 : }
2747 495 : powerSpectrum_exp = max_e;
2748 495 : move16();
2749 :
2750 495 : phaseDiff = hTonalMDCTConc->pTCI->phaseDiff; /* if multiple frame loss occurs use the phase from the last frame and continue rotating */
2751 495 : pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
2752 :
2753 495 : IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
2754 : {
2755 384 : if ( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive != 0 )
2756 : {
2757 0 : hTonalMDCTConc->nFramesLost = add( hTonalMDCTConc->nFramesLost, 2 ); /*Q1*/
2758 0 : move16();
2759 : }
2760 384 : if ( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive == 0 )
2761 : {
2762 384 : hTonalMDCTConc->nFramesLost = 3; /*Q1*/
2763 384 : move16();
2764 : }
2765 : }
2766 :
2767 : /* for each index group */
2768 3095 : FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
2769 : {
2770 2600 : phaseToAdd = L_mult0( hTonalMDCTConc->nFramesLost, phaseDiff[i] ); /*Q1*3Q12=2Q13*/
2771 :
2772 : /* Move phaseToAdd to range -PI..PI */
2773 3488 : WHILE( GT_32( phaseToAdd, 25736l /*EVS_PI Q13*/ ) )
2774 : {
2775 888 : phaseToAdd = L_sub( phaseToAdd, 51472l /*2*EVS_PI Q13*/ );
2776 : }
2777 4312 : WHILE( LT_32( phaseToAdd, -25736l /*-EVS_PI Q13*/ ) )
2778 : {
2779 1712 : phaseToAdd = L_add( phaseToAdd, 51472l /*2*EVS_PI Q13*/ );
2780 : }
2781 :
2782 20761 : FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
2783 : {
2784 : /* *pCurrentPhase and phaseToAdd are in range -PI..PI */
2785 18161 : Word32 currentPhase = L_mac0( phaseToAdd, ( *pCurrentPhase++ ), 1 ); /*2Q13+2Q13=3Q13*/
2786 18161 : IF( GT_32( currentPhase, 25736l /*EVS_PI Q13*/ ) )
2787 : {
2788 2016 : currentPhase = L_sub( currentPhase, 51472l /*2*EVS_PI Q13*/ );
2789 : }
2790 18161 : IF( LT_32( currentPhase, -25736l /*-EVS_PI Q13*/ ) )
2791 : {
2792 2630 : currentPhase = L_add( currentPhase, 51472l /*2*EVS_PI Q13*/ );
2793 : }
2794 :
2795 : /* getCosWord16 returns 1Q14*/
2796 18161 : mdctSpectrum[l] = Mpy_32_16_1( powerSpectrum[l], getCosWord16( extract_l( currentPhase ) ) );
2797 18161 : move32();
2798 18161 : mdctSpectrum[l] = L_shr( mdctSpectrum[l], sub( mdctSpectrum_exp, add( powerSpectrum_exp, 1 ) ) );
2799 : }
2800 : }
2801 : }
2802 :
2803 495 : hTonalMDCTConc->nFramesLost = add( hTonalMDCTConc->nFramesLost, 2 ); /*Q1*/
2804 495 : move16();
2805 :
2806 495 : return;
2807 : }
2808 :
2809 634 : void TonalMDCTConceal_SaveTimeSignal(
2810 : TonalMDCTConcealPtr hTonalMDCTConc,
2811 : Word16 *timeSignal, // Qx
2812 : Word16 nNewSamples
2813 :
2814 : )
2815 : {
2816 634 : IF( EQ_16( nNewSamples, hTonalMDCTConc->nSamples ) )
2817 : {
2818 634 : assert( nNewSamples <= L_FRAME_MAX );
2819 634 : IF( !hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
2820 : {
2821 634 : Copy( hTonalMDCTConc->lastPcmOut + hTonalMDCTConc->nSamples / 2, hTonalMDCTConc->secondLastPcmOut, hTonalMDCTConc->nSamples / 2 );
2822 : }
2823 634 : Copy( timeSignal, hTonalMDCTConc->lastPcmOut, hTonalMDCTConc->nSamples );
2824 : }
2825 :
2826 634 : return;
2827 : }
2828 898390 : void TonalMDCTConceal_SaveTimeSignal_ivas_fx(
2829 : TonalMDCTConcealPtr hTonalMDCTConc,
2830 : Word16 *timeSignal, // q_timeSignal
2831 : Word16 q_timeSignal,
2832 : Word16 nNewSamples )
2833 : {
2834 898390 : IF( EQ_16( nNewSamples, hTonalMDCTConc->nSamples ) )
2835 : {
2836 882899 : assert( nNewSamples <= L_FRAME_MAX );
2837 882899 : IF( !hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
2838 : {
2839 : Word16 exp, len;
2840 882525 : len = shr( hTonalMDCTConc->nSamples, 1 );
2841 882525 : Copy( hTonalMDCTConc->lastPcmOut + len, hTonalMDCTConc->secondLastPcmOut, len );
2842 882525 : exp = sub( q_timeSignal, hTonalMDCTConc->q_lastPcmOut );
2843 882525 : IF( exp != 0 )
2844 : {
2845 137336 : Scale_sig( hTonalMDCTConc->secondLastPcmOut, len, exp ); // q_timeSignal
2846 : }
2847 : }
2848 882899 : Copy( timeSignal, hTonalMDCTConc->lastPcmOut, hTonalMDCTConc->nSamples );
2849 882899 : hTonalMDCTConc->q_lastPcmOut = q_timeSignal;
2850 882899 : move16();
2851 : }
2852 :
2853 898390 : return;
2854 : }
2855 1598 : static void CalcPowerSpec(
2856 : const Word32 *mdctSpec, /* i: MDCT spectrum Q31-mdctSpec_exp */
2857 : const Word16 mdctSpec_exp, /* i: exponent of MDCT spectrum */
2858 : const Word32 *mdstSpec, /* i: MDST spectrum Q31-mdstSpec_exp */
2859 : const Word16 mdstSpec_exp, /* i: exponent of MDST spectrum */
2860 : const Word16 nSamples, /* i: frame size */
2861 : const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins Q0 */
2862 : Word32 *powerSpec, /* o: power spectrum Q31- powerSpec_exp */
2863 : Word16 *powerSpec_exp ) /* o: exponent of power spectrum */
2864 : {
2865 : Word16 k, s1, s2, tmp;
2866 : Word32 x, L_tmp, L_tmp_floor;
2867 :
2868 :
2869 1598 : k = s_max( mdctSpec_exp, mdstSpec_exp );
2870 1598 : *powerSpec_exp = add( add( k, k ), 3 ); /*extra 3 bits of headroom for MA filter in getEnvelope*/
2871 1598 : move16();
2872 1598 : s1 = sub( *powerSpec_exp, add( mdctSpec_exp, mdctSpec_exp ) );
2873 1598 : s2 = sub( *powerSpec_exp, add( mdstSpec_exp, mdstSpec_exp ) );
2874 :
2875 1598 : k = sub( 31, *powerSpec_exp );
2876 : /* If the signal is bellow floor, special care is needed for *powerSpec_exp */
2877 1598 : IF( LT_16( add( 16 - 3, norm_s( floorPowerSpectrum ) ), k ) ) /*extra 3 bits of headroom for MA filter in getEnvelope*/
2878 : {
2879 111 : k = sub( k, add( 16 - 3, norm_s( floorPowerSpectrum ) ) ); /*extra 3 bits of headroom for MA filter in getEnvelope*/
2880 111 : *powerSpec_exp = add( *powerSpec_exp, k );
2881 111 : s1 = add( s1, k );
2882 111 : s2 = add( s2, k );
2883 111 : k = add( 16 - 3, norm_s( floorPowerSpectrum ) );
2884 : }
2885 1598 : L_tmp_floor = L_shl( L_deposit_l( floorPowerSpectrum ), k );
2886 :
2887 1598 : tmp = sub( nSamples, 2 );
2888 829620 : FOR( k = 1; k <= tmp; k++ )
2889 : {
2890 828022 : x = Mpy_32_32( mdctSpec[k], mdctSpec[k] ); /*Q31,2*mdctSpec_exp*/
2891 :
2892 828022 : L_tmp = Mpy_32_32( mdstSpec[k], mdstSpec[k] ); /*Q31,2*mdstSpec_exp*/
2893 828022 : x = L_add( L_shr( x, s1 ), L_shr( L_tmp, s2 ) ); /*Q31,*powerSpec_exp*/
2894 :
2895 828022 : powerSpec[k] = L_max( L_tmp_floor, x );
2896 828022 : move32();
2897 : }
2898 :
2899 1598 : powerSpec[0] = L_shr( powerSpec[1], 1 );
2900 1598 : move32();
2901 1598 : powerSpec[nSamples - 1] = L_shr( powerSpec[nSamples - 2], 1 );
2902 1598 : move32();
2903 1598 : }
2904 :
2905 :
2906 : /*******************************************************/
2907 : /*-------------- public functions -------------------- */
2908 : /*******************************************************/
2909 :
2910 3201 : void TonalMdctConceal_create_concealment_noise_ivas_fx(
2911 : Word32 concealment_noise[L_FRAME48k], // Q31-concealment_noise_exp
2912 : Word16 *concealment_noise_exp,
2913 : CPE_DEC_HANDLE hCPE,
2914 : const Word16 L_frameTCX, // Q0
2915 : const Word16 L_frame, // Q0
2916 : const Word16 idchan, // Q0
2917 : const Word16 subframe_idx, // Q0
2918 : const Word16 core, // Q0
2919 : const Word16 crossfade_gain, // Q15
2920 : const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode )
2921 : {
2922 : STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct;
2923 : TonalMDCTConcealPtr hTonalMDCTConc;
2924 : Decoder_State *st;
2925 : HANDLE_FD_CNG_COM hFdCngCom;
2926 : Word16 *rnd_c, *rnd;
2927 : Word16 crossOverFreq, i, save_rnd_c, max_noise_line;
2928 : Word16 c, c_inv, inc, inc_log2;
2929 : Word32 noise_shape_buffer[L_FRAME48k];
2930 : Word16 noise_shape_buffer_e[L_FRAME48k];
2931 3201 : Word16 start_idx, stop_idx, noise_shape_buffer_common_exp = MIN16B_FLT_FX, last_scf_e, temp_e;
2932 3201 : move16();
2933 : Word32 *cngNoiseLevelPtr;
2934 : Word32 last_scf;
2935 :
2936 : Word16 c_e, c_inv_e;
2937 :
2938 3201 : push_wmops( "create_conc_noise" );
2939 :
2940 3201 : hStereoMdct = hCPE->hStereoMdct;
2941 3201 : st = hCPE->hCoreCoder[idchan];
2942 3201 : hTonalMDCTConc = st->hTonalMDCTConc;
2943 3201 : hFdCngCom = st->hFdCngDec->hFdCngCom;
2944 3201 : rnd = &hStereoMdct->noise_seeds_channels[idchan];
2945 3201 : rnd_c = &hStereoMdct->noise_seed_common;
2946 :
2947 : /* determine start bin for IGF */
2948 3201 : IF( st->igf == 0 )
2949 : {
2950 1096 : IF( st->narrowBand == 0 )
2951 : {
2952 : /* minimum needed for output with sampling rates lower then the
2953 : nominal sampling rate */
2954 1096 : crossOverFreq = s_min( L_frameTCX, L_frame );
2955 : }
2956 : ELSE
2957 : {
2958 0 : crossOverFreq = L_frameTCX;
2959 0 : move16();
2960 : }
2961 : }
2962 : ELSE
2963 : {
2964 2105 : crossOverFreq = s_min( st->hIGFDec->infoIGFStartLine, L_frameTCX );
2965 : }
2966 :
2967 : /* for tonal mdct concealment with tonal components above the crossover frequency, conditionally raise the frequency index until which noise is generated */
2968 3201 : max_noise_line = crossOverFreq;
2969 3201 : move16();
2970 3201 : IF( st->tonal_mdct_plc_active )
2971 : {
2972 98 : max_noise_line = s_max( max_noise_line, extract_l( L_add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ) ) );
2973 : }
2974 :
2975 : /* first lost frame is handled separately */
2976 3201 : IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
2977 : {
2978 1679 : *rnd = add( 1977, idchan ); // Q0
2979 1679 : move16();
2980 : /* will be set twice when looping over two channels, but does not matter */
2981 1679 : *rnd_c = 1979; // Q0
2982 1679 : move16();
2983 : }
2984 :
2985 3201 : IF( GT_16( crossfade_gain, 32734 ) )
2986 : /* Due to precision loss */ /* 0.999 in Q15*/
2987 : {
2988 : /* In first frame, noise is weighted with zero anyway, we only need the random numbers for the sign scrambling */
2989 657026 : FOR( i = 0; i < max_noise_line; i++ )
2990 : {
2991 655347 : *rnd = own_random( rnd );
2992 655347 : move16();
2993 655347 : concealment_noise[i] = *rnd; // Q31-concealment_noise_exp
2994 655347 : move32();
2995 : }
2996 1679 : *concealment_noise_exp = 31;
2997 1679 : move16();
2998 1679 : pop_wmops();
2999 :
3000 1679 : return;
3001 : }
3002 :
3003 1522 : save_rnd_c = *rnd_c; // Q0
3004 1522 : move16();
3005 :
3006 1522 : c_e = 1;
3007 1522 : move16();
3008 1522 : c_inv_e = 1;
3009 1522 : move16();
3010 :
3011 1522 : c = Sqrt16( hStereoMdct->lastCoh_fx, &c_e ); // Q1 = 15 - c_e
3012 1522 : c_inv = Sqrt16( sub( ONE_IN_Q14, hStereoMdct->lastCoh_fx ), &c_inv_e ); // Q2 = 15 - c_inv_e
3013 :
3014 1522 : IF( NE_16( c_e, c_inv_e ) )
3015 : {
3016 287 : IF( LT_16( c_e, c_inv_e ) )
3017 : {
3018 223 : c = shr( c, sub( c_inv_e, c_e ) ); // Q0
3019 223 : c_e = c_inv_e;
3020 223 : move16();
3021 : }
3022 : ELSE
3023 : {
3024 64 : c_inv = shr( c_inv, sub( c_e, c_inv_e ) ); // Q0
3025 : }
3026 : }
3027 :
3028 : /* pre-compute the noise shape for later weighting of the noise spectra */
3029 1522 : cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0];
3030 1522 : last_scf_e = hFdCngCom->cngNoiseLevelExp;
3031 1522 : move16();
3032 :
3033 1522 : IF( GT_16( st->core, TCX_20_CORE ) )
3034 : {
3035 8 : inc = 2;
3036 8 : inc_log2 = 1;
3037 8 : move16();
3038 8 : move16();
3039 8 : start_idx = shr( hFdCngCom->startBand, inc_log2 );
3040 8 : stop_idx = shr( hFdCngCom->stopFFTbin, inc_log2 );
3041 : }
3042 : ELSE
3043 : {
3044 1514 : inc = 1;
3045 1514 : start_idx = hFdCngCom->startBand;
3046 1514 : stop_idx = hFdCngCom->stopFFTbin;
3047 1514 : move16();
3048 1514 : move16();
3049 1514 : move16();
3050 : }
3051 :
3052 4558 : FOR( i = 0; i < start_idx; i++ )
3053 : {
3054 3036 : noise_shape_buffer[i] = 0;
3055 3036 : move32();
3056 3036 : noise_shape_buffer_e[i] = 0;
3057 3036 : move16();
3058 : }
3059 484246 : FOR( ; i < stop_idx; ( i++, cngNoiseLevelPtr += inc ) )
3060 : {
3061 482724 : noise_shape_buffer_e[i] = hFdCngCom->cngNoiseLevelExp;
3062 482724 : move16();
3063 482724 : noise_shape_buffer[i] = Sqrt32( *( cngNoiseLevelPtr ), &noise_shape_buffer_e[i] ); // Q31-noise_shape_buffer_e[i]
3064 482724 : move32();
3065 482724 : noise_shape_buffer_common_exp = s_max( noise_shape_buffer_e[i], noise_shape_buffer_common_exp );
3066 : }
3067 :
3068 487282 : FOR( i = 0; i < stop_idx; i++ )
3069 : {
3070 485760 : IF( NE_16( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) )
3071 : {
3072 :
3073 53528 : noise_shape_buffer[i] = L_shr( noise_shape_buffer[i], sub( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ); // Q31- (noise_shape_buffer_common_exp-noise_shape_buffer_e[i])
3074 53528 : move32();
3075 : }
3076 : }
3077 :
3078 1522 : last_scf = Sqrt32( *( cngNoiseLevelPtr - inc ), &last_scf_e ); // Q31-last_scf_e
3079 :
3080 1522 : IF( LT_16( noise_shape_buffer_common_exp, last_scf_e ) )
3081 : {
3082 0 : Scale_sig32( noise_shape_buffer, stop_idx, sub( noise_shape_buffer_common_exp, last_scf_e ) ); // Q31- (noise_shape_buffer_common_exp-last_scf_e)
3083 :
3084 0 : noise_shape_buffer_common_exp = last_scf_e;
3085 0 : move16();
3086 : }
3087 : ELSE
3088 : {
3089 1522 : last_scf = L_shl( last_scf, sub( last_scf_e, noise_shape_buffer_common_exp ) ); // Q31-(last_scf_e-noise_shape_buffer_common_exp)
3090 : }
3091 :
3092 91986 : FOR( ; i < max_noise_line; i++ )
3093 : {
3094 90464 : noise_shape_buffer[i] = last_scf; // Q31 - noise_shape_buffer_common_exp
3095 90464 : move32();
3096 : }
3097 :
3098 : /* fill the noise vector */
3099 1522 : hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG_Q31; // Q31
3100 1522 : move32();
3101 1522 : hTonalMDCTConc->curr_noise_nrg_exp = 0;
3102 1522 : move16();
3103 1522 : *concealment_noise_exp = add( 16, add( noise_shape_buffer_common_exp, c_e ) );
3104 1522 : move16();
3105 1522 : temp_e = hTonalMDCTConc->curr_noise_nrg_exp;
3106 1522 : move16();
3107 :
3108 1522 : test();
3109 1522 : test();
3110 1522 : test();
3111 1522 : test();
3112 1522 : IF( EQ_16( noise_gen_mode, EQUAL_CORES ) || ( ( EQ_16( noise_gen_mode, TCX20_IN_0_TCX10_IN_1 ) && EQ_16( idchan, 0 ) ) || ( EQ_16( noise_gen_mode, TCX10_IN_0_TCX20_IN_1 ) && EQ_16( idchan, 1 ) ) ) )
3113 : {
3114 : /* current channel is TCX20 -> generate noise for "full-length" spectrum */
3115 :
3116 577746 : FOR( i = 0; i < max_noise_line; i++ )
3117 : {
3118 576224 : *rnd = own_random( rnd ); // Q0
3119 576224 : *rnd_c = own_random( rnd_c );
3120 :
3121 576224 : move16();
3122 576224 : move16();
3123 :
3124 576224 : concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); // Q31 - *concealment_noise_exp
3125 576224 : move32();
3126 576224 : IF( concealment_noise[i] != 0 )
3127 : {
3128 71414 : hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e
3129 : }
3130 576224 : hTonalMDCTConc->curr_noise_nrg_exp = temp_e;
3131 576224 : move16();
3132 : }
3133 : }
3134 : ELSE /* ( ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 1 ) ) */
3135 : {
3136 : /* 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 */
3137 0 : FOR( i = 0; i < max_noise_line; i++ )
3138 : {
3139 0 : *rnd = own_random( rnd ); // Q0
3140 0 : *rnd_c = own_random( rnd_c ); // Q0
3141 0 : move16();
3142 0 : move16();
3143 :
3144 0 : concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] );
3145 0 : move32();
3146 0 : IF( concealment_noise[i] != 0 )
3147 : {
3148 0 : hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e
3149 : }
3150 0 : hTonalMDCTConc->curr_noise_nrg_exp = temp_e;
3151 0 : move16();
3152 :
3153 0 : *rnd_c = own_random( rnd_c );
3154 0 : move16();
3155 : }
3156 : }
3157 :
3158 1522 : IF( st->tonal_mdct_plc_active )
3159 : {
3160 13 : FOR( i = crossOverFreq; i < s_max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i )
3161 : {
3162 0 : concealment_noise[i] = 0;
3163 0 : move32();
3164 : }
3165 : }
3166 :
3167 : /* restore common seed
3168 : - after finishing the first channel
3169 : - after a first subframe if the current channel is TCX10 */
3170 :
3171 1522 : test();
3172 1522 : test();
3173 1522 : test();
3174 1522 : test();
3175 1522 : test();
3176 1522 : IF( ( EQ_16( idchan, 0 ) && ( EQ_16( core, TCX_20 ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 1 ) ) ) ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 0 ) ) )
3177 : {
3178 752 : *rnd_c = save_rnd_c;
3179 752 : move16();
3180 : }
3181 :
3182 1522 : st->seed_tcx_plc = *rnd;
3183 1522 : move16();
3184 :
3185 1522 : pop_wmops();
3186 :
3187 1522 : return;
3188 : }
3189 :
3190 :
3191 2093 : void TonalMdctConceal_whiten_noise_shape_ivas_fx(
3192 : Decoder_State *st,
3193 : const Word16 L_frame,
3194 : const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode )
3195 : {
3196 : Word16 inc, start_idx, stop_idx, i;
3197 : Word32 *noiseLevelPtr, *scfs_bg, *scfs_for_shaping;
3198 : Word16 noiseLevelPtr_exp;
3199 : HANDLE_FD_CNG_COM hFdCngCom;
3200 : Word32 whitenend_noise_shape[L_FRAME16k];
3201 : Word16 q_wns;
3202 : Word32 scfs_int[FDNS_NPTS];
3203 : const PsychoacousticParameters *psychParams;
3204 :
3205 2093 : push_wmops( "apply_sns_on_noise_shape" );
3206 :
3207 2093 : scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground_fx[0];
3208 2093 : psychParams = st->hTonalMDCTConc->psychParams;
3209 2093 : hFdCngCom = st->hFdCngDec->hFdCngCom;
3210 :
3211 2093 : set32_fx( whitenend_noise_shape, 0, L_FRAME16k );
3212 :
3213 2093 : IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) )
3214 : {
3215 474 : IF( GT_16( st->core, TCX_20_CORE ) )
3216 : {
3217 6 : inc = 2;
3218 6 : move16();
3219 : }
3220 : ELSE
3221 : {
3222 468 : inc = 1;
3223 468 : move16();
3224 : }
3225 : }
3226 : ELSE
3227 : {
3228 1619 : IF( GT_16( st->last_core, TCX_20_CORE ) )
3229 : {
3230 21 : inc = 2;
3231 21 : move16();
3232 : }
3233 : ELSE
3234 : {
3235 1598 : inc = 1;
3236 1598 : move16();
3237 : }
3238 : }
3239 2093 : start_idx = shr( hFdCngCom->startBand, sub( inc, 1 ) );
3240 2093 : stop_idx = shr( L_frame, sub( inc, 1 ) );
3241 2093 : noiseLevelPtr = hFdCngCom->cngNoiseLevel;
3242 2093 : noiseLevelPtr_exp = hFdCngCom->cngNoiseLevelExp;
3243 2093 : move16();
3244 :
3245 663374 : FOR( Word16 j = start_idx; j < stop_idx; j++ )
3246 : {
3247 661281 : whitenend_noise_shape[j] = L_shr( *noiseLevelPtr, 3 );
3248 661281 : move32();
3249 661281 : noiseLevelPtr += inc;
3250 : }
3251 :
3252 2093 : IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) )
3253 : {
3254 : Word32 scf[SNS_NPTS];
3255 :
3256 474 : sns_compute_scf_fx( whitenend_noise_shape, psychParams, L_frame, scf, sub( sub( 31, noiseLevelPtr_exp ), 3 ) );
3257 :
3258 474 : sns_interpolate_scalefactors_fx( scfs_int, scf, ENC );
3259 474 : sns_interpolate_scalefactors_fx( scfs_bg, scf, DEC );
3260 :
3261 474 : scfs_for_shaping = &scfs_int[0]; // Q16
3262 : }
3263 : ELSE /* whitening_mode == ON_FIRST_GOOD_FRAME */
3264 : {
3265 1619 : scfs_for_shaping = &scfs_bg[0]; // Q16
3266 : }
3267 :
3268 2093 : IF( sum32_sat( scfs_for_shaping, FDNS_NPTS ) > 0 )
3269 : {
3270 932 : q_wns = sub( sub( 31, noiseLevelPtr_exp ), 3 );
3271 932 : sns_shape_spectrum_fx( whitenend_noise_shape, &q_wns, psychParams, scfs_for_shaping, Q16, L_frame, NULL );
3272 :
3273 932 : IF( GT_16( add( q_wns, 1 ), sub( 31, hFdCngCom->cngNoiseLevelExp ) ) )
3274 : {
3275 262543 : FOR( i = 0; i < sub( stop_idx, start_idx ); i++ )
3276 : {
3277 261714 : hFdCngCom->cngNoiseLevel[i] = L_shr( whitenend_noise_shape[start_idx + i], sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); //(q_wns + 1)
3278 261714 : move32();
3279 : }
3280 : }
3281 : ELSE
3282 : {
3283 103 : Copy32( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, sub( stop_idx, start_idx ) );
3284 :
3285 103 : scale_sig32( hFdCngCom->cngNoiseLevel + sub( stop_idx, start_idx ), sub( FFTCLDFBLEN, sub( stop_idx, start_idx ) ), sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) );
3286 :
3287 103 : hFdCngCom->cngNoiseLevelExp = sub( Q30, q_wns ); // Exponent = 31 - (q_wns + 1)
3288 103 : move16();
3289 : }
3290 : }
3291 : ELSE
3292 : {
3293 1161 : set32_fx( hFdCngCom->cngNoiseLevel, 0, sub( stop_idx, start_idx ) );
3294 : }
3295 :
3296 2093 : pop_wmops();
3297 2093 : }
|