LCOV - code coverage report
Current view: top level - lib_enc - ivas_mct_enc_mct.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 6baab0c613aa6c7100498ed7b93676aa8198a493 Lines: 268 269 99.6 %
Date: 2025-05-28 04:28:20 Functions: 11 11 100.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 "ivas_cnst.h"
      37             : #include "ivas_prot.h"
      38             : #include "prot.h"
      39             : #include "wmc_auto.h"
      40             : #include <assert.h>
      41             : 
      42             : 
      43             : /*--------------------------------------------------------------*
      44             :  * Local constants
      45             :  *---------------------------------------------------------------*/
      46             : 
      47             : #define SPAR_CORR_THRES    0.9f
      48             : #define DEFAULT_CORR_THRES 0.3f
      49             : 
      50             : /*-------------------------------------------------------------------------
      51             :  * getChannelEnergies()
      52             :  *
      53             :  * Calculate energy for each cahnnel
      54             :  *-------------------------------------------------------------------------*/
      55             : 
      56     2919672 : void getChannelEnergies(
      57             :     Encoder_State **sts,         /* i/o: Encoder state structure               */
      58             :     float nrg[MCT_MAX_CHANNELS], /* o  : buffer with energies for each channel */
      59             :     const int16_t nchan          /* i  : number of channels                    */
      60             : )
      61             : {
      62             :     int16_t ch, n;
      63             :     int16_t nSubframes, L_subframe;
      64             :     Encoder_State *st;
      65             : 
      66             :     /* Calculate energies per channel */
      67    17506228 :     for ( ch = 0; ch < nchan; ch++ )
      68             :     {
      69    14586556 :         st = sts[ch];
      70    14586556 :         if ( st->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
      71             :         {
      72    14285448 :             nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
      73    14285448 :             L_subframe = st->hTcxEnc->L_frameTCX / nSubframes;
      74             : 
      75    14285448 :             nrg[ch] = 0;
      76    28888802 :             for ( n = 0; n < nSubframes; n++ )
      77             :             {
      78    14603354 :                 nrg[ch] += sum2_f( st->hTcxEnc->spectrum[n], L_subframe );
      79             :             }
      80    14285448 :             nrg[ch] = sqrtf( nrg[ch] );
      81             :         }
      82             :     }
      83             : 
      84     2919672 :     return;
      85             : }
      86             : 
      87             : 
      88             : /*-------------------------------------------------------------------------
      89             :  * getNextBestCorrelation()
      90             :  *
      91             :  * find channel pair with highest cross-correlation
      92             :  *-------------------------------------------------------------------------*/
      93             : 
      94     1393652 : static void getNextBestCorrelation(
      95             :     float xCorrMatrix[][MCT_MAX_CHANNELS], /* i  : cross-correlation matrix                                    */
      96             :     int16_t *_ch1,                         /* o  : first channel of selected channel-pair                      */
      97             :     int16_t *_ch2,                         /* o  : second channel of selected channel-pair                     */
      98             :     float *max_corr,                       /* o  : normalized cross correlation value of selected channel pair */
      99             :     const int16_t sortInd,
     100             :     const int16_t nChannels )
     101             : {
     102             :     float tmp_corrVals[( MCT_MAX_CHANNELS * ( MCT_MAX_CHANNELS - 1 ) ) / 2];
     103             :     int16_t i;
     104             :     int16_t ch1, ch2;
     105             : 
     106     1393652 :     set_f( tmp_corrVals, 0, ( MCT_MAX_CHANNELS * ( MCT_MAX_CHANNELS - 1 ) ) / 2 );
     107             : 
     108             :     /* first sort correlation matrix */
     109     1393652 :     i = 0;
     110     8428715 :     for ( ch1 = 0; ch1 < nChannels; ch1++ )
     111             :     {
     112    25419633 :         for ( ch2 = ch1 + 1; ch2 < nChannels; ch2++ )
     113             :         {
     114    18384570 :             if ( fabsf( xCorrMatrix[ch1][ch2] ) > 0 )
     115             :             {
     116     9990777 :                 assert( i < ( MCT_MAX_CHANNELS * ( MCT_MAX_CHANNELS - 1 ) ) / 2 );
     117     9990777 :                 tmp_corrVals[i] = fabsf( xCorrMatrix[ch1][ch2] );
     118     9990777 :                 i++;
     119             :             }
     120             :         }
     121             :     }
     122             : 
     123             :     /* sort values */
     124     1393652 :     v_sort( tmp_corrVals, 0, ( ( nChannels * ( nChannels - 1 ) ) / 2 ) - 1 );
     125             : 
     126             :     /* get max, or 2nd max and so on depending on sortInd value */
     127     1393652 :     *max_corr = tmp_corrVals[( nChannels * ( nChannels - 1 ) ) / 2 - 1 - sortInd];
     128             : 
     129             :     /*find channel pair for this max_corr*/
     130     8428715 :     for ( ch1 = 0; ch1 < nChannels; ch1++ )
     131             :     {
     132    20756009 :         for ( ch2 = ch1 + 1; ch2 < nChannels; ch2++ )
     133             :         {
     134    15606358 :             if ( fabsf( xCorrMatrix[ch1][ch2] ) == *max_corr )
     135             :             {
     136     1885412 :                 *_ch1 = ch1;
     137     1885412 :                 *_ch2 = ch2;
     138     1885412 :                 *max_corr = xCorrMatrix[ch1][ch2]; /* assign to max_corr its actual value */
     139     1885412 :                 break;
     140             :             }
     141             :         }
     142             :     }
     143             : 
     144     1393652 :     return;
     145             : }
     146             : 
     147             : 
     148             : /*-----------------------------------------------------------------------*
     149             :  * getCorrelationMatrix()
     150             :  *
     151             :  * calculates the cross correlation matrix for all active
     152             :  * channels
     153             :  *-----------------------------------------------------------------------*/
     154             : 
     155     1458469 : static void getCorrelationMatrix(
     156             :     Encoder_State **sts,                                  /* i  : core coder handle          */
     157             :     MCT_ENC_HANDLE hMCT,                                  /* i  : MCT handle                 */
     158             :     float xCorrMatrix[MCT_MAX_CHANNELS][MCT_MAX_CHANNELS] /* o  : cross-correlation matrix   */
     159             : )
     160             : {
     161             :     int16_t ch1, ch2, n, nchan;
     162             :     float tmp;
     163             : 
     164     1458469 :     nchan = hMCT->nchan_out_woLFE;
     165             : 
     166             :     /* correlation */
     167     8746708 :     for ( ch1 = 0; ch1 < nchan; ch1++ )
     168             :     {
     169    32642068 :         for ( ch2 = ch1; ch2 < nchan; ch2++ )
     170             :         {
     171    25353829 :             xCorrMatrix[ch1][ch2] = 0;
     172             : 
     173    25353829 :             if ( sts[ch1]->core == sts[ch2]->core && sts[ch1]->mct_chan_mode != MCT_CHAN_MODE_IGNORE &&
     174    24534261 :                  sts[ch2]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     175             :             {
     176    24187657 :                 int16_t nSubframes = ( sts[ch1]->core == TCX_20_CORE ? 1 : NB_DIV );
     177    24187657 :                 int16_t L_subframe = sts[ch1]->hTcxEnc->L_frameTCX / nSubframes;
     178             : 
     179    48804839 :                 for ( n = 0; n < nSubframes; n++ )
     180             :                 {
     181    24617182 :                     xCorrMatrix[ch1][ch2] += dotp( sts[ch1]->hTcxEnc->spectrum[n], sts[ch2]->hTcxEnc->spectrum[n], L_subframe );
     182             :                 }
     183             :             }
     184             :         }
     185             :     }
     186             : 
     187             :     /* normalize */
     188     8746708 :     for ( ch1 = 0; ch1 < nchan; ch1++ )
     189             :     {
     190    25353829 :         for ( ch2 = ch1 + 1; ch2 < nchan; ch2++ )
     191             :         {
     192    18065590 :             tmp = sqrtf( xCorrMatrix[ch1][ch1] * xCorrMatrix[ch2][ch2] );
     193             : 
     194    18065590 :             if ( tmp > 0.f )
     195             :             {
     196    17321311 :                 xCorrMatrix[ch1][ch2] /= tmp;
     197             :             }
     198             :             else
     199             :             {
     200      744279 :                 xCorrMatrix[ch1][ch2] = 0.f;
     201             :             }
     202             : 
     203             : #ifdef DEBUG_MODE_MDCT
     204             :             dbgwrite( &xCorrMatrix[ch1][ch2], sizeof( float ), 1, 1, "./res/xCorrMatrix" );
     205             : #endif
     206             :         }
     207             :     }
     208             : 
     209     1458469 :     return;
     210             : }
     211             : 
     212             : 
     213             : /*-----------------------------------------------------------------*
     214             :  * getBestCorrelation()
     215             :  *
     216             :  * searches for the best correlated channel pair
     217             :  *------------------------------------------------------------------*/
     218             : 
     219     1619513 : static void getBestCorrelation(
     220             :     MCT_ENC_HANDLE hMCT,                                    /* i  : MCT handle                                */
     221             :     int16_t *_ch1,                                          /* o  : first channel of selected channel-pair    */
     222             :     int16_t *_ch2,                                          /* o  : second channel of selected channel-pair   */
     223             :     float *max_corr,                                        /* o  : normalized cross correlation value of selected channel pair */
     224             :     float xCorrMatrix[MCT_MAX_CHANNELS][MCT_MAX_CHANNELS] ) /* i  : cross-correlation matrix                  */
     225             : {
     226             :     int16_t ch1, ch2;
     227             : 
     228     1619513 :     *_ch1 = -1;
     229     1619513 :     *_ch2 = -1;
     230     1619513 :     *max_corr = 0.f;
     231             : 
     232    12908768 :     for ( ch1 = 0; ch1 < ( hMCT->nchan_out_woLFE ); ch1++ )
     233             :     {
     234    50699629 :         for ( ch2 = ch1 + 1; ch2 < ( hMCT->nchan_out_woLFE ); ch2++ )
     235             :         {
     236    39410374 :             if ( fabsf( *max_corr ) < fabsf( xCorrMatrix[ch1][ch2] ) )
     237             :             {
     238     3400597 :                 *max_corr = xCorrMatrix[ch1][ch2];
     239             : 
     240     3400597 :                 *_ch1 = ch1;
     241     3400597 :                 *_ch2 = ch2;
     242             :             }
     243             :         }
     244             :     }
     245             : 
     246     1619513 :     return;
     247             : }
     248             : 
     249             : 
     250             : /*----------------------------------------------------------------------*
     251             :  * getBlockValues()
     252             :  * stereo processing for the channels of current block
     253             :  *----------------------------------------------------------------------*/
     254             : 
     255     1556238 : static void getBlockValues(
     256             :     Encoder_State **sts,                          /* i/o: core coder handle               */
     257             :     const int16_t ch1,                            /* i  : first channel of channel-pair   */
     258             :     const int16_t ch2,                            /* i  : second channel of channel-pair  */
     259             :     MCT_BLOCK_DATA *hBlock,                       /* i  : stereo block handle             */
     260             :     float *mdst_spectrum[MCT_MAX_CHANNELS][2],    /* i/o: MDST spectrum                   */
     261             :     float *inv_spectrum[MCT_MAX_CHANNELS][2],     /* i/o: inverse spectrum                */
     262             :     float *inv_mdst_spectrum[MCT_MAX_CHANNELS][2] /* i/o: invers MDST spectrum            */
     263             : )
     264             : {
     265             :     int16_t n;
     266             :     float *p_mdst_spectrum[2][2];
     267             :     float *p_inv_spectrum[2][2];
     268             :     float *p_inv_mdst_spectrum[2][2];
     269             :     Encoder_State *p_st[2];
     270             : 
     271             :     /* init return values: */
     272     1556238 :     hBlock->isActive = 1;
     273             : 
     274             :     /* map vectors to current block channels */
     275     4668714 :     for ( n = 0; n < 2; n++ )
     276             :     {
     277     3112476 :         p_mdst_spectrum[0][n] = mdst_spectrum[ch1][n];
     278     3112476 :         p_mdst_spectrum[1][n] = mdst_spectrum[ch2][n];
     279     3112476 :         p_inv_spectrum[0][n] = inv_spectrum[ch1][n];
     280     3112476 :         p_inv_spectrum[1][n] = inv_spectrum[ch2][n];
     281     3112476 :         p_inv_mdst_spectrum[0][n] = inv_mdst_spectrum[ch1][n];
     282     3112476 :         p_inv_mdst_spectrum[1][n] = inv_mdst_spectrum[ch2][n];
     283             :     }
     284     1556238 :     p_st[0] = sts[ch1];
     285     1556238 :     p_st[1] = sts[ch2];
     286             : 
     287     1556238 :     stereo_coder_tcx( hBlock->hStereoMdct, p_st, hBlock->mask, p_mdst_spectrum, p_inv_spectrum, p_inv_mdst_spectrum, 1 );
     288             : 
     289     1556238 :     if ( ( sts[ch1]->core == TCX_20_CORE && hBlock->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) || ( sts[ch1]->core == TCX_10_CORE && hBlock->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO && hBlock->hStereoMdct->mdct_stereo_mode[1] == SMDCT_DUAL_MONO ) )
     290             :     {
     291       37363 :         hBlock->isActive = 0;
     292             :     }
     293             : 
     294     1556238 :     return;
     295             : }
     296             : 
     297             : 
     298             : /*-------------------------------------------------------------------*
     299             :  * updateCorrelationMatrix()
     300             :  *
     301             :  * updates the cross correlation matrix with modified spectra after
     302             :  * stereo block processing
     303             :  *-------------------------------------------------------------------*/
     304             : 
     305     1518875 : static void updateCorrelationMatrix(
     306             :     Encoder_State **sts,
     307             :     MCT_ENC_HANDLE hMCT,
     308             :     const int16_t _ch1,
     309             :     const int16_t _ch2,
     310             :     float xCorrMatrix[MCT_MAX_CHANNELS][MCT_MAX_CHANNELS] )
     311             : {
     312             :     int16_t ch1, ch2, n;
     313             : 
     314             :     /* correlation: */
     315    12349365 :     for ( ch1 = 0; ch1 < ( hMCT->nchan_out_woLFE ); ch1++ )
     316             :     {
     317    60823277 :         for ( ch2 = ch1; ch2 < ( hMCT->nchan_out_woLFE ); ch2++ )
     318             :         {
     319    49992787 :             if ( sts[ch1]->core == sts[ch2]->core && sts[ch1]->mct_chan_mode != MCT_CHAN_MODE_IGNORE &&
     320    49109319 :                  sts[ch2]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     321             :             {
     322    48940483 :                 int16_t nSubframes = ( sts[ch1]->core == TCX_20_CORE ? 1 : NB_DIV );
     323             : 
     324    48940483 :                 if ( ch1 == _ch1 || ch2 == _ch2 || ch1 == _ch2 || ch2 == _ch1 )
     325             :                 {
     326    39885101 :                     for ( n = 0; n < nSubframes; n++ )
     327             :                     {
     328    20135904 :                         xCorrMatrix[ch1][ch2] = 0; /*disable combinations with channels already processed */
     329             :                     }
     330             :                 }
     331             :             }
     332             :         }
     333             :     }
     334             : 
     335     1518875 :     return;
     336             : }
     337             : 
     338             : 
     339             : /*----------------------------------------------------------*
     340             :  * channelPairToIndex()
     341             :  * get the index of each channel pair
     342             :  *----------------------------------------------------------*/
     343             : 
     344     1518875 : static int16_t channelPairToIndex(
     345             :     const int16_t chIdx1,
     346             :     const int16_t chIdx2,
     347             :     const int16_t nChannels )
     348             : {
     349             :     int16_t ch1, ch2;
     350             :     int16_t pairIdx;
     351             : 
     352     1518875 :     pairIdx = 0;
     353             : 
     354     6770695 :     for ( ch2 = 1; ch2 < nChannels; ch2++ )
     355             :     {
     356    25720774 :         for ( ch1 = 0; ch1 < ch2; ch1++ )
     357             :         {
     358    20468954 :             if ( ch1 == chIdx1 && ch2 == chIdx2 )
     359             :             {
     360     1518875 :                 return pairIdx;
     361             :             }
     362             :             else
     363             :             {
     364    18950079 :                 pairIdx++;
     365             :             }
     366             :         }
     367             :     }
     368             : 
     369           0 :     return -1;
     370             : }
     371             : 
     372             : 
     373             : /*--------------------------------------------------------------------*
     374             :  * getGlobalILD()
     375             :  * get broadband ILD to mean energy and normalize channels with ratio
     376             :  *--------------------------------------------------------------------*/
     377             : 
     378     1458469 : static void getGlobalILD(
     379             :     Encoder_State **sts,
     380             :     MCT_ENC_HANDLE hMCT,
     381             :     float *mdst_spectrum[MCT_MAX_CHANNELS][2],
     382             :     const int16_t nchan )
     383             : {
     384             :     int16_t k, ch, nSubframes, L_subframe;
     385             :     float nrg[MCT_MAX_CHANNELS];
     386     1458469 :     float meanE = 0.f, ratio, qratio;
     387     1458469 :     int16_t cnt = 0;
     388             : 
     389             :     /*Initializations*/
     390     1458469 :     set_s( hMCT->lowE_ch, 0, nchan );
     391             : 
     392     1458469 :     getChannelEnergies( sts, nrg, nchan );
     393             : 
     394             :     /*calculate total energy without LFE*/
     395     8746708 :     for ( ch = 0; ch < nchan; ch++ )
     396             :     {
     397     7288239 :         if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     398             :         {
     399     7142030 :             meanE += nrg[ch];
     400     7142030 :             cnt++;
     401             :         }
     402             :     }
     403             : 
     404             :     /*calculate mean energy*/
     405     1458469 :     assert( cnt >= 2 );
     406     1458469 :     meanE = max( meanE / cnt, EPSILON );
     407     8746708 :     for ( ch = 0; ch < nchan; ch++ )
     408             :     {
     409     7288239 :         if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     410             :         {
     411     7142030 :             nSubframes = ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
     412     7142030 :             L_subframe = sts[ch]->hTcxEnc->L_frameTCX / nSubframes;
     413             : 
     414     7142030 :             if ( nrg[ch] > meanE ) /*change it to meanE if final solution*/
     415             :             {
     416     2781663 :                 ratio = meanE / nrg[ch];
     417     2781663 :                 hMCT->mc_global_ild[ch] = max( 1, min( SMDCT_ILD_RANGE - 1, (int16_t) ( SMDCT_ILD_RANGE * ratio + 0.5f ) ) );
     418     2781663 :                 qratio = (float) hMCT->mc_global_ild[ch] / SMDCT_ILD_RANGE;
     419             :             }
     420             :             else
     421             :             {
     422     4360367 :                 ratio = nrg[ch] / meanE;
     423     4360367 :                 hMCT->lowE_ch[ch] = 1;
     424     4360367 :                 hMCT->mc_global_ild[ch] = max( 1, min( SMDCT_ILD_RANGE - 1, (int16_t) ( SMDCT_ILD_RANGE * ratio + 0.5f ) ) );
     425     4360367 :                 qratio = (float) SMDCT_ILD_RANGE / hMCT->mc_global_ild[ch];
     426             :             }
     427             : 
     428    14443010 :             for ( k = 0; k < nSubframes; k++ )
     429             :             {
     430     7300980 :                 v_multc( sts[ch]->hTcxEnc->spectrum[k], qratio, sts[ch]->hTcxEnc->spectrum[k], L_subframe );
     431     7300980 :                 v_multc( mdst_spectrum[ch][k], qratio, mdst_spectrum[ch][k], L_subframe );
     432             :             }
     433             :         }
     434             :     }
     435             : 
     436             : #ifdef DEBUG_MODE_MDCT
     437             :     /*check if energy levels are comparable*/
     438             :     getChannelEnergies( sts, nrg, nchan );
     439             :     dbgwrite( nrg, sizeof( float ), 6, 1, "./res/nrgGlobalILD" );
     440             : #endif
     441             : 
     442     1458469 :     return;
     443             : }
     444             : 
     445             : 
     446             : /*--------------------------------------------------------------------*
     447             :  * apply_MCT_enc()
     448             :  *
     449             :  * apply MCT algorithm to input channels
     450             :  *--------------------------------------------------------------------*/
     451             : 
     452     1461203 : void apply_MCT_enc(
     453             :     MCT_ENC_HANDLE hMCT,                                /* i/o: MCT encoder structure               */
     454             :     Encoder_State **sts,                                /* i/o: encoder state structure             */
     455             :     float *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV],     /* i/o: MDST spectrum                       */
     456             :     float *inv_spectrum[MCT_MAX_CHANNELS][NB_DIV],      /* i/o: inverse spectrum                    */
     457             :     float *inv_mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: inverse MDST spectrum               */
     458             :     const int16_t nchan                                 /* i  : number of channels                  */
     459             : )
     460             : {
     461             :     int16_t ch, k, ch1, ch2, nSubframes, L_subframeTCX;
     462             :     float max_corr, qratio;
     463             :     int16_t forceKeepTree, pair;
     464             :     float sumCorrDiff, thr;
     465             :     float xCorrMatrix[MCT_MAX_CHANNELS][MCT_MAX_CHANNELS];
     466             :     int16_t currBlockDataCnt;
     467             :     int16_t cpEle[MCT_MAX_CHANNELS];
     468             :     int16_t inactiveBlockDetected;
     469             :     int16_t tmp_ch1, tmp_ch2;
     470             :     float tmp_max_corr;
     471     1461203 :     int16_t count_active_ch = 0;
     472             : 
     473     1461203 :     push_wmops( "mct_core_enc_mct" );
     474             : 
     475     1461203 :     forceKeepTree = 1;
     476     1461203 :     inactiveBlockDetected = 0;
     477     1461203 :     set_s( cpEle, 0, MCT_MAX_CHANNELS );
     478             : 
     479             :     /*Determine active channels*/
     480     8759520 :     for ( ch = 0; ch < nchan; ch++ )
     481             :     {
     482     7298317 :         if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     483             :         {
     484     7143418 :             count_active_ch++;
     485             :         }
     486             :         else
     487             :         {
     488      154899 :             hMCT->mc_global_ild[ch] = 0;
     489             :         }
     490             :     }
     491             : 
     492             :     /*there should be at least one cp*/
     493     1461203 :     if ( count_active_ch >= CPE_CHANNELS )
     494             :     {
     495             :         /*Normalize energies with global ILD*/
     496     1458469 :         getGlobalILD( sts, hMCT, mdst_spectrum, nchan );
     497             : #ifndef DEBUG_FORCE_MCT_CP
     498     1458469 :         getCorrelationMatrix( sts, hMCT, xCorrMatrix );
     499             : 
     500             :         /*check if previous tree should be kept*/
     501     1458469 :         sumCorrDiff = 0.0f;
     502     1458469 :         thr = 0.15f * (float) ( count_active_ch ) * ( count_active_ch - 1 ) / 2.0f;
     503     7288239 :         for ( ch2 = 1; ch2 < nchan; ch2++ )
     504             :         {
     505    23895360 :             for ( ch1 = 0; ch1 < ch2; ch1++ )
     506             :             {
     507    18065590 :                 if ( sts[ch1]->mct_chan_mode != MCT_CHAN_MODE_IGNORE &&
     508    17674483 :                      sts[ch2]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     509             :                 {
     510    17321311 :                     sumCorrDiff += fabsf( hMCT->lastxCorrMatrix[ch1][ch2] - xCorrMatrix[ch1][ch2] );
     511             :                 }
     512             :             }
     513             :         }
     514             : 
     515     1458469 :         if ( sumCorrDiff > thr )
     516             :         {
     517      480681 :             forceKeepTree = 0;
     518             :         }
     519             : 
     520             :         /* check if keepTree is applied on unallowed blocks (e.g. channel pairs with different cores) */
     521     1458469 :         if ( forceKeepTree )
     522             :         {
     523      977788 :             if ( !hMCT->currBlockDataCnt )
     524             :             {
     525      444129 :                 forceKeepTree = 0;
     526             :             }
     527             :             else
     528             :             {
     529     1702193 :                 for ( pair = 0; pair < hMCT->currBlockDataCnt; pair++ )
     530             :                 {
     531     1168534 :                     if ( xCorrMatrix[hMCT->hBlockData[pair]->ch1][hMCT->hBlockData[pair]->ch2] == 0.0f )
     532             :                     {
     533        1170 :                         forceKeepTree = 0;
     534             :                     }
     535             :                 }
     536             :             }
     537             :         }
     538             : 
     539             :         /*save initial correlation matrix for next frame*/
     540     8746708 :         for ( ch1 = 0; ch1 < nchan; ch1++ )
     541             :         {
     542    32642068 :             for ( ch2 = ch1; ch2 < nchan; ch2++ )
     543             :             {
     544    25353829 :                 hMCT->lastxCorrMatrix[ch1][ch2] = xCorrMatrix[ch1][ch2];
     545             :             }
     546             :         }
     547             : 
     548             : #ifdef DEBUG_MODE_MDCT
     549             :         dbgwrite( &forceKeepTree, sizeof( int16_t ), 1, 1, "./res/keepTree" );
     550             : #endif
     551             : 
     552     1458469 :         currBlockDataCnt = 0;
     553     3013165 :         while ( currBlockDataCnt < hMCT->nchan_out_woLFE )
     554             :         {
     555             :             /* find best fitting channel pair: */
     556     3013165 :             ch1 = -1;
     557     3013165 :             ch2 = -1;
     558     3013165 :             max_corr = 0.f;
     559             : 
     560     3013165 :             if ( !forceKeepTree )
     561             :             {
     562     1393652 :                 getNextBestCorrelation( xCorrMatrix, &ch1, &ch2, &max_corr, inactiveBlockDetected, nchan );
     563             :             }
     564             :             else
     565             :             {
     566     1619513 :                 getBestCorrelation( hMCT, &tmp_ch1, &tmp_ch2, &tmp_max_corr, xCorrMatrix );
     567             : 
     568     1619513 :                 if ( currBlockDataCnt == hMCT->currBlockDataCnt )
     569             :                 {
     570      458676 :                     break;
     571             :                 }
     572             :                 else
     573             :                 {
     574     1160837 :                     ch1 = hMCT->hBlockData[currBlockDataCnt]->ch1;
     575     1160837 :                     ch2 = hMCT->hBlockData[currBlockDataCnt]->ch2;
     576             : 
     577             :                     /*don't allow forcing of channel-pair if their correlation is under the  threshold*/
     578     1160837 :                     max_corr = xCorrMatrix[ch1][ch2];
     579     1160837 :                     if ( fabsf( max_corr ) <= 0.3f )
     580             :                     {
     581       68792 :                         ch1 = tmp_ch1;
     582       68792 :                         ch2 = tmp_ch2;
     583       68792 :                         max_corr = tmp_max_corr;
     584       68792 :                         forceKeepTree = 0;
     585             :                     }
     586             :                 }
     587             :             }
     588             : 
     589     2554489 :             if ( ( fabsf( max_corr ) > DEFAULT_CORR_THRES && !hMCT->hbr_mct ) || ( fabsf( max_corr ) > SPAR_CORR_THRES && hMCT->hbr_mct ) )
     590             :             {
     591     1556238 :                 if ( !forceKeepTree )
     592             :                 {
     593             :                     /*save channel pair*/
     594      464644 :                     hMCT->hBlockData[currBlockDataCnt]->ch1 = ch1;
     595      464644 :                     hMCT->hBlockData[currBlockDataCnt]->ch2 = ch2;
     596             :                 }
     597             : 
     598             :                 /* calculate all related values: */
     599     1556238 :                 assert( sts[ch1]->mct_chan_mode != MCT_CHAN_MODE_IGNORE && sts[ch2]->mct_chan_mode != MCT_CHAN_MODE_IGNORE );
     600             : 
     601     1556238 :                 getBlockValues( sts, ch1, ch2, hMCT->hBlockData[currBlockDataCnt], mdst_spectrum, inv_spectrum, inv_mdst_spectrum );
     602             : 
     603     1556238 :                 if ( hMCT->hBlockData[currBlockDataCnt]->isActive == 0 )
     604             :                 {
     605       37363 :                     inactiveBlockDetected++;
     606       37363 :                     if ( inactiveBlockDetected > hMCT->nchan_out_woLFE / 2 )
     607             :                     {
     608        1542 :                         break;
     609             :                     }
     610       35821 :                     forceKeepTree = 0;
     611             : 
     612       35821 :                     continue; /* skip inactive blocks where stereo mode is dual-mono */
     613             :                 }
     614             : 
     615     1518875 :                 updateCorrelationMatrix( sts, hMCT, ch1, ch2, xCorrMatrix );
     616     1518875 :                 cpEle[ch1] = 1;
     617     1518875 :                 cpEle[ch2] = 1;
     618             : 
     619     1518875 :                 currBlockDataCnt++;
     620             :             }
     621             :             else
     622             :             {
     623             :                 break;
     624             :             }
     625             :         }
     626             : 
     627             :         /*save number of blocks for next frame*/
     628     1458469 :         hMCT->currBlockDataCnt = currBlockDataCnt;
     629             : #else
     630             :         forceKeepTree = 1;
     631             :         if ( nchan == 3 ) /*3 TCs*/
     632             :         {
     633             : #ifdef DEBUG_SINGLE_CODE_OMNI
     634             :             ch1 = 1;
     635             :             ch2 = 2;
     636             :             cpEle[0] = 0;
     637             : #else
     638             :             /* one stereo pair for first and second channel (W,Y)*/
     639             :             ch1 = 0;
     640             :             ch2 = 1;
     641             :             cpEle[2] = 0;
     642             : #endif
     643             :             hMCT->currBlockDataCnt = 1;
     644             :             hMCT->hBlockData[0]->ch1 = ch1;
     645             :             hMCT->hBlockData[0]->ch2 = ch2;
     646             : 
     647             :             getBlockValues( sts, ch1, ch2, hMCT->hBlockData[0], mdst_spectrum, inv_spectrum, inv_mdst_spectrum );
     648             : 
     649             :             if ( hMCT->hBlockData[0]->isActive )
     650             :             {
     651             :                 cpEle[ch1] = 1;
     652             :                 cpEle[ch2] = 1;
     653             :             }
     654             :             else
     655             :             {
     656             :                 hMCT->currBlockDataCnt = 0;
     657             :             }
     658             :         }
     659             :         else
     660             :         {
     661             :             assert( nchan == 4 ); /*4 TCs*/
     662             :             /* 2 Stereo Pairs W-Y and X-Z */
     663             :             hMCT->currBlockDataCnt = nchan * 0.5;
     664             :             for ( currBlockDataCnt = 0; currBlockDataCnt < hMCT->currBlockDataCnt; currBlockDataCnt++ )
     665             :             {
     666             :                 hMCT->hBlockData[currBlockDataCnt]->ch1 = currBlockDataCnt * CPE_CHANNELS;
     667             :                 hMCT->hBlockData[currBlockDataCnt]->ch2 = currBlockDataCnt * CPE_CHANNELS + 1;
     668             :                 getBlockValues( sts, hMCT->hBlockData[currBlockDataCnt]->ch1, hMCT->hBlockData[currBlockDataCnt]->ch2, hMCT->hBlockData[currBlockDataCnt], mdst_spectrum, inv_spectrum, inv_mdst_spectrum );
     669             :                 if ( hMCT->hBlockData[0]->isActive )
     670             :                 {
     671             :                     cpEle[hMCT->hBlockData[currBlockDataCnt]->ch1] = 1;
     672             :                     cpEle[hMCT->hBlockData[currBlockDataCnt]->ch2] = 1;
     673             :                 }
     674             :                 else
     675             :                 {
     676             :                     hMCT->currBlockDataCnt -= 1;
     677             :                 }
     678             :             }
     679             :         }
     680             : #endif
     681             : 
     682     8746708 :         for ( ch = 0; ch < nchan; ch++ )
     683             :         {
     684     7288239 :             if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     685             :             {
     686     7142030 :                 if ( ( !cpEle[ch] ) || hMCT->currBlockDataCnt == 0 )
     687             :                 {
     688     4104280 :                     nSubframes = ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV;
     689     4104280 :                     L_subframeTCX = sts[ch]->hTcxEnc->L_frameTCX / nSubframes;
     690             : 
     691     4104280 :                     if ( hMCT->lowE_ch[ch] )
     692             :                     {
     693     2623901 :                         qratio = (float) hMCT->mc_global_ild[ch] / SMDCT_ILD_RANGE;
     694             :                     }
     695             :                     else
     696             :                     {
     697     1480379 :                         qratio = (float) SMDCT_ILD_RANGE / hMCT->mc_global_ild[ch];
     698             :                     }
     699             : 
     700     8296584 :                     for ( k = 0; k < nSubframes; k++ )
     701             :                     {
     702     4192304 :                         v_multc( sts[ch]->hTcxEnc->spectrum[k], qratio, sts[ch]->hTcxEnc->spectrum[k], L_subframeTCX );
     703     4192304 :                         v_multc( mdst_spectrum[ch][k], qratio, mdst_spectrum[ch][k], L_subframeTCX );
     704     4192304 :                         set_zero( inv_spectrum[ch][k], L_subframeTCX );
     705             :                     }
     706     4104280 :                     hMCT->mc_global_ild[ch] = 0;
     707             :                 }
     708             :             }
     709             :         }
     710             :     }
     711             :     else
     712             :     {
     713        2734 :         hMCT->currBlockDataCnt = 0;
     714       12812 :         for ( ch = 0; ch < nchan; ch++ )
     715             :         {
     716       10078 :             hMCT->mc_global_ild[ch] = 0;
     717             :         }
     718             :     }
     719             : #ifdef DEBUG_MODE_MDCT
     720             :     dbgwrite( &hMCT->currBlockDataCnt, sizeof( int16_t ), 1, 1, "./res/blockCnt" );
     721             : 
     722             :     {
     723             :         int16_t pair, k;
     724             :         for ( pair = 0; pair < (int16_t) ( hMCT->nchan_out_woLFE * 0.5 ); pair++ )
     725             :         {
     726             :             dbgwrite( &hMCT->hBlockData[pair]->ch1, sizeof( int16_t ), 1, 1, "./res/CP_in_blocks" );
     727             :             dbgwrite( &hMCT->hBlockData[pair]->ch2, sizeof( int16_t ), 1, 1, "./res/CP_in_blocks" );
     728             :             for ( k = 0; k < 2; k++ )
     729             :             {
     730             :                 dbgwrite( &hMCT->hBlockData[pair]->hStereoMdct->global_ild[k], sizeof( int16_t ), 1, 1, "./res/ILD_p_block" );
     731             :                 dbgwrite( &hMCT->hBlockData[pair]->hStereoMdct->mdct_stereo_mode[k], sizeof( int16_t ), 1, 1, "./res/stereo_mode_p_block" );
     732             :                 dbgwrite( &hMCT->hBlockData[pair]->mask[k], sizeof( int16_t ), MAX_SFB, 1, "./res/ms_mask_p_block" );
     733             :             }
     734             :         }
     735             :     }
     736             : #endif
     737             : 
     738     1461203 :     pop_wmops();
     739             : 
     740     1461203 :     return;
     741             : }
     742             : 
     743             : 
     744             : /*--------------------------------------------------------------------*
     745             :  * write_mct_bitstream()
     746             :  *
     747             :  * write mct metadata to bitstream
     748             :  *--------------------------------------------------------------------*/
     749             : 
     750     1461203 : void write_mct_bitstream(
     751             :     Encoder_State **sts, /* i/o: encoder state structure     */
     752             :     MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure       */
     753             :     const int16_t nchan  /* i  : number of channels          */
     754             : )
     755             : {
     756             :     int16_t pair, ch;
     757             :     int16_t channelPairIndex;
     758             :     int16_t nbits_start;
     759             :     MCT_BLOCK_DATA_HANDLE hBlock;
     760             :     Encoder_State *p_st[2];
     761     1461203 :     BSTR_ENC_HANDLE hBstr = sts[0]->hBstr;
     762             : 
     763     1461203 :     nbits_start = hBstr->nb_bits_tot;
     764             : 
     765     1461203 :     push_next_indice( hBstr, hMCT->currBlockDataCnt, MCT_NUM_BLOCK_DATA_BITS );
     766             : 
     767             :     /* first write core info and overlap mode for all channels */
     768     8759520 :     for ( ch = 0; ch < nchan; ch++ )
     769             :     {
     770     7298317 :         if ( hMCT->currBlockDataCnt && sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     771             :         {
     772     4260240 :             push_next_indice( hBstr, hMCT->mc_global_ild[ch], SMDCT_GLOBAL_ILD_BITS );
     773             :         }
     774             :     }
     775             : 
     776     1461203 :     if ( hMCT->currBlockDataCnt )
     777             :     {
     778     5069833 :         for ( ch = 0; ch < nchan; ch++ )
     779             :         {
     780     4331179 :             if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     781             :             {
     782     4260240 :                 push_next_indice( hBstr, hMCT->lowE_ch[ch], 1 );
     783             :             }
     784             :         }
     785             :     }
     786             : 
     787             :     /* Do for each stereo block */
     788     2980078 :     for ( pair = hMCT->currBlockDataCnt - 1; pair >= 0; pair-- )
     789             :     {
     790     1518875 :         hBlock = hMCT->hBlockData[pair];
     791             : 
     792             :         /*calculate channel pair index and write it to BS*/
     793     1518875 :         channelPairIndex = channelPairToIndex( hBlock->ch1, hBlock->ch2, nchan );
     794     1518875 :         push_next_indice( hBstr, channelPairIndex, hMCT->bitsChannelPairIndex );
     795             : 
     796             :         /*point to encoder states of actual channels to write block pair bits*/
     797     1518875 :         p_st[0] = sts[hBlock->ch1];
     798     1518875 :         p_st[1] = sts[hBlock->ch2];
     799             : 
     800             :         /*then business as usual for each block pair */
     801     1518875 :         write_stereo_to_bitstream( hMCT->hBlockData[pair]->hStereoMdct, p_st, hBlock->mask, 1, hBstr );
     802             :     }
     803             : 
     804     1461203 :     hMCT->nBitsMCT = hBstr->nb_bits_tot - nbits_start;
     805             : 
     806     1461203 :     return;
     807             : }
     808             : 
     809             : 
     810             : /*--------------------------------------------------------------------*
     811             :  * mctStereoIGF_enc()
     812             :  *
     813             :  * IGF analysis of channels after MCT processing
     814             :  *--------------------------------------------------------------------*/
     815             : 
     816      495569 : void mctStereoIGF_enc(
     817             :     MCT_ENC_HANDLE hMCT,                             /* i/o: MCT encoder structure               */
     818             :     Encoder_State **sts,                             /* i/o: encoder state structure             */
     819             :     float *orig_spectrum[MCT_MAX_CHANNELS][2],       /* i  : MDCT spectrum for ITF               */
     820             :     float *powerSpec[MCT_MAX_CHANNELS],              /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/
     821             :     float *powerSpecMsInv[MCT_MAX_CHANNELS][NB_DIV], /* i  : same as above but for inverse spect.*/
     822             :     float *inv_spectrum[MCT_MAX_CHANNELS][NB_DIV],   /* i  : inverse spectrum                    */
     823             :     const int16_t sp_aud_decision0[MCT_MAX_CHANNELS] /* i  : speech audio decision               */
     824             : )
     825             : {
     826             :     int16_t b, nSubframes, L_subframeTCX;
     827             :     int16_t p_ch[2], n, ch, ch1, ch2;
     828             :     Encoder_State *p_st[NB_DIV];
     829             :     Encoder_State *st;
     830             :     float *p_powerSpecMsInv[CPE_CHANNELS][NB_DIV];
     831             :     float *p_inv_spectrum[CPE_CHANNELS][NB_DIV];
     832             :     float *p_orig_spectrum[CPE_CHANNELS][NB_DIV];
     833             :     float *p_powerSpec[NB_DIV];
     834             :     int16_t singleChEle[MCT_MAX_CHANNELS];
     835             : 
     836      495569 :     L_subframeTCX = 0; /* to avoid compilation warning */
     837      495569 :     set_s( singleChEle, 1, hMCT->nchan_out_woLFE );
     838             : 
     839     1640741 :     for ( b = 0; b < hMCT->currBlockDataCnt; b++ )
     840             :     {
     841     1145172 :         ch1 = hMCT->hBlockData[b]->ch1;
     842     1145172 :         ch2 = hMCT->hBlockData[b]->ch2;
     843             : 
     844     1145172 :         p_ch[0] = ch1;
     845     1145172 :         p_ch[1] = ch2;
     846             : 
     847     1145172 :         singleChEle[hMCT->hBlockData[b]->ch1] = 0;
     848     1145172 :         singleChEle[hMCT->hBlockData[b]->ch2] = 0;
     849             : 
     850             :         /* point to encoder states of actual channels to write block pair bits */
     851     1145172 :         p_st[0] = sts[ch1];
     852     1145172 :         p_st[1] = sts[ch2];
     853             : 
     854     1145172 :         if ( ch1 > 0 )
     855             :         {
     856      798007 :             sts[ch1]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
     857             :         }
     858             : 
     859     1145172 :         if ( ch2 > 0 )
     860             :         {
     861     1145172 :             sts[ch2]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
     862             :         }
     863             : 
     864     1145172 :         p_powerSpec[0] = powerSpec[ch1];
     865     1145172 :         p_powerSpec[1] = powerSpec[ch2];
     866             : 
     867             :         /* Band-wise M/S for MDST */
     868     1145172 :         nSubframes = p_st[0]->hTcxEnc->tcxMode == TCX_20 ? 1 : NB_DIV;
     869     2319192 :         for ( n = 0; n < nSubframes; n++ )
     870             :         {
     871     1174020 :             p_orig_spectrum[0][n] = orig_spectrum[ch1][n];
     872     1174020 :             p_orig_spectrum[1][n] = orig_spectrum[ch2][n];
     873     1174020 :             p_powerSpecMsInv[0][n] = powerSpecMsInv[ch1][n];
     874     1174020 :             p_powerSpecMsInv[1][n] = powerSpecMsInv[ch2][n];
     875     1174020 :             p_inv_spectrum[0][n] = inv_spectrum[ch1][n];
     876     1174020 :             p_inv_spectrum[1][n] = inv_spectrum[ch2][n];
     877             : 
     878     1174020 :             if ( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n] != hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[n] ||
     879      590570 :                  hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n] == SMDCT_BW_MS )
     880             :             {
     881      617424 :                 ProcessStereoIGF( hMCT->hBlockData[b]->hStereoMdct, p_st, hMCT->hBlockData[b]->mask, p_orig_spectrum, p_powerSpec, p_powerSpecMsInv, p_inv_spectrum, n, sp_aud_decision0[ch1], p_st[0]->total_brate, 1 );
     882             :             }
     883             :             else
     884             :             {
     885     1669788 :                 for ( ch = 0; ch < CPE_CHANNELS; ch++ )
     886             :                 {
     887     1113192 :                     st = p_st[ch];
     888             : 
     889     1113192 :                     L_subframeTCX = st->hTcxEnc->L_frameTCX / nSubframes;
     890             : 
     891     1113192 :                     ProcessIGF( st, st->hTcxEnc->spectrum[n], (float *) orig_spectrum[p_ch[ch]][n], &powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch1], 0 );
     892             :                 }
     893             :             }
     894             :         }
     895             :     }
     896             : 
     897             :     /* channel elements that are coded separately detected */
     898      495569 :     if ( sum_s( singleChEle, ( hMCT->nchan_out_woLFE ) ) != 0 )
     899             :     {
     900     3494246 :         for ( ch = 0; ch < ( hMCT->nchan_out_woLFE ); ch++ )
     901             :         {
     902     2998721 :             if ( singleChEle[ch] )
     903             :             {
     904      708557 :                 st = sts[ch];
     905             : 
     906      708557 :                 if (
     907      708557 :                     st->mct_chan_mode == MCT_CHAN_MODE_IGNORE )
     908             :                 {
     909       10635 :                     continue;
     910             :                 }
     911             : 
     912      697922 :                 if ( ch > 0 )
     913             :                 {
     914      549715 :                     st->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
     915             :                 }
     916             : 
     917      697922 :                 nSubframes = st->hTcxEnc->tcxMode == TCX_20 ? 1 : NB_DIV;
     918     1414634 :                 for ( n = 0; n < nSubframes; n++ )
     919             :                 {
     920      716712 :                     ProcessIGF( st, st->hTcxEnc->spectrum[n], (float *) orig_spectrum[ch][n], &powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 );
     921             :                 }
     922             :             }
     923             :         }
     924             :     }
     925             : 
     926      495569 :     return;
     927             : }

Generated by: LCOV version 1.14