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