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