Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <stdlib.h>
34 : #include "options.h"
35 : #include <math.h>
36 : #include "prot.h"
37 : #include "isar_lcld_prot.h"
38 : #include "isar_rom_lcld_tables.h"
39 : #include "wmc_auto.h"
40 :
41 :
42 : /*-------------------------------------------------------------------*
43 : * Local ROM tables
44 : *
45 : *
46 : *-------------------------------------------------------------------*/
47 :
48 : static const float c_afThreshQuiet48[23] = {
49 : -8.40653699e+01f,
50 : -8.40653699e+01f,
51 : -8.40653699e+01f,
52 : -8.40653699e+01f,
53 : -8.40653699e+01f,
54 : -8.40653699e+01f,
55 : -8.40653699e+01f,
56 : -8.40653699e+01f,
57 : -8.38067304e+01f,
58 : -8.28409495e+01f,
59 : -8.17031225e+01f,
60 : -7.89799501e+01f,
61 : -7.70607916e+01f,
62 : -7.58484320e+01f,
63 : -7.47976303e+01f,
64 : -7.37491303e+01f,
65 : -7.13163746e+01f,
66 : -6.86144293e+01f,
67 : -6.56295695e+01f,
68 : -6.06521800e+01f,
69 : -3.15408065e+01f,
70 : -1.92542188e+01f,
71 : -1.88401753e+01f,
72 : };
73 :
74 : static const float c_fiDefaultTheta48[MAX_BANDS_48] = {
75 : 0.4375,
76 : 0.4375,
77 : 0.375,
78 : 0.3125,
79 : 0.3125,
80 : 0.25,
81 : 0.25,
82 : 0.25,
83 : 0.25,
84 : 0.25,
85 : 0.25,
86 : 0.25,
87 : 0.25,
88 : 0.25,
89 : 0.25,
90 : 0.25,
91 : 0.25,
92 : 0.25,
93 : 0.25,
94 : 0.25,
95 : 0.25,
96 : 0.25,
97 : 0.25,
98 : };
99 :
100 : typedef struct GMNODE
101 : {
102 : int32_t iGroupStart;
103 : int32_t iGroupLength;
104 : float *pfMergedEnergydB;
105 : int32_t *piQRMSEnvelope;
106 :
107 : int32_t iGroupRMSEnvelopeCost;
108 : float fGroupSNRPenalty;
109 :
110 : struct GMNODE *psNext;
111 : } GMNode;
112 :
113 : struct RMS_ENVELOPE_GROUPING
114 : {
115 : int32_t iNumBlocks;
116 : int32_t iMaxGroups;
117 : float **ppfBandEnergy;
118 : float **ppfBandEnergydB;
119 : float **ppfWeight;
120 : GMNode *psGMNodes;
121 : };
122 :
123 :
124 : /*-------------------------------------------------------------------*
125 : * Function CreateRMSEnvelopeGrouping()
126 : *
127 : *
128 : *-------------------------------------------------------------------*/
129 :
130 2098 : RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping(
131 : const int32_t iNumBlocks )
132 : {
133 : int32_t n;
134 :
135 : RMSEnvelopeGrouping *psRMSEnvelopeGrouping;
136 :
137 2098 : psRMSEnvelopeGrouping = (RMSEnvelopeGrouping *) malloc( sizeof( RMSEnvelopeGrouping ) );
138 2098 : psRMSEnvelopeGrouping->iNumBlocks = iNumBlocks;
139 :
140 2098 : psRMSEnvelopeGrouping->iMaxGroups = iNumBlocks >> 1;
141 :
142 2098 : psRMSEnvelopeGrouping->ppfBandEnergy = (float **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( float * ) );
143 2098 : psRMSEnvelopeGrouping->ppfBandEnergydB = (float **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( float * ) );
144 2098 : psRMSEnvelopeGrouping->ppfWeight = (float **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( float * ) );
145 35274 : for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ )
146 : {
147 33176 : psRMSEnvelopeGrouping->ppfBandEnergy[n] = (float *) malloc( MAX_BANDS * 2 * sizeof( float ) ); /* 2 for stereo joint group calc */
148 33176 : psRMSEnvelopeGrouping->ppfBandEnergydB[n] = (float *) malloc( MAX_BANDS * 2 * sizeof( float ) );
149 33176 : psRMSEnvelopeGrouping->ppfWeight[n] = (float *) malloc( MAX_BANDS * 2 * sizeof( float ) );
150 : }
151 :
152 2098 : psRMSEnvelopeGrouping->psGMNodes = (GMNode *) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( GMNode ) );
153 35274 : for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ )
154 : {
155 33176 : psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB = (float *) malloc( MAX_BANDS * 2 * sizeof( float ) );
156 33176 : psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope = (int32_t *) malloc( MAX_BANDS * 2 * sizeof( int32_t ) );
157 33176 : psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1;
158 33176 : psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0;
159 : }
160 :
161 2098 : return psRMSEnvelopeGrouping;
162 : }
163 :
164 :
165 : /*-------------------------------------------------------------------*
166 : * Function DeleteRMSEnvelopeGrouping()
167 : *
168 : *
169 : *-------------------------------------------------------------------*/
170 :
171 2098 : void DeleteRMSEnvelopeGrouping(
172 : RMSEnvelopeGrouping *psRMSEnvelopeGrouping )
173 : {
174 : int32_t n;
175 :
176 35274 : for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ )
177 : {
178 33176 : free( psRMSEnvelopeGrouping->ppfBandEnergy[n] );
179 33176 : free( psRMSEnvelopeGrouping->ppfBandEnergydB[n] );
180 33176 : free( psRMSEnvelopeGrouping->ppfWeight[n] );
181 : }
182 2098 : free( psRMSEnvelopeGrouping->ppfBandEnergy );
183 2098 : free( psRMSEnvelopeGrouping->ppfBandEnergydB );
184 2098 : free( psRMSEnvelopeGrouping->ppfWeight );
185 :
186 35274 : for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ )
187 : {
188 33176 : free( psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB );
189 33176 : free( psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope );
190 : }
191 2098 : free( psRMSEnvelopeGrouping->psGMNodes );
192 :
193 2098 : free( psRMSEnvelopeGrouping );
194 :
195 2098 : return;
196 : }
197 :
198 :
199 : /*-------------------------------------------------------------------*
200 : * Function ComputeBandEnergy()
201 : *
202 : *
203 : *-------------------------------------------------------------------*/
204 :
205 325009 : static void ComputeBandEnergy(
206 : const int32_t iChannels,
207 : const int32_t iNumBlocks,
208 : const int32_t iNumBands,
209 : const int32_t *piBandwidths,
210 : float ***pppfReal,
211 : float ***pppfImag,
212 : float **ppfBandEnergy,
213 : float **ppfBandEnergydB,
214 : float **ppfWeight )
215 : {
216 : int32_t n;
217 :
218 975027 : for ( n = 0; n < iChannels; n++ )
219 : {
220 : int32_t k;
221 : int32_t iChanOffset;
222 :
223 650018 : iChanOffset = n * iNumBands;
224 10639746 : for ( k = 0; k < iNumBlocks; k++ )
225 : {
226 : int32_t b;
227 : int32_t iFBOffset;
228 : float fMaxWeight;
229 :
230 9989728 : iFBOffset = 0;
231 9989728 : fMaxWeight = 0.0f;
232 229763744 : for ( b = 0; b < iNumBands; b++ )
233 : {
234 : int32_t m;
235 219774016 : float fEnergy = 1e-12f;
236 : float fWeight;
237 :
238 719260416 : for ( m = 0; m < piBandwidths[b]; m++ )
239 : {
240 499486400 : fEnergy += ( pppfReal[n][k][iFBOffset] * pppfReal[n][k][iFBOffset] + pppfImag[n][k][iFBOffset] * pppfImag[n][k][iFBOffset] );
241 499486400 : iFBOffset++;
242 : }
243 219774016 : fEnergy /= (float) ( piBandwidths[b] ); /* Correction removed normalization by 2*/
244 219774016 : ppfBandEnergy[k][iChanOffset + b] = fEnergy;
245 :
246 219774016 : fWeight = 0.33f * powf( 10.0f, 0.0068f * ( 10.0f * log10f( fEnergy ) - c_afThreshQuiet48[b] ) );
247 219774016 : fWeight = ( fWeight > 0.33f ) ? fWeight : 0.33f;
248 219774016 : fWeight = ( fWeight < 1.0f ) ? fWeight : 1.0f;
249 219774016 : fMaxWeight = ( fMaxWeight > fWeight ) ? fMaxWeight : fWeight;
250 219774016 : ppfWeight[k][iChanOffset + b] = fWeight;
251 :
252 : #ifdef APPLY_TEMPORAL_SMOOTHING
253 : if ( k > 0 )
254 : {
255 : float fSmoothEnergy;
256 : fSmoothEnergy = 0.7f * ppfBandEnergy[k - 1][iChanOffset + b] + 0.3f * fEnergy;
257 :
258 : fEnergy = ( fEnergy > fSmoothEnergy ) ? fEnergy : fSmoothEnergy;
259 : }
260 : #endif
261 219774016 : fEnergy = 10.0f * log10f( fEnergy );
262 219774016 : ppfBandEnergydB[k][iChanOffset + b] = fEnergy;
263 : }
264 229763744 : for ( b = 0; b < iNumBands; b++ )
265 : {
266 219774016 : ppfWeight[k][iChanOffset + b] /= fMaxWeight;
267 : }
268 : }
269 : }
270 :
271 325009 : return;
272 : }
273 :
274 : /*-------------------------------------------------------------------*
275 : * Function ComputeMergeRMS()
276 : *
277 : *
278 : *-------------------------------------------------------------------*/
279 :
280 12461681 : static void ComputeMergeRMS(
281 : const int32_t iNumBands,
282 : const int32_t iStartBlock,
283 : const int32_t iGroupLength,
284 : float **ppfBandEnergy,
285 : float *pfMergedEnergydB,
286 : int32_t *piQRMSEnvelope )
287 : {
288 : int32_t b;
289 12461681 : float fInvGroupSize = 1.0f / (float) iGroupLength;
290 :
291 560775645 : for ( b = 0; b < iNumBands; b++ )
292 : {
293 : int32_t n;
294 : float fGroupEnergy;
295 : float fRMSEnvelope;
296 : int32_t iQRMSEnvelope;
297 :
298 548313964 : fGroupEnergy = 0.0;
299 3342744548 : for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ )
300 : {
301 2794430584 : fGroupEnergy += ppfBandEnergy[n][b];
302 : }
303 548313964 : fGroupEnergy *= fInvGroupSize;
304 :
305 548313964 : fRMSEnvelope = log2f( fGroupEnergy );
306 548313964 : iQRMSEnvelope = ( fRMSEnvelope > 0.0 ) ? (int32_t) ( fRMSEnvelope + 0.5 ) : (int32_t) ( fRMSEnvelope - 0.5 );
307 :
308 548313964 : fGroupEnergy = 10.0f * log10f( fGroupEnergy ); /* Note epsilon was added when computing BandEnergy;*/
309 :
310 548313964 : pfMergedEnergydB[b] = fGroupEnergy;
311 548313964 : piQRMSEnvelope[b] = iQRMSEnvelope;
312 : }
313 :
314 12461681 : return;
315 : }
316 :
317 :
318 : /*-------------------------------------------------------------------*
319 : * Function ComputeRMSEnvelopeBits()
320 : *
321 : *
322 : *-------------------------------------------------------------------*/
323 :
324 12461681 : static int32_t ComputeRMSEnvelopeBits(
325 : const int32_t iChannels,
326 : const int32_t iNumBands,
327 : const int32_t *piQRMSEnevelope )
328 : {
329 : int32_t n;
330 12461681 : int32_t iRMSEnvelopeBits = 0;
331 12461681 : int32_t iChanOffset = 0;
332 :
333 37385043 : for ( n = 0; n < iChannels; n++ )
334 : {
335 : int32_t b;
336 : int32_t iLastRMSVal;
337 :
338 24923362 : iRMSEnvelopeBits += ENV0_BITS;
339 24923362 : iLastRMSVal = piQRMSEnevelope[iChanOffset];
340 548313964 : for ( b = 1; b < iNumBands; b++ )
341 : {
342 : int32_t iDelta;
343 :
344 523390602 : iDelta = piQRMSEnevelope[iChanOffset + b] - iLastRMSVal;
345 523390602 : iDelta = ( iDelta > ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN;
346 523390602 : iDelta = ( iDelta < ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX;
347 523390602 : iDelta -= ENV_DELTA_MIN;
348 523390602 : iRMSEnvelopeBits += c_aaiRMSEnvHuffEnc[iDelta][0];
349 :
350 523390602 : iLastRMSVal = piQRMSEnevelope[iChanOffset + b];
351 : }
352 :
353 24923362 : iChanOffset += iNumBands;
354 : }
355 :
356 12461681 : return iRMSEnvelopeBits;
357 : }
358 :
359 :
360 : /*-------------------------------------------------------------------*
361 : * Function ComputeSNRPenalty()
362 : *
363 : *
364 : *-------------------------------------------------------------------*/
365 :
366 12461681 : static float ComputeSNRPenalty(
367 : const int32_t iChannels,
368 : const int32_t iNumBands,
369 : const int32_t *piBandwidths,
370 : const int32_t iStartBlock,
371 : const int32_t iGroupLength,
372 : float **ppfBandEnergydB,
373 : const int32_t *piRMSEnvelope )
374 : {
375 : int32_t n;
376 : int32_t iChanOffset;
377 12461681 : float fSNRPenalty = 0.0;
378 :
379 12461681 : iChanOffset = 0;
380 37385043 : for ( n = 0; n < iChannels; n++ )
381 : {
382 : int32_t b;
383 573237326 : for ( b = 0; b < iNumBands; b++ )
384 : {
385 : int32_t k;
386 : float fRMSVal;
387 :
388 548313964 : fRMSVal = 3.0103f * (float) piRMSEnvelope[iChanOffset + b];
389 :
390 3342744548 : for ( k = iStartBlock; k < ( iStartBlock + iGroupLength ); k++ )
391 : {
392 : float fDeltadB;
393 :
394 2794430584 : fDeltadB = fRMSVal - ppfBandEnergydB[k][iChanOffset + b];
395 2794430584 : if ( fDeltadB < -9.0309f )
396 : {
397 224966 : fSNRPenalty += 1e10f; /* Some large number to prevent clipping*/
398 : }
399 : else /*if(fDeltadB < 0.0)*/
400 : {
401 2794205618 : fSNRPenalty += fabsf( c_fiDefaultTheta48[b] * fDeltadB - fDeltadB ) * 2.0f * (float) piBandwidths[b] / 6.0f;
402 : }
403 : }
404 : }
405 :
406 24923362 : iChanOffset += iNumBands;
407 : }
408 :
409 12461681 : return fSNRPenalty;
410 : }
411 :
412 :
413 : /*-------------------------------------------------------------------*
414 : * Function TryMerge2()
415 : *
416 : *
417 : *-------------------------------------------------------------------*/
418 :
419 8262615 : static float TryMerge2(
420 : const int32_t iChannels,
421 : const int32_t iNumBands,
422 : const int32_t *piBandwidths,
423 : float **ppfBandEnergy,
424 : float **ppfBandEnergydB,
425 : GMNode *psGMNode1,
426 : GMNode *psGMNode2 )
427 : {
428 : int32_t iRMSEnvBits1;
429 : int32_t iRMSEnvBits2;
430 : int32_t iRMSEnvBitsMerged;
431 : float fSNRPenalty1;
432 : float fSNRPenalty2;
433 : float fSNRPenaltyMerged;
434 8262615 : float fMergedCost = 0.0;
435 :
436 : /* First compute current RMS Envelope for each group */
437 8262615 : if ( psGMNode1->iGroupRMSEnvelopeCost == -1 || psGMNode1->fGroupSNRPenalty == -1.0 )
438 : {
439 800100 : ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergy, psGMNode1->pfMergedEnergydB, psGMNode1->piQRMSEnvelope );
440 :
441 800100 : iRMSEnvBits1 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope );
442 :
443 800100 : fSNRPenalty1 = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergydB, psGMNode1->piQRMSEnvelope );
444 :
445 800100 : psGMNode1->iGroupRMSEnvelopeCost = iRMSEnvBits1;
446 800100 : psGMNode1->fGroupSNRPenalty = fSNRPenalty1;
447 : }
448 : else
449 : {
450 7462515 : iRMSEnvBits1 = psGMNode1->iGroupRMSEnvelopeCost;
451 7462515 : fSNRPenalty1 = psGMNode1->fGroupSNRPenalty;
452 : }
453 :
454 8262615 : if ( psGMNode2->iGroupRMSEnvelopeCost == -1 || psGMNode2->fGroupSNRPenalty == -1.0 )
455 : {
456 3398966 : ComputeMergeRMS( iNumBands * iChannels, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergy, psGMNode2->pfMergedEnergydB, psGMNode2->piQRMSEnvelope );
457 :
458 3398966 : iRMSEnvBits2 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode2->piQRMSEnvelope );
459 :
460 3398966 : fSNRPenalty2 = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergydB, psGMNode2->piQRMSEnvelope );
461 :
462 3398966 : psGMNode2->iGroupRMSEnvelopeCost = iRMSEnvBits2;
463 3398966 : psGMNode2->fGroupSNRPenalty = fSNRPenalty2;
464 : }
465 : else
466 : {
467 4863649 : iRMSEnvBits2 = psGMNode2->iGroupRMSEnvelopeCost;
468 4863649 : fSNRPenalty2 = psGMNode2->fGroupSNRPenalty;
469 : }
470 :
471 : /* Compute the merged group */
472 8262615 : ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, ppfBandEnergy, psGMNode1->pfMergedEnergydB, psGMNode1->piQRMSEnvelope );
473 :
474 : /* Compute the RMS Envelope cost for merged group */
475 8262615 : iRMSEnvBitsMerged = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope );
476 :
477 : /* Compute an approximation of the bit cost based on SNR increase/decrease due to merging */
478 8262615 : fSNRPenaltyMerged = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, ppfBandEnergydB, psGMNode1->piQRMSEnvelope );
479 :
480 8262615 : fMergedCost = fSNRPenaltyMerged - fSNRPenalty1 - fSNRPenalty2 + (float) iRMSEnvBitsMerged - (float) iRMSEnvBits1 - (float) iRMSEnvBits2;
481 :
482 8262615 : return fMergedCost;
483 : }
484 :
485 : /*-------------------------------------------------------------------*
486 : * Function ComputeGreedyGroups3()
487 : *
488 : *
489 : *-------------------------------------------------------------------*/
490 :
491 325009 : static void ComputeGreedyGroups3(
492 : RMSEnvelopeGrouping *psRMSEnvelopeGrouping,
493 : const int32_t iChannels,
494 : const int32_t iNumBands,
495 : const int32_t *piBandwidths,
496 : const int32_t iMaxGroups )
497 : {
498 :
499 325009 : int32_t iDone = 0;
500 325009 : int32_t iNumGroups = psRMSEnvelopeGrouping->iMaxGroups;
501 :
502 2521402 : while ( iDone == 0 )
503 : {
504 : GMNode *psGMNode;
505 : GMNode *psBestGMNode;
506 : float fBestMergeCost;
507 :
508 2196393 : fBestMergeCost = 1e20f;
509 2196393 : psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0];
510 2196393 : psBestGMNode = NULL;
511 10459008 : while ( psGMNode->psNext != NULL )
512 : {
513 : float fMergeCost;
514 :
515 8262615 : fMergeCost = TryMerge2( iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psGMNode, psGMNode->psNext );
516 :
517 8262615 : if ( fMergeCost < fBestMergeCost )
518 : {
519 4052925 : fBestMergeCost = fMergeCost;
520 4052925 : psBestGMNode = psGMNode;
521 : }
522 :
523 8262615 : psGMNode = psGMNode->psNext;
524 : }
525 :
526 2196393 : if ( fBestMergeCost > 0.0 && iNumGroups <= iMaxGroups )
527 : {
528 325009 : iDone++;
529 : }
530 1871384 : else if ( psBestGMNode != NULL && psBestGMNode->psNext != NULL )
531 : {
532 1871384 : psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength;
533 1871384 : psBestGMNode->iGroupRMSEnvelopeCost = -1;
534 1871384 : psBestGMNode->fGroupSNRPenalty = -1.0;
535 1871384 : psBestGMNode->psNext = psBestGMNode->psNext->psNext;
536 1871384 : iNumGroups--;
537 : }
538 : else
539 : {
540 0 : iDone++; /* This only catches a problem*/
541 : }
542 : }
543 :
544 325009 : return;
545 : }
546 :
547 :
548 : /*-------------------------------------------------------------------*
549 : * Function ComputeRMSEnvelope()
550 : *
551 : *
552 : *-------------------------------------------------------------------*/
553 :
554 325009 : static void ComputeRMSEnvelope(
555 : const int32_t iChannels,
556 : const int32_t iNumBands,
557 : const int32_t iNumGroups,
558 : const int32_t *piGroupLengths,
559 : float **ppfBandEnergy,
560 : int32_t ***pppiRMSEnvelope )
561 : {
562 : int32_t n;
563 :
564 975027 : for ( n = 0; n < iChannels; n++ )
565 : {
566 : int32_t b;
567 : int32_t iChanOffset;
568 :
569 650018 : iChanOffset = n * iNumBands;
570 14950414 : for ( b = 0; b < iNumBands; b++ )
571 : {
572 : int32_t k;
573 : int32_t iBlockOffset;
574 :
575 14300396 : iBlockOffset = 0;
576 41846508 : for ( k = 0; k < iNumGroups; k++ )
577 : {
578 : int32_t m;
579 : float fGroupEnergy;
580 27546112 : fGroupEnergy = 0.0;
581 247320128 : for ( m = 0; m < piGroupLengths[k]; m++ )
582 : {
583 219774016 : fGroupEnergy += ppfBandEnergy[iBlockOffset][b + iChanOffset];
584 219774016 : iBlockOffset++;
585 : }
586 27546112 : fGroupEnergy /= (float) piGroupLengths[k];
587 :
588 27546112 : fGroupEnergy = log2f( fGroupEnergy );
589 27546112 : pppiRMSEnvelope[n][k][b] = ( fGroupEnergy > 0.0 ) ? (int32_t) ( fGroupEnergy + 0.5 ) : (int32_t) ( fGroupEnergy - 0.5 );
590 27546112 : pppiRMSEnvelope[n][k][b] = ( pppiRMSEnvelope[n][k][b] > ENV_MIN ) ? pppiRMSEnvelope[n][k][b] : ENV_MIN;
591 27546112 : pppiRMSEnvelope[n][k][b] = ( pppiRMSEnvelope[n][k][b] < ENV_MAX ) ? pppiRMSEnvelope[n][k][b] : ENV_MAX;
592 : }
593 : }
594 : }
595 :
596 325009 : return;
597 : }
598 :
599 :
600 : /*-------------------------------------------------------------------*
601 : * Function LimitRMSEnvelope()
602 : *
603 : *
604 : *-------------------------------------------------------------------*/
605 :
606 1252096 : static void LimitRMSEnvelope(
607 : const int32_t iBandCount,
608 : const int32_t iRMSDeltaMax,
609 : const int32_t iRMSDeltaMin,
610 : int32_t *piRMSEnvelope )
611 : {
612 : int32_t iBand;
613 : int32_t iLastSCF;
614 :
615 : /* Increase low envelope values to ensure that the scale factors traces the large values correctly (checking for max deltas) */
616 1252096 : iLastSCF = piRMSEnvelope[iBandCount - 1];
617 27546112 : for ( iBand = iBandCount - 2; iBand > -1; iBand-- )
618 : {
619 : int32_t iDelta;
620 :
621 26294016 : iDelta = iLastSCF - piRMSEnvelope[iBand];
622 :
623 26294016 : if ( iDelta > iRMSDeltaMax )
624 : {
625 : #ifdef DEBUG_VERBOSE
626 : printf( "WARNING RMS envelope delta limited\n" );
627 : #endif
628 1102 : piRMSEnvelope[iBand] += ( iDelta - iRMSDeltaMax );
629 : }
630 :
631 26294016 : iLastSCF = piRMSEnvelope[iBand];
632 : }
633 :
634 : /* Increase low envelope values to ensure that the envelope traces the large values correctly (checking for min deltas)*/
635 1252096 : iLastSCF = piRMSEnvelope[0];
636 27546112 : for ( iBand = 1; iBand < iBandCount; iBand++ )
637 : {
638 : int32_t iDelta;
639 :
640 26294016 : iDelta = piRMSEnvelope[iBand] - iLastSCF;
641 :
642 26294016 : if ( iDelta < iRMSDeltaMin )
643 : {
644 : #ifdef DEBUG_VERBOSE
645 : printf( "WARNING RMS envelope delta limited\n" );
646 : #endif
647 1711 : piRMSEnvelope[iBand] += ( iRMSDeltaMin - iDelta );
648 : }
649 :
650 26294016 : iLastSCF = piRMSEnvelope[iBand];
651 : }
652 :
653 1252096 : return;
654 : }
655 :
656 :
657 : /*-------------------------------------------------------------------*
658 : * Function ComputeEnvelopeGrouping()
659 : *
660 : *
661 : *-------------------------------------------------------------------*/
662 :
663 325009 : void ComputeEnvelopeGrouping(
664 : RMSEnvelopeGrouping *psRMSEnvelopeGrouping,
665 : const int32_t iChannels,
666 : const int32_t iNumBands,
667 : const int32_t *piBandwidths,
668 : float ***pppfReal,
669 : float ***pppfImag,
670 : int32_t *piNumGroups,
671 : int32_t *piGroupLengths,
672 : int32_t ***pppiRMSEnvelope )
673 : {
674 : int32_t n;
675 : GMNode *psGMNode;
676 :
677 : /* Compute Band Energies */
678 325009 : ComputeBandEnergy( iChannels, psRMSEnvelopeGrouping->iNumBlocks, iNumBands, piBandwidths, pppfReal, pppfImag, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psRMSEnvelopeGrouping->ppfWeight );
679 :
680 : /* Init GMNodes */
681 325009 : psRMSEnvelopeGrouping->psGMNodes[0].iGroupStart = 0;
682 325009 : psRMSEnvelopeGrouping->psGMNodes[0].iGroupLength = 2;
683 325009 : psRMSEnvelopeGrouping->psGMNodes[0].psNext = NULL;
684 325009 : psRMSEnvelopeGrouping->psGMNodes[0].iGroupRMSEnvelopeCost = -1;
685 325009 : psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty = -1.0f;
686 :
687 2497432 : for ( n = 1; n < psRMSEnvelopeGrouping->iMaxGroups; n++ )
688 : {
689 2172423 : psRMSEnvelopeGrouping->psGMNodes[n - 1].psNext = &psRMSEnvelopeGrouping->psGMNodes[n];
690 2172423 : psRMSEnvelopeGrouping->psGMNodes[n].iGroupStart = n * 2;
691 2172423 : psRMSEnvelopeGrouping->psGMNodes[n].iGroupLength = 2;
692 2172423 : psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1;
693 2172423 : psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0;
694 2172423 : psRMSEnvelopeGrouping->psGMNodes[n].psNext = NULL;
695 : }
696 :
697 : /* Perform grouping via Greedy Merge */
698 : /* Allows control over max groups can call using 16 if want same as previous call */
699 325009 : ComputeGreedyGroups3( psRMSEnvelopeGrouping, iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->iNumBlocks );
700 :
701 : /* Calc Groups from Merge Results */
702 325009 : *piNumGroups = 0;
703 325009 : psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0];
704 951057 : while ( psGMNode != NULL )
705 : {
706 626048 : piGroupLengths[*piNumGroups] = psGMNode->iGroupLength;
707 626048 : *piNumGroups += 1;
708 626048 : psGMNode = psGMNode->psNext;
709 : }
710 :
711 : /* Compute RMS Envelope given group lengths */
712 325009 : ComputeRMSEnvelope( iChannels, iNumBands, *piNumGroups, piGroupLengths, psRMSEnvelopeGrouping->ppfBandEnergy, pppiRMSEnvelope );
713 :
714 : /* Envelope Tenting */
715 975027 : for ( n = 0; n < iChannels; n++ )
716 : {
717 : int32_t k;
718 1902114 : for ( k = 0; k < *piNumGroups; k++ )
719 : {
720 1252096 : LimitRMSEnvelope( iNumBands, ENV_DELTA_MAX, ENV_DELTA_MIN, pppiRMSEnvelope[n][k] );
721 : }
722 : }
723 :
724 325009 : return;
725 : }
|