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 <stdint.h>
34 : #include "options.h"
35 : #include <math.h>
36 : #include <assert.h>
37 : #include "isar_lcld_prot.h"
38 : #include "isar_rom_lcld_tables.h"
39 : #include "prot_fx.h"
40 : #include "prot_fx.h"
41 : #include "isar_prot.h"
42 : #include "wmc_auto.h"
43 : #include "basop_util.h"
44 : #include "enh64.h"
45 : #include "basop32.h"
46 :
47 : #define LOG10_2_FX ( 646456993 )
48 : /*------------------------------------------------------------------------------------------*
49 : * Local structures
50 : *------------------------------------------------------------------------------------------*/
51 : struct LCLD_ENCODER
52 : {
53 : Word32 iSampleRate;
54 : Word32 iChannels;
55 : Word32 iNumBlocks;
56 :
57 : Word32 iTargetBitRate;
58 :
59 : Word32 iNumBands;
60 : const Word32 *piBandwidths;
61 :
62 : Word32 iMSMode;
63 : Word32 *piMSFlags;
64 : Word32 piMSPredCoefs[MAX_BANDS];
65 : Word32 piLRPhaseDiffs[MAX_BANDS];
66 : Word32 iAllowSidePred;
67 :
68 : Word32 iRealOnlyOut;
69 :
70 : RMSEnvelopeGrouping *psRMSEnvelopeGrouping;
71 :
72 : Word32 iCommonGrouping;
73 : Word32 *piNumGroups;
74 : Word32 **ppiGroupLengths;
75 :
76 : Word32 ***pppiRMSEnvelope;
77 : Word32 ***pppiSMR;
78 : Word32 ***pppiExcitation;
79 : Word32 ***pppiAlloc;
80 :
81 : Word32 iAllocOffset;
82 :
83 : Word32 ***pppiLCLDSignReal;
84 : Word32 ***pppiLCLDSignImag;
85 : Word32 ***pppiQLCLDReal;
86 : Word32 ***pppiQLCLDImag;
87 :
88 :
89 : PredictionEncoder *psPredictionEncoder;
90 : };
91 : /*------------------------------------------------------------------------------------------*
92 : * Function Quantize()
93 : *
94 : *
95 : *------------------------------------------------------------------------------------------*/
96 0 : static Word32 Quantize_fx(
97 : const Word32 fVal_fx,
98 : const Word32 fScale_fx,
99 : Word32 *iSign,
100 : const Word32 iMaxVal )
101 : {
102 : Word32 iVal_fx;
103 0 : IF( GT_32( fVal_fx, 0 ) )
104 : {
105 0 : iVal_fx = (Word32) L_add( Mpy_32_32( fScale_fx, fVal_fx ), ONE_IN_Q20 );
106 0 : *iSign = 0;
107 : }
108 : ELSE
109 : {
110 0 : iVal_fx = (Word32) L_add( Mpy_32_32( -fScale_fx, fVal_fx ), ONE_IN_Q20 );
111 0 : *iSign = 1;
112 : }
113 0 : iVal_fx = ( iVal_fx < iMaxVal ) ? iVal_fx : iMaxVal;
114 :
115 0 : return iVal_fx;
116 : }
117 : /*------------------------------------------------------------------------------------------*
118 : * Function UnQuantize()
119 : *
120 : *
121 : *------------------------------------------------------------------------------------------*/
122 0 : static Word32 UnQuantize_fx(
123 : const Word32 iVal_fx,
124 : const Word32 fScale_fx,
125 : const Word32 iSign )
126 : {
127 :
128 : Word32 fVal_fx;
129 0 : IF( EQ_32( iSign, 0 ) )
130 : {
131 0 : fVal_fx = Mpy_32_32( fScale_fx, iVal_fx ); // Q19
132 : }
133 : ELSE
134 : {
135 0 : fVal_fx = Mpy_32_32( -fScale_fx, iVal_fx ); // Q19
136 : }
137 0 : return fVal_fx;
138 : }
139 0 : static void PackReal(
140 : const Word32 iChannels,
141 : const Word32 iNumBlocks,
142 : Word32 ***pppfReal,
143 : Word32 ***pppfImag )
144 : {
145 : Word32 ch, b, n;
146 0 : FOR( ch = 0; ch < iChannels; ch++ )
147 : {
148 0 : FOR( b = 0; b < LCLD_BANDS; b++ )
149 : {
150 0 : Word32 iRealBlock = 0;
151 0 : move32();
152 0 : FOR( n = 0; n < iNumBlocks; n += 2 )
153 : {
154 0 : pppfImag[ch][iRealBlock][b] = pppfReal[ch][n + 1][b];
155 0 : move32();
156 0 : pppfReal[ch][iRealBlock][b] = pppfReal[ch][n][b];
157 0 : move32();
158 0 : iRealBlock++;
159 : }
160 : }
161 : }
162 0 : }
163 : /*------------------------------------------------------------------------------------------*
164 : * Function CreateLCLDEncoder()
165 : *
166 : *
167 : *------------------------------------------------------------------------------------------*/
168 :
169 0 : ivas_error CreateLCLDEncoder(
170 : LCLDEncoder **psLCLDEncoder_out,
171 : const Word32 iSampleRate,
172 : const Word32 iChannels,
173 : const Word32 iTargetBitRate,
174 : const Word32 iAllowSidePred,
175 : const Word16 iNumBlocks,
176 : const Word16 iNumSubSets,
177 : const Word32 iRealOnlyOut )
178 : {
179 : Word32 n;
180 : LCLDEncoder *psLCLDEncoder;
181 : ivas_error error;
182 0 : Word32 iMaxNumPredBands = 0;
183 0 : move32();
184 :
185 0 : assert( iSampleRate == 48000 ); // Fix
186 0 : assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 );
187 0 : assert( iNumSubSets > 0 && iNumSubSets <= LCLD_MAX_NUM_PRED_SUBSETS );
188 :
189 0 : IF( ( psLCLDEncoder = (LCLDEncoder *) malloc( sizeof( LCLDEncoder ) ) ) == NULL )
190 : {
191 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
192 : }
193 :
194 0 : psLCLDEncoder->iSampleRate = iSampleRate;
195 0 : move32();
196 0 : psLCLDEncoder->iChannels = iChannels;
197 0 : move32();
198 0 : psLCLDEncoder->iRealOnlyOut = iRealOnlyOut;
199 0 : move32();
200 0 : psLCLDEncoder->iAllocOffset = 0;
201 0 : move32();
202 :
203 0 : psLCLDEncoder->iTargetBitRate = iTargetBitRate;
204 0 : move32();
205 :
206 0 : psLCLDEncoder->piBandwidths = c_aiBandwidths48;
207 0 : psLCLDEncoder->iNumBands = DEF_BANDS_48; /* 22 bands = 50 CLDFB bands (rather than 23 bands) */
208 0 : move32();
209 0 : iMaxNumPredBands = L_min( c_aiNumLcldBandsPerBand[psLCLDEncoder->iNumBands - 1], 50 );
210 0 : IF( EQ_32( iRealOnlyOut, 1 ) )
211 : {
212 0 : iMaxNumPredBands = 0;
213 0 : move32();
214 0 : assert( iNumSubSets == 1 );
215 0 : psLCLDEncoder->iNumBlocks = L_deposit_l( shr( iNumBlocks, 1 ) );
216 : }
217 : ELSE
218 : {
219 0 : psLCLDEncoder->iNumBlocks = iNumBlocks;
220 0 : move32();
221 : }
222 :
223 0 : psLCLDEncoder->iMSMode = 0;
224 0 : move32();
225 0 : IF( ( psLCLDEncoder->piMSFlags = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
226 : {
227 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
228 : }
229 :
230 0 : FOR( n = 0; n < MAX_BANDS; n++ )
231 : {
232 0 : psLCLDEncoder->piLRPhaseDiffs[n] = 0;
233 0 : move32();
234 0 : psLCLDEncoder->piMSPredCoefs[n] = 0;
235 0 : move32();
236 : }
237 0 : psLCLDEncoder->iAllowSidePred = iAllowSidePred;
238 0 : move32();
239 :
240 0 : psLCLDEncoder->psRMSEnvelopeGrouping = CreateRMSEnvelopeGrouping( psLCLDEncoder->iNumBlocks );
241 :
242 0 : psLCLDEncoder->iCommonGrouping = 1; //*Common grouping always on only impacts stereo */
243 0 : move32();
244 0 : IF( ( psLCLDEncoder->piNumGroups = (Word32 *) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ) ) ) == NULL )
245 : {
246 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
247 : }
248 :
249 0 : IF( ( psLCLDEncoder->ppiGroupLengths = (Word32 **) malloc( psLCLDEncoder->iChannels * sizeof( Word32 * ) ) ) == NULL )
250 : {
251 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
252 : }
253 :
254 0 : IF( ( psLCLDEncoder->pppiRMSEnvelope = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
255 : {
256 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
257 : }
258 :
259 0 : IF( ( psLCLDEncoder->pppiSMR = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
260 : {
261 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
262 : }
263 :
264 0 : IF( ( psLCLDEncoder->pppiExcitation = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
265 : {
266 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
267 : }
268 :
269 0 : IF( ( psLCLDEncoder->pppiAlloc = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
270 : {
271 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
272 : }
273 :
274 :
275 0 : IF( ( psLCLDEncoder->pppiLCLDSignReal = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
276 : {
277 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
278 : }
279 :
280 0 : IF( ( psLCLDEncoder->pppiLCLDSignImag = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
281 : {
282 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
283 : }
284 :
285 0 : IF( ( psLCLDEncoder->pppiQLCLDReal = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
286 : {
287 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
288 : }
289 :
290 0 : IF( ( psLCLDEncoder->pppiQLCLDImag = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
291 : {
292 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
293 : }
294 :
295 :
296 0 : FOR( n = 0; n < iChannels; n++ )
297 : {
298 : Word32 k;
299 0 : IF( ( psLCLDEncoder->ppiGroupLengths[n] = (Word32 *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 ) ) ) == NULL )
300 : {
301 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
302 : }
303 :
304 0 : IF( ( psLCLDEncoder->pppiRMSEnvelope[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
305 : {
306 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
307 : }
308 :
309 0 : IF( ( psLCLDEncoder->pppiSMR[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
310 : {
311 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
312 : }
313 :
314 0 : IF( ( psLCLDEncoder->pppiExcitation[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
315 : {
316 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
317 : }
318 :
319 0 : IF( ( psLCLDEncoder->pppiAlloc[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
320 : {
321 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
322 : }
323 :
324 :
325 0 : IF( ( psLCLDEncoder->pppiLCLDSignReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
326 : {
327 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
328 : }
329 :
330 0 : IF( ( psLCLDEncoder->pppiLCLDSignImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
331 : {
332 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
333 : }
334 :
335 0 : IF( ( psLCLDEncoder->pppiQLCLDReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
336 : {
337 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
338 : }
339 :
340 0 : IF( ( psLCLDEncoder->pppiQLCLDImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
341 : {
342 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
343 : }
344 :
345 0 : FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
346 : {
347 0 : IF( ( psLCLDEncoder->pppiRMSEnvelope[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
348 : {
349 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
350 : }
351 :
352 0 : IF( ( psLCLDEncoder->pppiSMR[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
353 : {
354 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
355 : }
356 :
357 0 : IF( ( psLCLDEncoder->pppiExcitation[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
358 : {
359 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
360 : }
361 :
362 0 : IF( ( psLCLDEncoder->pppiAlloc[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
363 : {
364 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
365 : }
366 :
367 :
368 0 : IF( ( psLCLDEncoder->pppiLCLDSignReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
369 : {
370 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
371 : }
372 :
373 0 : IF( ( psLCLDEncoder->pppiLCLDSignImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
374 : {
375 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
376 : }
377 :
378 0 : IF( ( psLCLDEncoder->pppiQLCLDReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
379 : {
380 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
381 : }
382 :
383 0 : IF( ( psLCLDEncoder->pppiQLCLDImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
384 : {
385 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
386 : }
387 : }
388 : }
389 :
390 0 : IF( ( error = CreatePredictionEncoder_fx( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks, L_deposit_l( iNumSubSets ), iMaxNumPredBands ) ) != IVAS_ERR_OK )
391 : {
392 0 : return error;
393 : }
394 :
395 0 : *psLCLDEncoder_out = psLCLDEncoder;
396 :
397 0 : return IVAS_ERR_OK;
398 : }
399 :
400 :
401 : /*------------------------------------------------------------------------------------------*
402 : * Function DeleteLCLDEncoder()
403 : *
404 : *
405 : *------------------------------------------------------------------------------------------*/
406 :
407 0 : void DeleteLCLDEncoder(
408 : LCLDEncoder *psLCLDEncoder )
409 : {
410 : Word32 k, n;
411 :
412 0 : IF( psLCLDEncoder != NULL )
413 : {
414 :
415 0 : IF( psLCLDEncoder->piMSFlags != NULL )
416 : {
417 0 : free( psLCLDEncoder->piMSFlags );
418 : }
419 :
420 0 : IF( psLCLDEncoder->piNumGroups != NULL )
421 : {
422 0 : free( psLCLDEncoder->piNumGroups );
423 : }
424 :
425 0 : IF( psLCLDEncoder->psRMSEnvelopeGrouping != NULL )
426 : {
427 0 : DeleteRMSEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping );
428 : }
429 :
430 0 : IF( psLCLDEncoder->ppiGroupLengths != NULL )
431 : {
432 0 : FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
433 : {
434 0 : free( psLCLDEncoder->ppiGroupLengths[n] );
435 : }
436 0 : free( psLCLDEncoder->ppiGroupLengths );
437 : }
438 0 : IF( psLCLDEncoder->pppiRMSEnvelope != NULL )
439 : {
440 0 : FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
441 : {
442 0 : FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
443 : {
444 0 : free( psLCLDEncoder->pppiRMSEnvelope[n][k] );
445 : }
446 0 : free( psLCLDEncoder->pppiRMSEnvelope[n] );
447 : }
448 0 : free( psLCLDEncoder->pppiRMSEnvelope );
449 : }
450 :
451 0 : IF( psLCLDEncoder->pppiSMR != NULL )
452 : {
453 0 : FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
454 : {
455 0 : FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
456 : {
457 0 : free( psLCLDEncoder->pppiSMR[n][k] );
458 : }
459 0 : free( psLCLDEncoder->pppiSMR[n] );
460 : }
461 0 : free( psLCLDEncoder->pppiSMR );
462 : }
463 :
464 0 : IF( psLCLDEncoder->pppiExcitation != NULL )
465 : {
466 0 : FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
467 : {
468 0 : FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
469 : {
470 0 : free( psLCLDEncoder->pppiExcitation[n][k] );
471 : }
472 0 : free( psLCLDEncoder->pppiExcitation[n] );
473 : }
474 0 : free( psLCLDEncoder->pppiExcitation );
475 : }
476 :
477 0 : IF( psLCLDEncoder->pppiAlloc != NULL )
478 : {
479 0 : FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
480 : {
481 0 : FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
482 : {
483 0 : free( psLCLDEncoder->pppiAlloc[n][k] );
484 : }
485 0 : free( psLCLDEncoder->pppiAlloc[n] );
486 : }
487 0 : free( psLCLDEncoder->pppiAlloc );
488 : }
489 :
490 0 : IF( psLCLDEncoder->pppiLCLDSignReal != NULL )
491 : {
492 0 : FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
493 : {
494 0 : FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
495 : {
496 0 : free( psLCLDEncoder->pppiLCLDSignReal[n][k] );
497 : }
498 0 : free( psLCLDEncoder->pppiLCLDSignReal[n] );
499 : }
500 0 : free( psLCLDEncoder->pppiLCLDSignReal );
501 : }
502 :
503 0 : IF( psLCLDEncoder->pppiLCLDSignImag != NULL )
504 : {
505 0 : FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
506 : {
507 0 : FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
508 : {
509 0 : free( psLCLDEncoder->pppiLCLDSignImag[n][k] );
510 : }
511 0 : free( psLCLDEncoder->pppiLCLDSignImag[n] );
512 : }
513 0 : free( psLCLDEncoder->pppiLCLDSignImag );
514 : }
515 :
516 0 : IF( psLCLDEncoder->pppiQLCLDReal != NULL )
517 : {
518 0 : FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
519 : {
520 0 : FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
521 : {
522 0 : free( psLCLDEncoder->pppiQLCLDReal[n][k] );
523 : }
524 0 : free( psLCLDEncoder->pppiQLCLDReal[n] );
525 : }
526 0 : free( psLCLDEncoder->pppiQLCLDReal );
527 : }
528 :
529 0 : IF( psLCLDEncoder->pppiQLCLDImag != NULL )
530 : {
531 0 : FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
532 : {
533 0 : FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
534 : {
535 0 : free( psLCLDEncoder->pppiQLCLDImag[n][k] );
536 : }
537 0 : free( psLCLDEncoder->pppiQLCLDImag[n] );
538 : }
539 0 : free( psLCLDEncoder->pppiQLCLDImag );
540 : }
541 :
542 0 : DeletePredictionEncoder_fx( psLCLDEncoder->psPredictionEncoder );
543 0 : free( psLCLDEncoder );
544 : }
545 :
546 0 : return;
547 : }
548 :
549 : /*------------------------------------------------------------------------------------------*
550 : * Local function declarations
551 : *------------------------------------------------------------------------------------------*/
552 :
553 : static Word32 MSModeCalculation_fx( const Word32 iNumBlocks, const Word32 iNumBands, const Word32 *piBandwidths, Word32 ***pppfReal_fx, Word32 ***pppfImag_fx, Word16 Q_in, Word32 *piMSMode, Word32 *piLRPhaseDiff, Word32 *piMSPredCoef, const Word32 iAllowSidePred, const Word32 iRealOnlyOut, Word32 *piMSFlags );
554 : static void RemoveRMSEnvelope( const Word32 iNumBands, const Word32 *piBandwidths, const Word32 iNumGroups, const Word32 *piGroupLengths, Word32 **ppiRMSEnvelope, Word32 **ppfReal_fx, Word32 **ppfImag_fx );
555 : static Word32 CountLCLDBits( const Word32 iNumGroups, const Word32 *piGroupLengths, const Word32 iNumBands, const Word32 *piBandwidths, const Word32 *piPredEnable, Word32 **ppiAlloc, Word32 **ppiQReal, Word32 **ppiQImag );
556 :
557 : static Word32 WriteHeaderInformation( const Word32 iNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits );
558 :
559 : static Word32 WriteMSInformation( const Word32 iNumBands, const Word32 iMSMode, const Word32 *piMSFlags, const Word32 *piLRPhaseDiff, const Word32 *piMSPredCoef, Word32 iNumMSPredBands, ISAR_SPLIT_REND_BITS_HANDLE pBits );
560 :
561 : static Word32 WriteGroupInformation( const Word32 iChannels, const Word32 iCommonGrouping, const Word32 *piNumGroups, Word32 **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits );
562 :
563 : static Word32 WriteRMSEnvelope( const Word32 iChannels, const Word32 *piNumGroups, const Word32 iNumBands, Word32 ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits );
564 :
565 : static Word32 WriteAllocInformation( const Word32 iAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits );
566 :
567 : static Word32 WriteLCLDData( const Word32 *piNumGroups, Word32 **ppiGroupLengths, const Word32 iNumBands, const Word32 iNumChannels, Word32 **ppiPredEnable, const Word32 iNumSubSets, const Word32 iSubSetId, Word32 ***pppiAlloc, Word32 ***pppiSignReal, Word32 ***pppiSignImag, Word32 ***pppiQReal, Word32 ***pppiQImag, ISAR_SPLIT_REND_BITS_HANDLE pBits );
568 : static Word32 ComputeAllocation( const Word32 iChannels, const Word32 *piNumGroups, Word32 **ppiGroupLengths, const Word32 iNumBands, const Word32 *piBandwidths, Word32 ***pppfReal_fx, Word32 ***pppfImag_fx, Word16 q_final, Word32 ***pppiSMR, const Word32 iAvailableBits, Word32 *piAllocOffset, Word32 ***pppiAlloc, Word32 ***pppiQReal, Word32 ***pppiQImag, Word32 ***pppiSignReal, Word32 ***pppiSignImag, PredictionEncoder *psPredictionEncoder );
569 : /*------------------------------------------------------------------------------------------*
570 : * Function EncodeLCLDFrame()
571 : *
572 : *
573 : *------------------------------------------------------------------------------------------*/
574 0 : Word32 EncodeLCLDFrame(
575 : LCLDEncoder *psLCLDEncoder,
576 : Word32 ***pppfLCLDReal_fx,
577 : Word32 ***pppfLCLDImag_fx,
578 : Word32 *piBitsWritten,
579 : const Word32 available_bits,
580 : ISAR_SPLIT_REND_BITS_HANDLE pBits,
581 : Word16 *q_final )
582 : {
583 : Word32 n;
584 : Word32 iAvailableBits, iBitsWritten;
585 0 : Word32 iNumMSBands = 0;
586 : Word32 iAudioBitsWritten;
587 :
588 0 : iAvailableBits = available_bits; // HCBR for now
589 0 : iBitsWritten = 0;
590 0 : assert( available_bits <= pBits->buf_len * 8 );
591 0 : IF( EQ_32( psLCLDEncoder->iRealOnlyOut, 1 ) )
592 : {
593 0 : PackReal( psLCLDEncoder->iChannels, psLCLDEncoder->iNumBlocks * 2, pppfLCLDReal_fx, pppfLCLDImag_fx );
594 : }
595 : /* Do MS calc here */
596 0 : IF( EQ_32( psLCLDEncoder->iChannels, 2 ) )
597 : {
598 0 : iNumMSBands = MSModeCalculation_fx( psLCLDEncoder->iNumBlocks,
599 : psLCLDEncoder->iNumBands,
600 : psLCLDEncoder->piBandwidths,
601 : pppfLCLDReal_fx,
602 : pppfLCLDImag_fx,
603 0 : *q_final,
604 : &psLCLDEncoder->iMSMode,
605 0 : psLCLDEncoder->piLRPhaseDiffs,
606 0 : psLCLDEncoder->piMSPredCoefs,
607 : psLCLDEncoder->iAllowSidePred,
608 : psLCLDEncoder->iRealOnlyOut,
609 : psLCLDEncoder->piMSFlags );
610 0 : IF( GT_32( psLCLDEncoder->iMSMode, 0 ) )
611 : {
612 0 : psLCLDEncoder->iCommonGrouping = 1; // Make sure common grouping is enabled when MS is in use
613 : }
614 : }
615 : /* Compute Grouping and RMS Envelopes */
616 0 : IF( EQ_32( psLCLDEncoder->iChannels, 2 ) && EQ_32( psLCLDEncoder->iCommonGrouping, 1 ) )
617 : {
618 0 : ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping,
619 : psLCLDEncoder->iChannels,
620 : psLCLDEncoder->iNumBands,
621 : psLCLDEncoder->piBandwidths,
622 : pppfLCLDReal_fx,
623 : pppfLCLDImag_fx,
624 : &psLCLDEncoder->piNumGroups[0],
625 0 : psLCLDEncoder->ppiGroupLengths[0],
626 : psLCLDEncoder->pppiRMSEnvelope,
627 0 : *q_final );
628 0 : psLCLDEncoder->piNumGroups[1] = psLCLDEncoder->piNumGroups[0];
629 0 : FOR( n = 0; n < psLCLDEncoder->piNumGroups[0]; n++ )
630 : {
631 0 : psLCLDEncoder->ppiGroupLengths[1][n] = psLCLDEncoder->ppiGroupLengths[0][n];
632 0 : move32();
633 : }
634 : }
635 : ELSE
636 : {
637 0 : FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
638 : {
639 0 : ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping,
640 : psLCLDEncoder->iChannels,
641 : psLCLDEncoder->iNumBands,
642 : psLCLDEncoder->piBandwidths,
643 0 : &pppfLCLDReal_fx[n],
644 0 : &pppfLCLDImag_fx[n],
645 0 : &psLCLDEncoder->piNumGroups[n],
646 0 : psLCLDEncoder->ppiGroupLengths[n],
647 0 : &psLCLDEncoder->pppiRMSEnvelope[n], *q_final );
648 : }
649 : }
650 :
651 0 : FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
652 : {
653 0 : RemoveRMSEnvelope( psLCLDEncoder->iNumBands,
654 : psLCLDEncoder->piBandwidths,
655 0 : psLCLDEncoder->piNumGroups[n],
656 0 : (const Word32 *) psLCLDEncoder->ppiGroupLengths[n],
657 0 : psLCLDEncoder->pppiRMSEnvelope[n],
658 0 : pppfLCLDReal_fx[n],
659 0 : pppfLCLDImag_fx[n] );
660 : }
661 0 : *q_final = add( *q_final, 9 ); // Increasing the Q as it has changed inside the RemoveRMSEnvelope
662 :
663 0 : ComputePredictors_fx( psLCLDEncoder->psPredictionEncoder, pppfLCLDReal_fx, pppfLCLDImag_fx );
664 :
665 0 : iBitsWritten = L_add( iBitsWritten, WriteHeaderInformation( psLCLDEncoder->iNumBands, pBits ) );
666 :
667 0 : IF( EQ_32( psLCLDEncoder->iChannels, 2 ) )
668 : {
669 0 : iBitsWritten = L_add( iBitsWritten, WriteMSInformation( psLCLDEncoder->iNumBands,
670 : psLCLDEncoder->iMSMode,
671 0 : (const Word32 *) psLCLDEncoder->piMSFlags,
672 0 : (const Word32 *) psLCLDEncoder->piLRPhaseDiffs,
673 0 : (const Word32 *) psLCLDEncoder->piMSPredCoefs,
674 : iNumMSBands,
675 : pBits ) );
676 : }
677 :
678 :
679 0 : iBitsWritten = L_add( iBitsWritten, WritePredictors( psLCLDEncoder->psPredictionEncoder, pBits ) );
680 :
681 0 : iBitsWritten = L_add( iBitsWritten, WriteGroupInformation( psLCLDEncoder->iChannels, psLCLDEncoder->iCommonGrouping, (const Word32 *) psLCLDEncoder->piNumGroups, psLCLDEncoder->ppiGroupLengths, pBits ) );
682 :
683 0 : iBitsWritten = L_add( iBitsWritten, WriteRMSEnvelope( psLCLDEncoder->iChannels, (const Word32 *) psLCLDEncoder->piNumGroups, psLCLDEncoder->iNumBands, psLCLDEncoder->pppiRMSEnvelope, pBits ) );
684 :
685 :
686 0 : IF( EQ_32( psLCLDEncoder->iChannels, 2 ) && EQ_32( psLCLDEncoder->iCommonGrouping, 1 ) )
687 0 : {
688 : Word32 k;
689 0 : FOR( k = 0; k < psLCLDEncoder->piNumGroups[0]; k++ )
690 : {
691 0 : PerceptualModelStereo_fx( psLCLDEncoder->iNumBands,
692 0 : psLCLDEncoder->piMSFlags,
693 0 : psLCLDEncoder->pppiRMSEnvelope[0][k],
694 0 : psLCLDEncoder->pppiRMSEnvelope[1][k],
695 0 : psLCLDEncoder->pppiExcitation[0][k],
696 0 : psLCLDEncoder->pppiExcitation[1][k],
697 0 : psLCLDEncoder->pppiSMR[0][k],
698 0 : psLCLDEncoder->pppiSMR[1][k] );
699 : }
700 : }
701 : ELSE
702 : {
703 0 : FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
704 : {
705 : Word32 k;
706 0 : FOR( k = 0; k < psLCLDEncoder->piNumGroups[n]; k++ )
707 : {
708 0 : PerceptualModel_fx( psLCLDEncoder->iNumBands,
709 0 : psLCLDEncoder->pppiRMSEnvelope[n][k],
710 0 : psLCLDEncoder->pppiExcitation[n][k],
711 0 : psLCLDEncoder->pppiSMR[n][k] );
712 : }
713 : }
714 : }
715 : #ifdef DEBUG_WRITE_PREDICTORS
716 : {
717 : static FILE *fid;
718 : if ( !fid )
719 : fid = fopen( "pred_enc.txt", "wt" );
720 : for ( n = 0; n < psLCLDEncoder->iChannels; n++ )
721 : {
722 : int16_t b;
723 : for ( b = 0; b < 60; b++ )
724 : fprintf( fid, "%.5f ", (float) psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable[n][b] * psLCLDEncoder->psPredictionEncoder->ppfA1Imag[n][b] );
725 : }
726 : fprintf( fid, "%d %d\n", psLCLDEncoder->psPredictionEncoder->iSubSetId, psLCLDEncoder->psPredictionEncoder->piPredChanEnable[n] );
727 : }
728 : #endif
729 0 : iAvailableBits = L_sub( iAvailableBits, iBitsWritten );
730 :
731 0 : ComputeAllocation( psLCLDEncoder->iChannels,
732 0 : (const Word32 *) psLCLDEncoder->piNumGroups,
733 : psLCLDEncoder->ppiGroupLengths,
734 : psLCLDEncoder->iNumBands,
735 : psLCLDEncoder->piBandwidths,
736 : pppfLCLDReal_fx,
737 : pppfLCLDImag_fx,
738 0 : *q_final,
739 : psLCLDEncoder->pppiSMR,
740 : iAvailableBits,
741 : &psLCLDEncoder->iAllocOffset,
742 : psLCLDEncoder->pppiAlloc,
743 : psLCLDEncoder->pppiQLCLDReal,
744 : psLCLDEncoder->pppiQLCLDImag,
745 : psLCLDEncoder->pppiLCLDSignReal,
746 : psLCLDEncoder->pppiLCLDSignImag,
747 : psLCLDEncoder->psPredictionEncoder );
748 :
749 0 : iBitsWritten = L_add( iBitsWritten, WriteAllocInformation( psLCLDEncoder->iAllocOffset,
750 : pBits ) );
751 0 : iAudioBitsWritten = iBitsWritten;
752 0 : iBitsWritten = L_add( iBitsWritten, WriteLCLDData( psLCLDEncoder->piNumGroups,
753 : psLCLDEncoder->ppiGroupLengths,
754 : psLCLDEncoder->iNumBands,
755 : psLCLDEncoder->iChannels,
756 0 : psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable,
757 0 : psLCLDEncoder->psPredictionEncoder->iNumSubSets,
758 0 : psLCLDEncoder->psPredictionEncoder->iSubSetId,
759 : psLCLDEncoder->pppiAlloc,
760 : psLCLDEncoder->pppiLCLDSignReal,
761 : psLCLDEncoder->pppiLCLDSignImag,
762 : psLCLDEncoder->pppiQLCLDReal,
763 : psLCLDEncoder->pppiQLCLDImag,
764 : pBits ) );
765 0 : *piBitsWritten = iBitsWritten;
766 0 : move32();
767 0 : iAudioBitsWritten = L_sub( iBitsWritten, iAudioBitsWritten );
768 :
769 0 : UpdatePredictionSubSetId( psLCLDEncoder->psPredictionEncoder );
770 :
771 0 : return 0;
772 : }
773 :
774 : /*------------------------------------------------------------------------------------------*
775 : * Function GetNumGroups()
776 : *
777 : *
778 : *------------------------------------------------------------------------------------------*/
779 :
780 0 : Word32 GetNumGroups( LCLDEncoder *psLCLDEncoder )
781 : {
782 0 : return psLCLDEncoder->piNumGroups[0];
783 : }
784 :
785 :
786 : /*------------------------------------------------------------------------------------------*
787 : * Local functions
788 : *
789 : *
790 : *------------------------------------------------------------------------------------------*/
791 :
792 : enum MSPred_Types
793 : {
794 : MS_PHASE_AND_PRED = 0, /* LR phase alignment + real-valued M/S prediction */
795 : MS_PRED_ONLY = 1, /* real-valued M/S prediction */
796 : MS_PHASE_ONLY = 2 /* LR phase alignment + M/S */
797 : };
798 :
799 : enum MS_BS_TYPES
800 : {
801 : MS_OFF = 0,
802 : MS_ALL = 1,
803 : MS_SOME = 2,
804 : MS_PRED = 3
805 : };
806 :
807 0 : static Word32 MSModeCalculation_fx(
808 : const Word32 iNumBlocks,
809 : const Word32 iNumBands,
810 : const Word32 *piBandwidths,
811 : /*float ***pppfReal,
812 : float ***pppfImag,*/
813 : Word32 ***pppfReal_fx,
814 : Word32 ***pppfImag_fx,
815 : Word16 Q_in,
816 : Word32 *piMSMode,
817 : Word32 *piLRPhaseDiffs,
818 : Word32 *piMSPredCoefs,
819 : const Word32 iAllowSidePred,
820 : const Word32 iRealOnlyOut,
821 : Word32 *piMSFlags )
822 : {
823 : Word32 b;
824 : Word32 iFBOffset;
825 : Word32 iNumMSBands;
826 : Word32 iMSPredType;
827 : /*float fMSBitGain = 0.0f;
828 : float pfMSPredBitGain[3] = { 0.0f };
829 : float fPred;*/
830 0 : Word32 fMSBitGain_fx = 0;
831 0 : Word32 pfMSPredBitGain_fx[3] = { 0 };
832 : Word32 fPred_fx;
833 0 : Word32 piMSPredFlags0[MAX_BANDS] = { 0 };
834 0 : Word32 piMSPredFlags1[MAX_BANDS] = { 0 };
835 0 : Word32 piMSPredFlags2[MAX_BANDS] = { 0 };
836 : Word32 *ppiMSPredFlags[3];
837 0 : Word32 piMSPredCoefs0[MAX_BANDS] = { 0 };
838 0 : Word32 piMSPredCoefs1[MAX_BANDS] = { 0 };
839 0 : Word32 piMSPredCoefs2[MAX_BANDS] = { 0 };
840 : Word32 *ppiMSPredCoefs[3];
841 0 : Word32 piMSPredPhase0[MAX_BANDS] = { 0 };
842 0 : Word32 piMSPredPhase1[MAX_BANDS] = { 0 };
843 0 : Word32 piMSPredPhase2[MAX_BANDS] = { 0 };
844 : Word32 *ppiMSPredPhase[3];
845 : Word32 iMsInfoBits;
846 0 : Word32 piMsPredInfoBits[3] = { 0 };
847 :
848 : // const float feps = 1e-12f;
849 : // float fBitsFactor = 3.32192809488736f; /* = 1/log10(2), from dB/10 to bits assuming 1 bit per log2(SNR) or 1 bit per 3dB SNR */
850 0 : const Word32 feps_fx = 1; // is this correct?
851 0 : move32();
852 0 : Word32 fBitsFactor_fx = 1783446565; /* = 1/log10(2) (Q29), from dB/10 to bits assuming 1 bit per log2(SNR) or 1 bit per 3dB SNR */
853 0 : move32();
854 0 : IF( LT_32( iNumBlocks, LCLD_BLOCKS_PER_FRAME ) )
855 : {
856 : // fBitsFactor *= ( 0.7f + (float) ( iNumBlocks - 4 ) / (float) ( LCLD_BLOCKS_PER_FRAME - 4 ) * ( 1.0f - 0.7f ) ); /* Tuning for relatively higher side rate due to shorter frame length */
857 0 : fBitsFactor_fx = Mpy_32_32( fBitsFactor_fx, L_add( 1503238553, W_extract_l( W_mult0_32_32( L_sub( iNumBlocks, 4 ), 596523235 ) ) ) ); /* Tuning for relatively higher side rate due to shorter frame length */
858 : }
859 :
860 0 : ppiMSPredFlags[0] = piMSPredFlags0;
861 0 : move32();
862 0 : ppiMSPredFlags[1] = piMSPredFlags1;
863 0 : move32();
864 0 : ppiMSPredFlags[2] = piMSPredFlags2;
865 0 : move32();
866 0 : ppiMSPredCoefs[0] = piMSPredCoefs0;
867 0 : move32();
868 0 : ppiMSPredCoefs[1] = piMSPredCoefs1;
869 0 : move32();
870 0 : ppiMSPredCoefs[2] = piMSPredCoefs2;
871 0 : move32();
872 0 : ppiMSPredPhase[0] = piMSPredPhase0;
873 0 : move32();
874 0 : ppiMSPredPhase[1] = piMSPredPhase1;
875 0 : move32();
876 0 : ppiMSPredPhase[2] = piMSPredPhase2;
877 0 : move32();
878 0 : *piMSMode = MS_OFF;
879 0 : move32();
880 0 : iFBOffset = 0;
881 0 : move32();
882 0 : iNumMSBands = 0;
883 0 : move32();
884 0 : FOR( b = 0; b < iNumBands; b++ )
885 : {
886 : Word32 n;
887 : /*float fLeftEnergy;
888 : float fRightEnergy;
889 : float fMidEnergy;
890 : float fSideEnergy;
891 : float fLRRatio;
892 : float fMSRatio;
893 : float pfMSPredRatio[3] = { 0.0f };
894 : float fMidEnergyPred;
895 : float fSideEnergyPred;
896 : float fLRCovReal = 0.0f;
897 : float fLRCovImag = 0.0f;*/
898 : Word32 fLeftEnergy_fx;
899 : Word32 fRightEnergy_fx;
900 : Word32 fMidEnergy_fx;
901 : Word32 fSideEnergy_fx;
902 : Word64 fLeftEnergy_fx64;
903 : Word64 fRightEnergy_fx64;
904 : Word64 fMidEnergy_fx64;
905 : Word64 fSideEnergy_fx64;
906 : Word32 fLRRatio_fx;
907 : Word32 fMSRatio_fx;
908 0 : Word32 pfMSPredRatio_fx[3] = { 0 };
909 : Word32 fMidEnergyPred_fx;
910 : Word32 fSideEnergyPred_fx;
911 0 : Word32 fLRCovReal_fx = 0;
912 0 : Word32 fLRCovImag_fx = 0;
913 0 : Word64 fLRCovReal_fx64 = 0;
914 0 : Word64 fLRCovImag_fx64 = 0;
915 : Word32 iPhase;
916 : Word32 iPred;
917 0 : Word32 tabIdx = 0;
918 : // float fNumLines = (float)(iRealOnlyOut == 1 ? iNumBlocks * piBandwidths[b] * 4 : iNumBlocks * piBandwidths[b] * 2); /* per band per channel */
919 : // float fLevelToSMRdBFactor = (float) c_aiDefaultTheta48[b] / (float) ( 1 << PERCEPTUAL_MODEL_SLGAIN_SHIFT ); /* frequency dependent SMR slope in psy model */
920 0 : Word32 fNumLines_fx = iRealOnlyOut == 1 ? L_shl( iNumBlocks * piBandwidths[b], 2 ) : L_shl( iNumBlocks * piBandwidths[b], 1 ); /* per band per channel */
921 0 : Word32 fLevelToSMRdBFactor_fx = L_shl( c_aiDefaultTheta48[b], 23 ); /* frequency dependent SMR slope in psy model Q23:sub(Q31, PERCEPTUAL_MODEL_SLGAIN_SHIFT) */
922 0 : fLeftEnergy_fx = 0;
923 0 : fRightEnergy_fx = 0;
924 0 : fMidEnergy_fx = 0;
925 0 : fSideEnergy_fx = 0;
926 0 : fLeftEnergy_fx64 = 0;
927 0 : fRightEnergy_fx64 = 0;
928 0 : fMidEnergy_fx64 = 0;
929 0 : fSideEnergy_fx64 = 0;
930 0 : Word16 Q_en_tmp = 63;
931 :
932 0 : FOR( n = 0; n < piBandwidths[b]; n++ )
933 : {
934 : Word32 k;
935 0 : FOR( k = 0; k < iNumBlocks; k++ )
936 : {
937 : /*float fMidReal;
938 : float fMidImag;
939 : float fSideReal;
940 : float fSideImag;*/
941 : Word32 fMidReal_fx;
942 : Word32 fMidImag_fx;
943 : Word32 fSideReal_fx;
944 : Word32 fSideImag_fx;
945 :
946 : // fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] );
947 0 : fMidReal_fx = L_shr( L_add( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 );
948 : // fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] );
949 0 : fMidImag_fx = L_shr( L_add( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 );
950 : // fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] );
951 0 : fSideReal_fx = L_shr( L_sub( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 );
952 : // fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] );
953 0 : fSideImag_fx = L_shr( L_sub( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 );
954 :
955 : // fLeftEnergy += ( pppfReal[0][k][iFBOffset] * pppfReal[0][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[0][k][iFBOffset] );
956 0 : fLeftEnergy_fx64 = W_add( fLeftEnergy_fx64, W_add( W_mult0_32_32( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[0][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[0][k][iFBOffset] ) ) );
957 : // fRightEnergy += ( pppfReal[1][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[1][k][iFBOffset] * pppfImag[1][k][iFBOffset] );
958 0 : fRightEnergy_fx64 = W_add( fRightEnergy_fx64, W_add( W_mult0_32_32( pppfReal_fx[1][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[1][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ) ) );
959 : // fMidEnergy += ( fMidReal * fMidReal + fMidImag * fMidImag );
960 0 : fMidEnergy_fx64 = W_add( fMidEnergy_fx64, W_add( W_mult0_32_32( fMidReal_fx, fMidReal_fx ), W_mult0_32_32( fMidImag_fx, fMidImag_fx ) ) );
961 : // fSideEnergy += ( fSideReal * fSideReal + fSideImag * fSideImag );
962 0 : fSideEnergy_fx64 = W_add( fSideEnergy_fx64, W_add( W_mult0_32_32( fSideReal_fx, fSideReal_fx ), W_mult0_32_32( fSideImag_fx, fSideImag_fx ) ) );
963 :
964 : // fLRCovReal += ( pppfReal[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[1][k][iFBOffset] );
965 0 : fLRCovReal_fx64 = W_add( fLRCovReal_fx64, W_add( W_mult0_32_32( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ) ) );
966 : // fLRCovImag += ( pppfImag[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] - pppfImag[1][k][iFBOffset] * pppfReal[0][k][iFBOffset] );
967 0 : fLRCovImag_fx64 = W_add( fLRCovImag_fx64, W_sub( W_mult0_32_32( pppfImag_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[1][k][iFBOffset], pppfReal_fx[0][k][iFBOffset] ) ) );
968 : }
969 :
970 0 : iFBOffset++;
971 : }
972 0 : Q_en_tmp = min( Q_en_tmp, W_norm( fLeftEnergy_fx64 ) );
973 0 : Q_en_tmp = min( Q_en_tmp, W_norm( fRightEnergy_fx64 ) );
974 0 : Q_en_tmp = min( Q_en_tmp, W_norm( fMidEnergy_fx64 ) );
975 0 : Q_en_tmp = min( Q_en_tmp, W_norm( fSideEnergy_fx64 ) );
976 0 : Q_en_tmp = min( Q_en_tmp, W_norm( fLRCovReal_fx64 ) );
977 0 : Q_en_tmp = min( Q_en_tmp, W_norm( fLRCovImag_fx64 ) );
978 0 : Q_en_tmp = sub( Q_en_tmp, 2 );
979 0 : fLeftEnergy_fx = W_extract_h( W_shl( fLeftEnergy_fx64, Q_en_tmp ) );
980 0 : fRightEnergy_fx = W_extract_h( W_shl( fRightEnergy_fx64, Q_en_tmp ) );
981 0 : fMidEnergy_fx = W_extract_h( W_shl( fMidEnergy_fx64, Q_en_tmp ) );
982 0 : fSideEnergy_fx = W_extract_h( W_shl( fSideEnergy_fx64, Q_en_tmp ) );
983 0 : fLRCovReal_fx = W_extract_h( W_shl( fLRCovReal_fx64, Q_en_tmp ) );
984 0 : fLRCovImag_fx = W_extract_h( W_shl( fLRCovImag_fx64, Q_en_tmp ) );
985 0 : Word16 Q_en = add( shl( Q_in, 1 ), sub( Q_en_tmp, 32 ) ) /*2 * Q_in - 31 - 2*/;
986 : /* M/S prediction without phase alignment*/
987 : // fPred = 0.25f * ( fLeftEnergy - fRightEnergy ) / ( fMidEnergy + feps );
988 : // iPred = quantPred(fPred);
989 : // fPred = dequantPred(iPred);
990 : Word16 exp;
991 0 : fPred_fx = BASOP_Util_Divide3232_Scale( L_sub( fLeftEnergy_fx, fRightEnergy_fx ), L_add( fMidEnergy_fx, feps_fx ), &exp );
992 0 : exp = sub( exp, 2 ); //*0.25f
993 0 : fPred_fx = L_shl( fPred_fx, 16 );
994 0 : iPred = quantPred_fx( fPred_fx, exp );
995 0 : fPred_fx = dequantPred_fx( iPred ); // Q31
996 : // fSideEnergyPred = fSideEnergy + ( fPred * fPred * fMidEnergy - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) );
997 0 : fSideEnergyPred_fx = L_add( fSideEnergy_fx,
998 : L_sub( Mpy_32_32( Mpy_32_32( fPred_fx, fPred_fx ), fMidEnergy_fx ),
999 : L_shr( Mpy_32_32( fPred_fx, L_sub( fLeftEnergy_fx, fRightEnergy_fx ) ), 1 ) ) );
1000 0 : fSideEnergyPred_fx = max( fSideEnergyPred_fx, 0 );
1001 :
1002 0 : ppiMSPredCoefs[MS_PRED_ONLY][b] = iPred;
1003 0 : move32();
1004 0 : ppiMSPredPhase[MS_PRED_ONLY][b] = 0;
1005 0 : move32();
1006 : // pfMSPredRatio[MS_PRED_ONLY] = log10f( ( fMidEnergy + feps ) / ( fSideEnergyPred + feps ) );
1007 0 : pfMSPredRatio_fx[MS_PRED_ONLY] = Mpy_32_32( L_sub( BASOP_Util_Log2( L_add( fMidEnergy_fx, feps_fx ) ), BASOP_Util_Log2( L_add( fSideEnergyPred_fx, feps_fx ) ) ), LOG10_2_FX ); // Q25
1008 : // printf("%f ", (float)pfMSPredRatio_fx[MS_PRED_ONLY] / (1 << 25));
1009 :
1010 : /* Phase alignment*/
1011 0 : iPhase = 0;
1012 0 : move32();
1013 : // if ( fLRCovReal * fLRCovReal + fLRCovImag * fLRCovImag > 0.5f * fLeftEnergy * fRightEnergy )
1014 0 : IF( GT_32( L_add( Mpy_32_32( fLRCovReal_fx, fLRCovReal_fx ), Mpy_32_32( fLRCovImag_fx, fLRCovImag_fx ) ), L_shr( Mpy_32_32( fLeftEnergy_fx, fRightEnergy_fx ), 1 ) ) )
1015 : {
1016 : // float fPhase = atan2f( fLRCovImag, fLRCovReal );
1017 0 : Word32 fPhase_fx = BASOP_util_atan2( fLRCovImag_fx, fLRCovReal_fx, 0 );
1018 0 : exp = sub( 18, norm_l( fPhase_fx ) );
1019 0 : fPhase_fx = L_shl( fPhase_fx, norm_l( fPhase_fx ) ); // Q31
1020 : // iPhase = quantPhase( fPhase );
1021 0 : iPhase = quantPhase_fx( fPhase_fx, exp );
1022 : }
1023 :
1024 : /* adjust covariance */
1025 0 : tabIdx = L_sub( iPhase, PHASE_MIN_VAL );
1026 : // cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] );
1027 0 : cplxmult_fx( &fLRCovReal_fx, &fLRCovImag_fx, c_afRotRealImag_fx[tabIdx][0], -c_afRotRealImag_fx[tabIdx][1] );
1028 :
1029 : /* compute MS prediction coefficient based on adjusted covariance */
1030 : // fMidEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy + 2.0f * fLRCovReal );
1031 0 : fMidEnergyPred_fx = L_add( L_add( L_shr_r( fLeftEnergy_fx, 2 ), L_shr_r( fRightEnergy_fx, 2 ) ), L_shr( fLRCovReal_fx, 1 ) ); // Q_en
1032 : // fSideEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy - 2.0f * fLRCovReal );
1033 0 : fSideEnergyPred_fx = L_sub( L_add( L_shr_r( fLeftEnergy_fx, 2 ), L_shr_r( fRightEnergy_fx, 2 ) ), L_shr( fLRCovReal_fx, 1 ) ); // Q_en
1034 0 : fSideEnergyPred_fx = L_max( fSideEnergyPred_fx, 0 );
1035 :
1036 : /* M/S with LR phase alignment but without prediction */
1037 0 : ppiMSPredCoefs[MS_PHASE_ONLY][b] = 0;
1038 0 : move32();
1039 0 : ppiMSPredPhase[MS_PHASE_ONLY][b] = iPhase;
1040 0 : move32();
1041 : // pfMSPredRatio[MS_PHASE_ONLY] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) );
1042 0 : pfMSPredRatio_fx[MS_PHASE_ONLY] = Mpy_32_32( L_sub( BASOP_Util_Log2( L_add( fMidEnergyPred_fx, feps_fx ) ), BASOP_Util_Log2( L_add( fSideEnergyPred_fx, feps_fx ) ) ), LOG10_2_FX ); // Q25
1043 : // printf("%f ", (float)pfMSPredRatio_fx[MS_PHASE_ONLY] / (1 << 25));
1044 :
1045 : /* M/S with LR phase alignment and prediction */
1046 : // fPred = fMidEnergyPred == 0.0f ? 0.0f : 0.25f * ( fLeftEnergy - fRightEnergy ) / fMidEnergyPred;
1047 0 : fPred_fx = fMidEnergyPred_fx == 0 ? 0 : BASOP_Util_Divide3232_Scale( L_sub( fLeftEnergy_fx, fRightEnergy_fx ), fMidEnergyPred_fx, &exp );
1048 0 : exp = sub( exp, 2 ); //*0.25f
1049 0 : fPred_fx = L_shl( fPred_fx, 16 );
1050 : // iPred = quantPred( fPred );
1051 0 : iPred = quantPred_fx( fPred_fx, exp );
1052 : // fPred = dequantPred( iPred );
1053 0 : fPred_fx = dequantPred_fx( iPred );
1054 : // fSideEnergyPred += ( fPred * fPred * fMidEnergyPred - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) );
1055 0 : fSideEnergyPred_fx = L_add( fSideEnergyPred_fx,
1056 : L_sub( Mpy_32_32( Mpy_32_32( fPred_fx, fPred_fx ), fMidEnergyPred_fx ),
1057 : L_shr( Mpy_32_32( fPred_fx, L_sub( fLeftEnergy_fx, fRightEnergy_fx ) ), 1 ) ) );
1058 0 : fSideEnergyPred_fx = max( fSideEnergyPred_fx, 0 );
1059 : /* -= fPred * fPred * fMidEnergyPred doesn't work because fPred is quantized and does not match MS/MM exactly */
1060 0 : ppiMSPredCoefs[MS_PHASE_AND_PRED][b] = iPred;
1061 0 : move32();
1062 0 : ppiMSPredPhase[MS_PHASE_AND_PRED][b] = iPhase;
1063 0 : move32();
1064 : // pfMSPredRatio[MS_PHASE_AND_PRED] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) );
1065 0 : pfMSPredRatio_fx[MS_PHASE_AND_PRED] = Mpy_32_32( L_sub( BASOP_Util_Log2( L_add( fMidEnergyPred_fx, feps_fx ) ), BASOP_Util_Log2( L_add( fSideEnergyPred_fx, feps_fx ) ) ), LOG10_2_FX ); // Q25
1066 : // printf("%f ", (float)pfMSPredRatio_fx[MS_PHASE_AND_PRED] / (1 << 25));
1067 :
1068 : /* Plain M/S */
1069 : // fLeftEnergy = log10f( fLeftEnergy + feps );
1070 0 : exp = sub( 31, Q_en ); // 31 - Q
1071 0 : fLeftEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fLeftEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25
1072 : // fRightEnergy = log10f( fRightEnergy + feps );
1073 0 : fRightEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fRightEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25
1074 : // fMidEnergy = log10f( fMidEnergy + feps );
1075 0 : fMidEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fMidEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25
1076 : // fSideEnergy = log10f( fSideEnergy + feps );
1077 0 : fSideEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fSideEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25
1078 :
1079 : // fLRRatio = ( fLeftEnergy > fRightEnergy ? fLeftEnergy - fRightEnergy : fRightEnergy - fLeftEnergy );
1080 0 : fLRRatio_fx = ( fLeftEnergy_fx > fRightEnergy_fx ? L_sub( fLeftEnergy_fx, fRightEnergy_fx ) : L_sub( fRightEnergy_fx, fLeftEnergy_fx ) ); // Q25
1081 : // fMSRatio = ( fMidEnergy > fSideEnergy ? fMidEnergy - fSideEnergy : fSideEnergy - fMidEnergy );
1082 0 : fMSRatio_fx = ( fMidEnergy_fx > fSideEnergy_fx ? L_sub( fMidEnergy_fx, fSideEnergy_fx ) : L_sub( fSideEnergy_fx, fMidEnergy_fx ) ); // Q25
1083 :
1084 : // if ( fMSRatio > fLRRatio )
1085 0 : IF( GT_32( fMSRatio_fx, fLRRatio_fx ) )
1086 : {
1087 0 : iNumMSBands++;
1088 0 : piMSFlags[b] = 1;
1089 0 : move32();
1090 : // fMSBitGain += fNumLines * ( fMSRatio - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor;
1091 0 : fMSBitGain_fx = L_add( fMSBitGain_fx, W_extract_l( W_shr( W_mult0_32_32( fNumLines_fx, Mpy_32_32( Mpy_32_32( L_sub( fMSRatio_fx, fLRRatio_fx ), fLevelToSMRdBFactor_fx ), fBitsFactor_fx ) ), 7 ) ) ); // Q16
1092 : }
1093 : ELSE
1094 : {
1095 0 : piMSFlags[b] = 0;
1096 0 : move32();
1097 : }
1098 0 : piLRPhaseDiffs[b] = 0;
1099 0 : move32();
1100 0 : piMSPredCoefs[b] = 0;
1101 0 : move32();
1102 :
1103 : /* MSPred bit gains based on increase of level ratio compared to L/R ratio and the level dependent psy-model */
1104 0 : FOR( iMSPredType = 0; iMSPredType < 3; iMSPredType++ )
1105 : {
1106 : // if ( pfMSPredRatio[iMSPredType] > fLRRatio )
1107 0 : IF( GT_32( pfMSPredRatio_fx[iMSPredType], fLRRatio_fx ) )
1108 : {
1109 0 : ppiMSPredFlags[iMSPredType][b] = 1;
1110 0 : move32();
1111 : // pfMSPredBitGain[iMSPredType] += fNumLines * ( pfMSPredRatio[iMSPredType] - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor;
1112 0 : pfMSPredBitGain_fx[iMSPredType] = L_add( pfMSPredBitGain_fx[iMSPredType],
1113 : W_extract_l( W_shr( W_mult0_32_32( fNumLines_fx,
1114 : Mpy_32_32( Mpy_32_32( L_sub( pfMSPredRatio_fx[iMSPredType], fLRRatio_fx ), fLevelToSMRdBFactor_fx ),
1115 : fBitsFactor_fx ) ),
1116 : 7 ) ) ); // Q16
1117 : }
1118 : }
1119 : }
1120 0 : Word16 q_fMSBitGain_fx = Q16;
1121 0 : move16();
1122 0 : Word16 q_pfMSPredBitGain_fx = Q16; // Q23-7
1123 0 : move16();
1124 : /* remove signalling cost from bit gains */
1125 0 : FOR( iMSPredType = 0; iMSPredType < 3; iMSPredType++ )
1126 : {
1127 0 : piMsPredInfoBits[iMSPredType] = CountMSBits( iNumBands, MS_PRED, ppiMSPredFlags[iMSPredType], ppiMSPredPhase[iMSPredType], ppiMSPredCoefs[iMSPredType] );
1128 : // pfMSPredBitGain[iMSPredType] = max( pfMSPredBitGain[iMSPredType] - piMsPredInfoBits[iMSPredType], 0.0f );
1129 0 : pfMSPredBitGain_fx[iMSPredType] = max( pfMSPredBitGain_fx[iMSPredType] - L_shl( piMsPredInfoBits[iMSPredType], q_pfMSPredBitGain_fx ), 0 );
1130 : }
1131 :
1132 : /* find the best M/S Pred type */
1133 0 : IF( EQ_32( iRealOnlyOut, 1 ) )
1134 : {
1135 0 : iMSPredType = MS_PRED_ONLY;
1136 0 : move32();
1137 : }
1138 : ELSE
1139 : {
1140 0 : iMSPredType = MS_PHASE_AND_PRED;
1141 0 : move32();
1142 : // iMSPredType = ( pfMSPredBitGain[MS_PRED_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PRED_ONLY : iMSPredType );
1143 0 : iMSPredType = ( pfMSPredBitGain_fx[MS_PRED_ONLY] > pfMSPredBitGain_fx[iMSPredType] ? MS_PRED_ONLY : iMSPredType );
1144 : // iMSPredType = ( pfMSPredBitGain[MS_PHASE_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PHASE_ONLY : iMSPredType );
1145 0 : iMSPredType = ( pfMSPredBitGain_fx[MS_PHASE_ONLY] > pfMSPredBitGain_fx[iMSPredType] ? MS_PHASE_ONLY : iMSPredType );
1146 : }
1147 :
1148 : /* plain M/S */
1149 0 : iMsInfoBits = CountMSBits( iNumBands, MS_SOME, piMSFlags, NULL, NULL );
1150 : // fMSBitGain = max( fMSBitGain - iMsInfoBits, 0.0f );
1151 0 : fMSBitGain_fx = L_max( L_sub( fMSBitGain_fx, L_shl( iMsInfoBits, q_fMSBitGain_fx ) ), 0 ); // Q_en -2
1152 : // if ( iAllowSidePred && pfMSPredBitGain[iMSPredType] > 1.1f * fMSBitGain )
1153 0 : test();
1154 0 : IF( iAllowSidePred && GT_32( L_shr_r( pfMSPredBitGain_fx[iMSPredType], sub( q_pfMSPredBitGain_fx, q_fMSBitGain_fx ) ), L_add( fMSBitGain_fx, Mpy_32_32( fMSBitGain_fx, 214748364 ) ) ) )
1155 : {
1156 0 : *piMSMode = MS_PRED;
1157 0 : move32();
1158 0 : iNumMSBands = 0;
1159 0 : move32();
1160 0 : FOR( b = 0; b < iNumBands; b++ )
1161 : {
1162 0 : piMSFlags[b] = ppiMSPredFlags[iMSPredType][b];
1163 0 : IF( EQ_32( piMSFlags[b], 1 ) )
1164 : {
1165 0 : piMSPredCoefs[b] = ppiMSPredCoefs[iMSPredType][b];
1166 0 : move32();
1167 0 : piLRPhaseDiffs[b] = ppiMSPredPhase[iMSPredType][b];
1168 0 : move32();
1169 0 : iNumMSBands++;
1170 : }
1171 : ELSE
1172 : {
1173 0 : piMSPredCoefs[b] = 0;
1174 0 : move32();
1175 0 : piLRPhaseDiffs[b] = 0;
1176 0 : move32();
1177 : }
1178 : }
1179 : }
1180 0 : ELSE IF( EQ_32( iNumMSBands, iNumBands ) )
1181 : {
1182 0 : *piMSMode = MS_ALL;
1183 0 : move32();
1184 : }
1185 0 : ELSE IF( GT_32( iNumMSBands, 0 ) )
1186 : {
1187 0 : *piMSMode = MS_SOME;
1188 0 : move32();
1189 : }
1190 : ELSE
1191 : {
1192 0 : *piMSMode = MS_OFF;
1193 0 : move32();
1194 : }
1195 : #ifdef DEBUG_WRITE_MS_PRED
1196 : {
1197 : static FILE *fid;
1198 : int32_t iActualInfoBits = CountMSBits( iNumBands, *piMSMode, piMSFlags, piLRPhaseDiffs, piMSPredCoefs );
1199 : if ( !fid )
1200 : fid = fopen( "ms_info_bits.txt", "wt" );
1201 : fprintf( fid, "%d %d %d %d %d\n", iMsInfoBits, piMsPredInfoBits[MS_PHASE_AND_PRED], piMsPredInfoBits[MS_PRED_ONLY], piMsPredInfoBits[MS_PHASE_ONLY], iActualInfoBits );
1202 : }
1203 : #endif
1204 0 : IF( NE_32( *piMSMode, MS_OFF ) )
1205 : {
1206 0 : iFBOffset = 0;
1207 0 : move32();
1208 0 : FOR( b = 0; b < iNumBands; b++ )
1209 : {
1210 0 : IF( EQ_32( piMSFlags[b], 1 ) )
1211 : {
1212 : Word32 n;
1213 : Word32 phaseIdx;
1214 0 : phaseIdx = L_sub( piLRPhaseDiffs[b], PHASE_MIN_VAL );
1215 : // fPred = dequantPred( piMSPredCoefs[b] );
1216 0 : fPred_fx = dequantPred_fx( piMSPredCoefs[b] ); // Q31
1217 0 : FOR( n = 0; n < piBandwidths[b]; n++ )
1218 : {
1219 : Word32 k;
1220 0 : FOR( k = 0; k < iNumBlocks; k++ )
1221 : {
1222 : /*float fMidReal;
1223 : float fMidImag;
1224 : float fSideReal;
1225 : float fSideImag;*/
1226 : Word32 fMidReal_fx;
1227 : Word32 fMidImag_fx;
1228 : Word32 fSideReal_fx;
1229 : Word32 fSideImag_fx;
1230 :
1231 0 : IF( EQ_32( *piMSMode, MS_PRED ) )
1232 : {
1233 : // cplxmult( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] );
1234 0 : cplxmult_fx( &pppfReal_fx[1][k][iFBOffset], &pppfImag_fx[1][k][iFBOffset], c_afRotRealImag_fx[phaseIdx][0], c_afRotRealImag_fx[phaseIdx][1] );
1235 : }
1236 :
1237 : // fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] );
1238 0 : fMidReal_fx = L_shr( L_add( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 );
1239 : // fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] );
1240 0 : fMidImag_fx = L_shr( L_add( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 );
1241 : // fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] );
1242 0 : fSideReal_fx = L_shr( L_sub( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 );
1243 : // fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] );
1244 0 : fSideImag_fx = L_shr( L_sub( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 );
1245 :
1246 0 : IF( EQ_32( *piMSMode, MS_PRED ) )
1247 : {
1248 : // fSideReal -= fPred * fMidReal;
1249 0 : fSideReal_fx = L_sub( fSideReal_fx, Mpy_32_32( fPred_fx, fMidReal_fx ) );
1250 : // fSideImag -= fPred * fMidImag;
1251 0 : fSideImag_fx = L_sub( fSideImag_fx, Mpy_32_32( fPred_fx, fMidImag_fx ) );
1252 : }
1253 :
1254 0 : pppfReal_fx[0][k][iFBOffset] = fMidReal_fx;
1255 0 : move32();
1256 0 : pppfReal_fx[1][k][iFBOffset] = fSideReal_fx;
1257 0 : move32();
1258 0 : pppfImag_fx[0][k][iFBOffset] = fMidImag_fx;
1259 0 : move32();
1260 0 : pppfImag_fx[1][k][iFBOffset] = fSideImag_fx;
1261 0 : move32();
1262 : }
1263 0 : iFBOffset++;
1264 : }
1265 : }
1266 : ELSE
1267 : {
1268 0 : iFBOffset = L_add( iFBOffset, piBandwidths[b] );
1269 : }
1270 : }
1271 : }
1272 : #ifdef DEBUG_WRITE_MS_PRED
1273 : {
1274 : static FILE *fid;
1275 : if ( !fid )
1276 : fid = fopen( "ms_enc.txt", "wt" );
1277 : writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags );
1278 : }
1279 : #endif
1280 0 : IF( EQ_32( *piMSMode, MS_PRED ) )
1281 : {
1282 : /* Differential Coding of Phase Data*/
1283 0 : PrepEncode( piLRPhaseDiffs, piMSFlags, iNumBands );
1284 0 : PrepEncode( piMSPredCoefs, piMSFlags, iNumBands );
1285 : #ifdef DEBUG_WRITE_MS_PRED
1286 : {
1287 : static FILE *fid;
1288 : if ( !fid )
1289 : fid = fopen( "ms_pred_enc.txt", "wt" );
1290 : writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags );
1291 : }
1292 : #endif
1293 : /* Differential Coding*/
1294 0 : EncodePhase( piLRPhaseDiffs, iNumMSBands, PHASE_DIFF_DIM );
1295 0 : EncodePredCoef( piMSPredCoefs, iNumMSBands );
1296 : }
1297 :
1298 0 : return iNumMSBands;
1299 : }
1300 0 : static void RemoveRMSEnvelope(
1301 : const Word32 iNumBands,
1302 : const Word32 *piBandwidths,
1303 : const Word32 iNumGroups,
1304 : const Word32 *piGroupLengths,
1305 : Word32 **ppiRMSEnvelope,
1306 : Word32 **ppfReal_fx,
1307 : Word32 **ppfImag_fx )
1308 : {
1309 : Word32 k, n, b, iFBOffset, m, iRMSEnv;
1310 : Word32 iBlockOffset;
1311 : Word32 fGain_fx;
1312 : Word16 fGain_exp;
1313 0 : iBlockOffset = 0;
1314 0 : move32();
1315 : Word64 tmp;
1316 0 : FOR( n = 0; n < iNumGroups; n++ )
1317 : {
1318 0 : FOR( k = 0; k < piGroupLengths[n]; k++ )
1319 : {
1320 0 : iFBOffset = 0;
1321 0 : move32();
1322 0 : FOR( b = 0; b < iNumBands; b++ )
1323 : {
1324 0 : iRMSEnv = ppiRMSEnvelope[n][b];
1325 0 : IF( EQ_32( L_add( ENV_RECONSTRUCT_TABLE_CENTER, iRMSEnv ) % 2, 0 ) )
1326 : {
1327 0 : fGain_fx = 1073741824; // 2 ^ 30
1328 0 : move32();
1329 : }
1330 : ELSE
1331 : {
1332 0 : fGain_fx = 1518500249; // sqrt(2) * 2 ^ 30
1333 0 : move32();
1334 : }
1335 0 : fGain_exp = c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_CENTER - iRMSEnv];
1336 0 : move16();
1337 0 : FOR( m = 0; m < piBandwidths[b]; m++ )
1338 : {
1339 0 : tmp = W_mult_32_32( fGain_fx, ppfReal_fx[iBlockOffset][iFBOffset] );
1340 0 : tmp = W_shr( tmp, sub( fGain_exp, 8 ) ); // Q to (input_q -9)
1341 0 : ppfReal_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp );
1342 0 : move32();
1343 0 : tmp = W_mult_32_32( fGain_fx, ppfImag_fx[iBlockOffset][iFBOffset] );
1344 0 : tmp = W_shr( tmp, sub( fGain_exp, 8 ) ); // Q to (input_q -9)
1345 0 : ppfImag_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp );
1346 0 : move32();
1347 0 : iFBOffset++;
1348 : }
1349 : }
1350 0 : iBlockOffset++;
1351 : }
1352 : }
1353 :
1354 0 : return;
1355 : }
1356 0 : static void QuantizeSpectrumDPCM_Opt(
1357 : const Word32 iNumGroups,
1358 : const Word32 *piGroupLengths,
1359 : const Word32 iNumBands,
1360 : const Word32 *piBandwidths,
1361 : Word32 **ppiAlloc,
1362 : Word32 **ppfReal_fx,
1363 : Word32 **ppfImag_fx,
1364 : Word16 q_final,
1365 : Word32 **ppiQReal,
1366 : Word32 **ppiQImag,
1367 : Word32 **ppiSignReal,
1368 : Word32 **ppiSignImag,
1369 : Word32 iNumSubSets,
1370 : Word32 iSubSetId,
1371 : Word32 *piPredEnable,
1372 : Word32 *pfA1Real_fx,
1373 : Word32 *pfA1Imag_fx,
1374 : Word32 *pfPredStateReal_fx,
1375 : Word32 *pfPredStateImag_fx )
1376 : {
1377 : Word32 b, n;
1378 : Word32 iFBOffset;
1379 : Word32 k, iAlloc;
1380 : Word32 iMaxQuantVal_fx;
1381 : Word32 fSCFGain_fx, fInvSCFGain_fx;
1382 0 : iFBOffset = 0;
1383 : Word32 ppiQReal_fx, ppiQImag_fx;
1384 0 : FOR( b = 0; b < iNumBands; b++ )
1385 : {
1386 : Word32 m;
1387 0 : FOR( m = 0; m < piBandwidths[b]; m++ )
1388 : {
1389 0 : Word32 iBlockOffset = 0;
1390 0 : IF( EQ_32( piPredEnable[iFBOffset], 1 ) )
1391 : {
1392 : Word32 fReal_fx;
1393 : Word32 fImag_fx;
1394 0 : Word32 iSubset = iFBOffset % iNumSubSets;
1395 0 : Word32 fPrevReal_fx = 0;
1396 0 : Word32 fPrevImag_fx = 0;
1397 0 : IF( NE_32( iSubset, iSubSetId ) )
1398 : {
1399 : /* run predictors across sub-frames */
1400 0 : fPrevReal_fx = pfPredStateReal_fx[iFBOffset];
1401 0 : move32();
1402 0 : fPrevImag_fx = pfPredStateImag_fx[iFBOffset];
1403 0 : move32();
1404 : }
1405 0 : FOR( n = 0; n < iNumGroups; n++ )
1406 : {
1407 0 : iAlloc = ppiAlloc[n][b];
1408 0 : iMaxQuantVal_fx = c_aiQuantMaxValues_fx[iAlloc];
1409 0 : fSCFGain_fx = c_afScaleFactor_fx[iAlloc];
1410 0 : fInvSCFGain_fx = c_afInvScaleFactor_fx[iAlloc];
1411 0 : FOR( k = 0; k < piGroupLengths[n]; k++ )
1412 : {
1413 : /* prediction */
1414 0 : fReal_fx = L_sub( Mpy_32_32( pfA1Real_fx[iFBOffset], fPrevReal_fx ), Mpy_32_32( pfA1Imag_fx[iFBOffset], fPrevImag_fx ) );
1415 0 : fImag_fx = L_add( Mpy_32_32( pfA1Real_fx[iFBOffset], fPrevImag_fx ), Mpy_32_32( pfA1Imag_fx[iFBOffset], fPrevReal_fx ) );
1416 0 : ppiQReal_fx = Quantize_fx( L_add_sat( L_shr_r_sat( ppfReal_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ), fReal_fx ), /* quantize residual */
1417 : fSCFGain_fx,
1418 0 : &ppiSignReal[iBlockOffset][iFBOffset],
1419 : iMaxQuantVal_fx );
1420 0 : ppiQImag_fx = Quantize_fx( L_add_sat( L_shr_r_sat( ppfImag_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ), fImag_fx ),
1421 : fSCFGain_fx,
1422 0 : &ppiSignImag[iBlockOffset][iFBOffset],
1423 : iMaxQuantVal_fx );
1424 0 : ppiQReal[iBlockOffset][iFBOffset] = L_shr( ppiQReal_fx, 21 );
1425 :
1426 0 : ppiQImag[iBlockOffset][iFBOffset] = L_shr( ppiQImag_fx, 21 );
1427 :
1428 0 : ppiQReal_fx = L_shl( ppiQReal[iBlockOffset][iFBOffset], 21 );
1429 0 : fPrevReal_fx = L_sub( L_shl( UnQuantize_fx( ppiQReal_fx,
1430 : fInvSCFGain_fx,
1431 0 : ppiSignReal[iBlockOffset][iFBOffset] ),
1432 : 9 ),
1433 : fReal_fx );
1434 : /* add prediction to quantized residual = reconstructed sample */
1435 :
1436 0 : ppiQImag_fx = L_shl( ppiQImag[iBlockOffset][iFBOffset], 21 );
1437 0 : fPrevImag_fx = L_sub( L_shl( UnQuantize_fx( ppiQImag_fx,
1438 : fInvSCFGain_fx,
1439 0 : ppiSignImag[iBlockOffset][iFBOffset] ),
1440 : 9 ),
1441 : fImag_fx );
1442 0 : iBlockOffset++;
1443 : } /* group length */
1444 : } /* groups */
1445 0 : pfPredStateReal_fx[iFBOffset] = fPrevReal_fx;
1446 0 : move32();
1447 0 : pfPredStateImag_fx[iFBOffset] = fPrevImag_fx;
1448 0 : move32();
1449 : } /* predEnable */
1450 : ELSE
1451 : { /* no prediction */
1452 0 : FOR( n = 0; n < iNumGroups; n++ )
1453 : {
1454 0 : iAlloc = ppiAlloc[n][b];
1455 0 : move32();
1456 0 : iMaxQuantVal_fx = c_aiQuantMaxValues_fx[iAlloc];
1457 0 : move32();
1458 0 : fSCFGain_fx = c_afScaleFactor_fx[iAlloc];
1459 0 : move32();
1460 0 : fInvSCFGain_fx = c_afInvScaleFactor_fx[iAlloc];
1461 0 : move32();
1462 0 : FOR( k = 0; k < piGroupLengths[n]; k++ )
1463 : {
1464 0 : ppiQReal_fx = Quantize_fx( L_shr_r_sat( ppfReal_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ),
1465 : fSCFGain_fx,
1466 0 : &ppiSignReal[iBlockOffset][iFBOffset],
1467 : iMaxQuantVal_fx );
1468 0 : ppiQImag_fx = Quantize_fx( L_shr_r_sat( ppfImag_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ),
1469 : fSCFGain_fx,
1470 0 : &ppiSignImag[iBlockOffset][iFBOffset],
1471 : iMaxQuantVal_fx );
1472 :
1473 0 : ppiQReal[iBlockOffset][iFBOffset] = L_shr( ppiQReal_fx, 21 );
1474 :
1475 0 : ppiQImag[iBlockOffset][iFBOffset] = L_shr( ppiQImag_fx, 21 );
1476 :
1477 0 : iBlockOffset++;
1478 : } /* group length */
1479 : } /* groups */
1480 : } /* predEnable */
1481 0 : iFBOffset++;
1482 : } /* bandwidth */
1483 : }
1484 0 : }
1485 0 : static Word32 CountLCLDBits(
1486 : const Word32 iNumGroups,
1487 : const Word32 *piGroupLengths,
1488 : const Word32 iNumBands,
1489 : const Word32 *piBandwidths,
1490 : const Word32 *piPredEnable,
1491 : Word32 **ppiAlloc,
1492 : Word32 **ppiQReal,
1493 : Word32 **ppiQImag )
1494 : {
1495 : Word32 k, n, b, iFBOffset;
1496 : Word32 iBits, iBlockOffest;
1497 : Word32 m, iAlloc, iHuffDim, iHuffMod;
1498 :
1499 0 : iBits = 0;
1500 0 : move32();
1501 0 : iBlockOffest = 0;
1502 0 : move32();
1503 0 : FOR( n = 0; n < iNumGroups; n++ )
1504 : {
1505 0 : FOR( k = 0; k < piGroupLengths[n]; k++ )
1506 : {
1507 0 : iFBOffset = 0;
1508 0 : move32();
1509 0 : FOR( b = 0; b < iNumBands; b++ )
1510 : {
1511 0 : iAlloc = ppiAlloc[n][b];
1512 0 : move32();
1513 :
1514 0 : iHuffDim = c_aiHuffmanDim[iAlloc];
1515 0 : move32();
1516 0 : iHuffMod = c_aiHuffmanMod[iAlloc];
1517 0 : move32();
1518 :
1519 0 : IF( GT_32( iAlloc, 0 ) )
1520 : {
1521 0 : const UWord16( *pauiHuffmanTable )[2] = NULL;
1522 0 : const UWord16( *pauiHuffmanTableDPCM )[2] = NULL;
1523 0 : pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc];
1524 0 : pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc];
1525 0 : FOR( m = 0; m < piBandwidths[b]; m++ )
1526 : {
1527 : Word32 iQuantValue1;
1528 : Word32 iQuantValue2;
1529 :
1530 0 : iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset];
1531 0 : move32();
1532 0 : iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset];
1533 0 : move32();
1534 :
1535 0 : iBits = L_add( iBits, GT_32( iQuantValue1, 0 ) ? 1 : 0 ); /* Sign bit for vals > 0 */
1536 0 : iBits = L_add( iBits, GT_32( iQuantValue2, 0 ) ? 1 : 0 ); /* Sign bit for vals > 0 */
1537 :
1538 0 : IF( EQ_32( piPredEnable[iFBOffset], 1 ) )
1539 : {
1540 0 : IF( EQ_32( iHuffDim, 2 ) )
1541 : {
1542 0 : iQuantValue1 *= iHuffMod;
1543 0 : iQuantValue1 = L_add( iQuantValue1, iQuantValue2 );
1544 0 : iBits = L_add( iBits, pauiHuffmanTableDPCM[iQuantValue1][0] );
1545 : }
1546 : ELSE
1547 : {
1548 0 : iBits = L_add( iBits, pauiHuffmanTableDPCM[iQuantValue1][0] );
1549 0 : iBits = L_add( iBits, pauiHuffmanTableDPCM[iQuantValue2][0] );
1550 : }
1551 : }
1552 : ELSE
1553 : {
1554 0 : IF( EQ_32( iHuffDim, 2 ) )
1555 : {
1556 0 : iQuantValue1 *= iHuffMod;
1557 0 : iQuantValue1 = L_add( iQuantValue1, iQuantValue2 );
1558 0 : iBits = L_add( iBits, pauiHuffmanTable[iQuantValue1][0] );
1559 : }
1560 : ELSE
1561 : {
1562 0 : iBits = L_add( iBits, pauiHuffmanTable[iQuantValue1][0] );
1563 0 : iBits = L_add( iBits, pauiHuffmanTable[iQuantValue2][0] );
1564 : }
1565 : }
1566 :
1567 0 : iFBOffset++;
1568 : }
1569 : }
1570 : ELSE
1571 : {
1572 0 : iFBOffset = L_add( iFBOffset, piBandwidths[b] );
1573 : }
1574 : }
1575 :
1576 0 : iBlockOffest++;
1577 : }
1578 : }
1579 :
1580 0 : return iBits;
1581 : }
1582 :
1583 :
1584 : /* Currently only the number of bands in frame */
1585 0 : static Word32 WriteHeaderInformation(
1586 : const Word32 iNumBands,
1587 : ISAR_SPLIT_REND_BITS_HANDLE pBits )
1588 : {
1589 : Word32 iBitsWritten;
1590 :
1591 0 : iBitsWritten = 0;
1592 0 : move32();
1593 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumBands, 5 );
1594 0 : iBitsWritten = L_add( iBitsWritten, 5 );
1595 :
1596 0 : return iBitsWritten;
1597 : }
1598 :
1599 :
1600 0 : static Word32 WriteMSInformation(
1601 : const Word32 iNumBands,
1602 : const Word32 iMSMode,
1603 : const Word32 *piMSFlags,
1604 : const Word32 *piLRPhaseDiff,
1605 : const Word32 *piMSPredCoef,
1606 : Word32 iNumMSPredBands,
1607 : ISAR_SPLIT_REND_BITS_HANDLE pBits )
1608 : {
1609 : Word32 iBitsWritten;
1610 0 : Word32 iMSPredAll = (Word32) EQ_32( iNumMSPredBands, iNumBands );
1611 0 : move32();
1612 : #ifdef DEBUG_WRITE_MS_PRED
1613 : Word32 iBitsWrittenTmp = 0;
1614 : move32();
1615 : #endif
1616 0 : iBitsWritten = 0;
1617 0 : move32();
1618 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSMode, 2 );
1619 0 : iBitsWritten = L_add( iBitsWritten, 2 );
1620 :
1621 0 : IF( EQ_32( iMSMode, 3 ) )
1622 : {
1623 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSPredAll, 1 );
1624 0 : iBitsWritten = L_add( iBitsWritten, 1 );
1625 : }
1626 :
1627 0 : test();
1628 0 : test();
1629 0 : IF( EQ_32( iMSMode, 2 ) || ( EQ_32( iMSMode, 3 ) && !iMSPredAll ) )
1630 : {
1631 : Word32 n;
1632 0 : FOR( n = 0; n < iNumBands; n++ )
1633 : {
1634 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, piMSFlags[n], 1 );
1635 0 : iBitsWritten = L_add( iBitsWritten, 1 );
1636 : }
1637 : }
1638 :
1639 : #ifdef DEBUG_WRITE_MS_PRED
1640 : iBitsWrittenTmp = iBitsWritten;
1641 : #endif
1642 0 : IF( EQ_32( iMSMode, 3 ) )
1643 : {
1644 : Word32 b;
1645 : Word32 anyNonZero;
1646 0 : anyNonZero = 0;
1647 0 : move32();
1648 0 : FOR( b = 0; b < iNumMSPredBands; b++ )
1649 : {
1650 0 : IF( NE_32( piLRPhaseDiff[b], 0 ) )
1651 : {
1652 0 : anyNonZero = 1;
1653 0 : move32();
1654 0 : BREAK;
1655 : }
1656 : }
1657 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 );
1658 0 : iBitsWritten++;
1659 :
1660 0 : IF( anyNonZero )
1661 : {
1662 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( piLRPhaseDiff[0], PHASE_MIN_VAL ), PHASE_BAND0_BITS );
1663 0 : iBitsWritten = L_add( iBitsWritten, PHASE_BAND0_BITS );
1664 0 : FOR( b = 1; b < iNumMSPredBands; b++ )
1665 : {
1666 0 : Word32 tabIdx = L_sub( piLRPhaseDiff[b], ENV_DELTA_MIN );
1667 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] );
1668 0 : iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] );
1669 : }
1670 : }
1671 :
1672 0 : anyNonZero = 0;
1673 0 : move32();
1674 0 : FOR( b = 0; b < iNumMSPredBands; b++ )
1675 : {
1676 0 : IF( NE_32( piMSPredCoef[b], 0 ) )
1677 : {
1678 0 : anyNonZero = 1;
1679 0 : move32();
1680 0 : BREAK;
1681 : }
1682 : }
1683 :
1684 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 );
1685 0 : iBitsWritten++;
1686 :
1687 0 : IF( anyNonZero )
1688 : {
1689 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( piMSPredCoef[0], PRED_MIN_VAL ), PRED_BAND0_BITS );
1690 0 : iBitsWritten = L_add( iBitsWritten, PRED_BAND0_BITS );
1691 0 : FOR( b = 1; b < iNumMSPredBands; b++ )
1692 : {
1693 0 : Word32 tabIdx = L_sub( piMSPredCoef[b], ENV_DELTA_MIN );
1694 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] );
1695 0 : iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] );
1696 : }
1697 : }
1698 : }
1699 : #ifdef DEBUG_WRITE_MS_PRED
1700 : {
1701 : static FILE *fid = 0;
1702 : IF( !fid )
1703 : {
1704 : fid = fopen( "ms_pred_bitrate.txt", "wt" );
1705 : }
1706 : fprintf( fid, "%f\n", (float) ( ( iBitsWritten - iBitsWrittenTmp ) * ( iMSMode == 3 ) * 50 ) / 1000.0f ); /*kb/s*/
1707 : }
1708 : #endif
1709 :
1710 0 : return iBitsWritten;
1711 : }
1712 :
1713 :
1714 0 : static Word32 WriteGroupInformation(
1715 : const Word32 iChannels,
1716 : const Word32 iCommonGrouping,
1717 : const Word32 *piNumGroups,
1718 : Word32 **ppiGroupLengths,
1719 : ISAR_SPLIT_REND_BITS_HANDLE pBits )
1720 : {
1721 : Word32 c, k, n, iBitsWritten;
1722 :
1723 0 : iBitsWritten = 0;
1724 0 : move32();
1725 0 : test();
1726 0 : IF( EQ_32( iChannels, 2 ) && EQ_32( iCommonGrouping, 1 ) )
1727 : {
1728 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 );
1729 0 : iBitsWritten = L_add( iBitsWritten, 1 );
1730 :
1731 0 : FOR( n = 0; n < piNumGroups[0]; n++ )
1732 : {
1733 0 : FOR( k = 1; k < ppiGroupLengths[0][n]; k++ )
1734 : {
1735 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
1736 0 : iBitsWritten = L_add( iBitsWritten, 1 );
1737 : }
1738 0 : IF( LT_32( n, L_sub( piNumGroups[0], 1 ) ) )
1739 : {
1740 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
1741 0 : iBitsWritten = L_add( iBitsWritten, 1 );
1742 : }
1743 : }
1744 : }
1745 0 : ELSE IF( EQ_32( iChannels, 2 ) )
1746 : {
1747 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 );
1748 0 : iBitsWritten = L_add( iBitsWritten, 1 );
1749 :
1750 0 : FOR( c = 0; c < iChannels; c++ )
1751 : {
1752 0 : FOR( n = 0; n < piNumGroups[c]; n++ )
1753 : {
1754 0 : FOR( k = 1; k < ppiGroupLengths[c][n]; k++ )
1755 : {
1756 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
1757 0 : iBitsWritten = L_add( iBitsWritten, 1 );
1758 : }
1759 0 : IF( LT_32( n, L_sub( piNumGroups[c], 1 ) ) )
1760 : {
1761 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
1762 0 : iBitsWritten = L_add( iBitsWritten, 1 );
1763 : }
1764 : }
1765 : }
1766 : }
1767 : ELSE
1768 : {
1769 0 : FOR( c = 0; c < iChannels; c++ )
1770 : {
1771 0 : FOR( n = 0; n < piNumGroups[c]; n++ )
1772 : {
1773 0 : FOR( k = 1; k < ppiGroupLengths[c][n]; k++ )
1774 : {
1775 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
1776 0 : iBitsWritten = L_add( iBitsWritten, 1 );
1777 : }
1778 :
1779 0 : IF( LT_32( n, L_sub( piNumGroups[c], 1 ) ) )
1780 : {
1781 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
1782 0 : iBitsWritten = L_add( iBitsWritten, 1 );
1783 : }
1784 : }
1785 : }
1786 : }
1787 :
1788 0 : return iBitsWritten;
1789 : }
1790 :
1791 :
1792 0 : static Word32 WriteRMSEnvelope(
1793 : const Word32 iChannels,
1794 : const Word32 *piNumGroups,
1795 : const Word32 iNumBands,
1796 : Word32 ***pppiRMSEnvelope,
1797 : ISAR_SPLIT_REND_BITS_HANDLE pBits )
1798 : {
1799 : Word32 k, n;
1800 : Word32 iBitsWritten;
1801 :
1802 0 : iBitsWritten = 0;
1803 0 : move32();
1804 0 : FOR( n = 0; n < iChannels; n++ )
1805 : {
1806 0 : FOR( k = 0; k < piNumGroups[n]; k++ )
1807 : {
1808 : Word32 b;
1809 : Word32 iLastRMSVal;
1810 :
1811 0 : iLastRMSVal = pppiRMSEnvelope[n][k][0];
1812 0 : move32();
1813 0 : iLastRMSVal = GT_32( iLastRMSVal, ENV_MIN ) ? iLastRMSVal : ENV_MIN;
1814 0 : move32();
1815 0 : iLastRMSVal = LT_32( iLastRMSVal, ENV_MAX ) ? iLastRMSVal : ENV_MAX;
1816 0 : move32();
1817 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( iLastRMSVal, ENV_MIN ), ENV0_BITS );
1818 0 : iBitsWritten = L_add( iBitsWritten, ENV0_BITS );
1819 :
1820 0 : FOR( b = 1; b < iNumBands; b++ )
1821 : {
1822 : Word32 iDelta;
1823 :
1824 0 : iDelta = L_sub( pppiRMSEnvelope[n][k][b], iLastRMSVal );
1825 0 : iDelta = GT_32( iDelta, ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN;
1826 0 : move32();
1827 0 : iDelta = LT_32( iDelta, ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX;
1828 0 : move32();
1829 0 : iDelta = L_sub( iDelta, ENV_DELTA_MIN );
1830 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[iDelta][1], c_aaiRMSEnvHuffEnc[iDelta][0] );
1831 0 : iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[iDelta][0] );
1832 :
1833 0 : iLastRMSVal = pppiRMSEnvelope[n][k][b];
1834 0 : move32();
1835 : }
1836 : }
1837 : }
1838 :
1839 0 : return iBitsWritten;
1840 : }
1841 :
1842 :
1843 0 : static Word32 WriteAllocInformation(
1844 : const Word32 iAllocOffset,
1845 : ISAR_SPLIT_REND_BITS_HANDLE pBits )
1846 : {
1847 : Word32 iBitsWritten;
1848 :
1849 0 : iBitsWritten = 0;
1850 0 : move32();
1851 :
1852 0 : IF( LT_32( iAllocOffset, MIN_ALLOC_OFFSET ) || GT_32( iAllocOffset, MAX_ALLOC_OFFSET ) )
1853 : {
1854 0 : printf( "Serious error\n" );
1855 : }
1856 :
1857 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( iAllocOffset, MIN_ALLOC_OFFSET ), ALLOC_OFFSET_BITS );
1858 0 : iBitsWritten = L_add( iBitsWritten, ALLOC_OFFSET_BITS );
1859 :
1860 0 : return iBitsWritten;
1861 : }
1862 :
1863 :
1864 0 : static Word32 WriteLCLDData(
1865 : const Word32 *piNumGroups,
1866 : Word32 **ppiGroupLengths,
1867 : const Word32 iNumBands,
1868 : const Word32 iNumChannels,
1869 : Word32 **ppiPredEnable,
1870 : const Word32 iNumSubSets,
1871 : const Word32 iSubSetId,
1872 : Word32 ***pppiAlloc,
1873 : Word32 ***pppiSignReal,
1874 : Word32 ***pppiSignImag,
1875 : Word32 ***pppiQReal,
1876 : Word32 ***pppiQImag,
1877 : ISAR_SPLIT_REND_BITS_HANDLE pBits )
1878 : {
1879 : Word32 iBitsWritten;
1880 0 : Word32 iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1];
1881 : Word32 s;
1882 0 : Word32 iSet = iSubSetId;
1883 :
1884 0 : iBitsWritten = 0;
1885 0 : move32();
1886 0 : FOR( s = 0; s < iNumSubSets; ( s++, iSet-- ) )
1887 : {
1888 : Word32 ch;
1889 0 : IF( LT_32( iSet, 0 ) )
1890 : {
1891 0 : iSet = L_sub( iNumSubSets, 1 );
1892 : }
1893 :
1894 0 : FOR( ch = 0; ch < iNumChannels; ch++ )
1895 : {
1896 0 : Word32 iBlockOffest = 0;
1897 0 : move32();
1898 : Word32 n;
1899 0 : FOR( n = 0; n < piNumGroups[ch]; n++ )
1900 : {
1901 : Word32 k;
1902 0 : FOR( k = 0; k < ppiGroupLengths[ch][n]; k++ )
1903 : {
1904 : Word32 iFBOffset;
1905 0 : FOR( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets )
1906 : {
1907 : Word32 b;
1908 : Word32 iAlloc;
1909 : Word32 iHuffDim;
1910 : Word32 iHuffMod;
1911 :
1912 0 : b = c_aiBandIdPerLcldBand[iFBOffset];
1913 0 : move32();
1914 :
1915 0 : iAlloc = pppiAlloc[ch][n][b];
1916 0 : move32();
1917 :
1918 0 : iHuffDim = c_aiHuffmanDim[iAlloc];
1919 0 : move32();
1920 0 : iHuffMod = c_aiHuffmanMod[iAlloc];
1921 0 : move32();
1922 :
1923 0 : IF( GT_32( iAlloc, 0 ) )
1924 : {
1925 0 : const UWord16( *pauiHuffmanTable )[2] = NULL;
1926 0 : const UWord16( *pauiHuffmanTableDPCM )[2] = NULL;
1927 : Word32 iQuantValue1;
1928 : Word32 iQuantValue2;
1929 0 : pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc];
1930 0 : pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc];
1931 :
1932 0 : iQuantValue1 = pppiQReal[ch][iBlockOffest][iFBOffset];
1933 0 : move32();
1934 0 : iQuantValue2 = pppiQImag[ch][iBlockOffest][iFBOffset];
1935 0 : move32();
1936 : #ifdef LCLD_HANDLE_PRED_START_SAMPLE
1937 : IF( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) )
1938 : #else
1939 0 : IF( EQ_32( ppiPredEnable[ch][iFBOffset], 1 ) )
1940 : #endif
1941 : {
1942 0 : IF( EQ_32( iHuffDim, 2 ) )
1943 : {
1944 : Word32 iSymbol;
1945 0 : iSymbol = iQuantValue1;
1946 0 : move32();
1947 0 : iSymbol *= iHuffMod;
1948 0 : iSymbol = L_add( iSymbol, iQuantValue2 );
1949 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iSymbol][1], pauiHuffmanTableDPCM[iSymbol][0] );
1950 0 : iBitsWritten = L_add( iBitsWritten, pauiHuffmanTableDPCM[iSymbol][0] );
1951 : }
1952 : ELSE
1953 : {
1954 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue1][1], pauiHuffmanTableDPCM[iQuantValue1][0] );
1955 0 : iBitsWritten = L_add( iBitsWritten, pauiHuffmanTableDPCM[iQuantValue1][0] );
1956 :
1957 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue2][1], pauiHuffmanTableDPCM[iQuantValue2][0] );
1958 0 : iBitsWritten = L_add( iBitsWritten, pauiHuffmanTableDPCM[iQuantValue2][0] );
1959 : }
1960 : }
1961 : ELSE
1962 : {
1963 0 : IF( EQ_32( iHuffDim, 2 ) )
1964 : {
1965 : Word32 iSymbol;
1966 0 : iSymbol = iQuantValue1;
1967 0 : move32();
1968 0 : iSymbol *= iHuffMod;
1969 0 : iSymbol = L_add( iSymbol, iQuantValue2 );
1970 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iSymbol][1], pauiHuffmanTable[iSymbol][0] );
1971 0 : iBitsWritten = L_add( iBitsWritten, pauiHuffmanTable[iSymbol][0] );
1972 : }
1973 : ELSE
1974 : {
1975 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue1][1], pauiHuffmanTable[iQuantValue1][0] );
1976 0 : iBitsWritten = L_add( iBitsWritten, pauiHuffmanTable[iQuantValue1][0] );
1977 :
1978 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue2][1], pauiHuffmanTable[iQuantValue2][0] );
1979 0 : iBitsWritten = L_add( iBitsWritten, pauiHuffmanTable[iQuantValue2][0] );
1980 : }
1981 : }
1982 :
1983 0 : IF( GT_32( iQuantValue1, 0 ) )
1984 : {
1985 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignReal[ch][iBlockOffest][iFBOffset], 1 );
1986 0 : iBitsWritten = L_add( iBitsWritten, 1 );
1987 : }
1988 0 : IF( GT_32( iQuantValue2, 0 ) )
1989 : {
1990 0 : ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignImag[ch][iBlockOffest][iFBOffset], 1 );
1991 0 : iBitsWritten = L_add( iBitsWritten, 1 );
1992 : }
1993 : }
1994 : }
1995 0 : iBlockOffest++;
1996 : }
1997 : }
1998 : }
1999 : }
2000 :
2001 0 : return iBitsWritten;
2002 : }
2003 0 : static Word32 ComputeAllocation(
2004 : const Word32 iChannels,
2005 : const Word32 *piNumGroups,
2006 : Word32 **ppiGroupLengths,
2007 : const Word32 iNumBands,
2008 : const Word32 *piBandwidths,
2009 : Word32 ***pppfReal_fx,
2010 : Word32 ***pppfImag_fx,
2011 : Word16 q_final,
2012 : Word32 ***pppiSMR,
2013 : const Word32 iAvailableBits,
2014 : Word32 *piAllocOffset,
2015 : Word32 ***pppiAlloc,
2016 : Word32 ***pppiQReal,
2017 : Word32 ***pppiQImag,
2018 : Word32 ***pppiSignReal,
2019 : Word32 ***pppiSignImag,
2020 : PredictionEncoder *psPredictionEncoder )
2021 : {
2022 : Word32 iBitsUsed, iDone, iDelta;
2023 : Word32 b, k, n;
2024 : Word32 iLimitAllocOffset;
2025 :
2026 0 : iBitsUsed = ALLOC_OFFSET_BITS; /* Bits used for Alloc Offset */
2027 0 : move32();
2028 0 : iDone = 0;
2029 0 : move32();
2030 0 : iDelta = -MIN_ALLOC_OFFSET;
2031 0 : move32();
2032 0 : *piAllocOffset = 0;
2033 0 : move32();
2034 0 : WHILE( EQ_32( iDone, 0 ) )
2035 : {
2036 0 : iBitsUsed = ALLOC_OFFSET_BITS;
2037 0 : move32();
2038 0 : iLimitAllocOffset = *piAllocOffset;
2039 0 : move32();
2040 0 : iLimitAllocOffset = GT_32( iLimitAllocOffset, MIN_ALLOC_OFFSET ) ? iLimitAllocOffset : MIN_ALLOC_OFFSET;
2041 0 : iLimitAllocOffset = LT_32( iLimitAllocOffset, MAX_ALLOC_OFFSET ) ? iLimitAllocOffset : MAX_ALLOC_OFFSET;
2042 :
2043 0 : FOR( n = 0; n < iChannels; n++ )
2044 : {
2045 0 : FOR( k = 0; k < piNumGroups[n]; k++ )
2046 : {
2047 0 : FOR( b = 0; b < iNumBands; b++ )
2048 : {
2049 : Word32 iAlloc;
2050 0 : iAlloc = ( L_shr( L_add( pppiSMR[n][k][b], L_mult0( extract_l( iLimitAllocOffset ), ALLOC_OFFSET_SCALE ) ), 5 ) );
2051 0 : iAlloc = GT_32( iAlloc, MIN_ALLOC ) ? iAlloc : MIN_ALLOC;
2052 0 : iAlloc = LT_32( iAlloc, MAX_ALLOC ) ? iAlloc : MAX_ALLOC;
2053 0 : pppiAlloc[n][k][b] = iAlloc;
2054 0 : move32();
2055 : }
2056 : }
2057 0 : IF( psPredictionEncoder->iNumSubSets > 1 )
2058 : {
2059 0 : mvl2l( psPredictionEncoder->ppfPredStateReal_fx[n], psPredictionEncoder->ppfPredStateRealTmp_fx[n], LCLD_BANDS );
2060 0 : mvl2l( psPredictionEncoder->ppfPredStateImag_fx[n], psPredictionEncoder->ppfPredStateImagTmp_fx[n], LCLD_BANDS );
2061 : }
2062 :
2063 0 : QuantizeSpectrumDPCM_Opt( piNumGroups[n],
2064 0 : (const Word32 *) ppiGroupLengths[n],
2065 : iNumBands,
2066 : piBandwidths,
2067 0 : pppiAlloc[n],
2068 0 : pppfReal_fx[n],
2069 0 : pppfImag_fx[n],
2070 : q_final,
2071 0 : pppiQReal[n],
2072 0 : pppiQImag[n],
2073 0 : pppiSignReal[n],
2074 0 : pppiSignImag[n],
2075 : psPredictionEncoder->iNumSubSets,
2076 : psPredictionEncoder->iSubSetId,
2077 0 : psPredictionEncoder->ppiPredBandEnable[n],
2078 0 : psPredictionEncoder->ppfA1Real_fx[n],
2079 0 : psPredictionEncoder->ppfA1Imag_fx[n],
2080 0 : psPredictionEncoder->ppfPredStateRealTmp_fx[n],
2081 0 : psPredictionEncoder->ppfPredStateImagTmp_fx[n] );
2082 0 : iBitsUsed = L_add( iBitsUsed, CountLCLDBits( piNumGroups[n],
2083 0 : (const Word32 *) ppiGroupLengths[n],
2084 : iNumBands,
2085 : piBandwidths,
2086 0 : (const Word32 *) psPredictionEncoder->ppiPredBandEnable[n],
2087 0 : pppiAlloc[n],
2088 0 : pppiQReal[n],
2089 0 : pppiQImag[n] ) );
2090 : }
2091 :
2092 0 : IF( LE_32( *piAllocOffset, MIN_ALLOC_OFFSET ) && GT_32( iBitsUsed, iAvailableBits ) )
2093 : {
2094 : #ifdef DEBUG_VERBOSE
2095 : printf( "Frame can not be coded with the number of bits available\n" );
2096 : #endif
2097 : // iLastError = ENC_ERROR_STREAM_FAILURE;
2098 0 : return -1;
2099 : }
2100 0 : ELSE IF( GE_32( *piAllocOffset, MAX_ALLOC_OFFSET ) && LT_32( iBitsUsed, iAvailableBits ) )
2101 : {
2102 0 : *piAllocOffset = MAX_ALLOC_OFFSET;
2103 0 : iDone++;
2104 : }
2105 : ELSE
2106 : {
2107 0 : IF( EQ_32( iDelta, 0 ) && GT_32( iBitsUsed, iAvailableBits ) )
2108 : {
2109 0 : iDelta = 1;
2110 : }
2111 0 : ELSE IF( EQ_32( iDelta, 0 ) && LT_32( iBitsUsed, iAvailableBits ) )
2112 : {
2113 0 : iDone++;
2114 : }
2115 0 : ELSE IF( EQ_32( iBitsUsed, iAvailableBits ) )
2116 : {
2117 0 : iDone++;
2118 : }
2119 :
2120 0 : IF( GT_32( iBitsUsed, iAvailableBits ) )
2121 : {
2122 0 : *piAllocOffset -= iDelta;
2123 0 : iDelta = L_shr( iDelta, 1 );
2124 : }
2125 0 : ELSE IF( LT_32( iBitsUsed, iAvailableBits ) )
2126 : {
2127 0 : *piAllocOffset += iDelta;
2128 0 : iDelta = L_shr( iDelta, 1 );
2129 : }
2130 : }
2131 : }
2132 0 : IF( GT_32( psPredictionEncoder->iNumSubSets, 1 ) )
2133 : {
2134 0 : FOR( n = 0; n < iChannels; n++ )
2135 : {
2136 0 : mvl2l( psPredictionEncoder->ppfPredStateRealTmp_fx[n], psPredictionEncoder->ppfPredStateReal_fx[n], LCLD_BANDS );
2137 0 : mvl2l( psPredictionEncoder->ppfPredStateImagTmp_fx[n], psPredictionEncoder->ppfPredStateImag_fx[n], LCLD_BANDS );
2138 : }
2139 : }
2140 0 : return iBitsUsed;
2141 : }
|