LCOV - code coverage report
Current view: top level - lib_isar - isar_lcld_encoder.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 0 885 0.0 %
Date: 2025-08-23 01:22:27 Functions: 0 18 0.0 %

          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             : }

Generated by: LCOV version 1.14