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