LCOV - code coverage report
Current view: top level - lib_enc - ivas_mct_enc_mct.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 268 269 99.6 %
Date: 2025-05-23 08:37:30 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      201407 : 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     1162903 :     for ( ch = 0; ch < nchan; ch++ )
      68             :     {
      69      961496 :         st = sts[ch];
      70      961496 :         if ( st->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
      71             :         {
      72      946118 :             nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
      73      946118 :             L_subframe = st->hTcxEnc->L_frameTCX / nSubframes;
      74             : 
      75      946118 :             nrg[ch] = 0;
      76     1913528 :             for ( n = 0; n < nSubframes; n++ )
      77             :             {
      78      967410 :                 nrg[ch] += sum2_f( st->hTcxEnc->spectrum[n], L_subframe );
      79             :             }
      80      946118 :             nrg[ch] = sqrtf( nrg[ch] );
      81             :         }
      82             :     }
      83             : 
      84      201407 :     return;
      85             : }
      86             : 
      87             : 
      88             : /*-------------------------------------------------------------------------
      89             :  * getNextBestCorrelation()
      90             :  *
      91             :  * find channel pair with highest cross-correlation
      92             :  *-------------------------------------------------------------------------*/
      93             : 
      94      101093 : 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      101093 :     set_f( tmp_corrVals, 0, ( MCT_MAX_CHANNELS * ( MCT_MAX_CHANNELS - 1 ) ) / 2 );
     107             : 
     108             :     /* first sort correlation matrix */
     109      101093 :     i = 0;
     110      594411 :     for ( ch1 = 0; ch1 < nChannels; ch1++ )
     111             :     {
     112     1658169 :         for ( ch2 = ch1 + 1; ch2 < nChannels; ch2++ )
     113             :         {
     114     1164851 :             if ( fabsf( xCorrMatrix[ch1][ch2] ) > 0 )
     115             :             {
     116      726828 :                 assert( i < ( MCT_MAX_CHANNELS * ( MCT_MAX_CHANNELS - 1 ) ) / 2 );
     117      726828 :                 tmp_corrVals[i] = fabsf( xCorrMatrix[ch1][ch2] );
     118      726828 :                 i++;
     119             :             }
     120             :         }
     121             :     }
     122             : 
     123             :     /* sort values */
     124      101093 :     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      101093 :     *max_corr = tmp_corrVals[( nChannels * ( nChannels - 1 ) ) / 2 - 1 - sortInd];
     128             : 
     129             :     /*find channel pair for this max_corr*/
     130      594411 :     for ( ch1 = 0; ch1 < nChannels; ch1++ )
     131             :     {
     132     1378190 :         for ( ch2 = ch1 + 1; ch2 < nChannels; ch2++ )
     133             :         {
     134     1013839 :             if ( fabsf( xCorrMatrix[ch1][ch2] ) == *max_corr )
     135             :             {
     136      128967 :                 *_ch1 = ch1;
     137      128967 :                 *_ch2 = ch2;
     138      128967 :                 *max_corr = xCorrMatrix[ch1][ch2]; /* assign to max_corr its actual value */
     139      128967 :                 break;
     140             :             }
     141             :         }
     142             :     }
     143             : 
     144      101093 :     return;
     145             : }
     146             : 
     147             : 
     148             : /*-----------------------------------------------------------------------*
     149             :  * getCorrelationMatrix()
     150             :  *
     151             :  * calculates the cross correlation matrix for all active
     152             :  * channels
     153             :  *-----------------------------------------------------------------------*/
     154             : 
     155      100468 : 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      100468 :     nchan = hMCT->nchan_out_woLFE;
     165             : 
     166             :     /* correlation */
     167      580177 :     for ( ch1 = 0; ch1 < nchan; ch1++ )
     168             :     {
     169     2017070 :         for ( ch2 = ch1; ch2 < nchan; ch2++ )
     170             :         {
     171     1537361 :             xCorrMatrix[ch1][ch2] = 0;
     172             : 
     173     1537361 :             if ( sts[ch1]->core == sts[ch2]->core && sts[ch1]->mct_chan_mode != MCT_CHAN_MODE_IGNORE &&
     174     1501804 :                  sts[ch2]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     175             :             {
     176     1473396 :                 int16_t nSubframes = ( sts[ch1]->core == TCX_20_CORE ? 1 : NB_DIV );
     177     1473396 :                 int16_t L_subframe = sts[ch1]->hTcxEnc->L_frameTCX / nSubframes;
     178             : 
     179     2970404 :                 for ( n = 0; n < nSubframes; n++ )
     180             :                 {
     181     1497008 :                     xCorrMatrix[ch1][ch2] += dotp( sts[ch1]->hTcxEnc->spectrum[n], sts[ch2]->hTcxEnc->spectrum[n], L_subframe );
     182             :                 }
     183             :             }
     184             :         }
     185             :     }
     186             : 
     187             :     /* normalize */
     188      580177 :     for ( ch1 = 0; ch1 < nchan; ch1++ )
     189             :     {
     190     1537361 :         for ( ch2 = ch1 + 1; ch2 < nchan; ch2++ )
     191             :         {
     192     1057652 :             tmp = sqrtf( xCorrMatrix[ch1][ch1] * xCorrMatrix[ch2][ch2] );
     193             : 
     194     1057652 :             if ( tmp > 0.f )
     195             :             {
     196     1026725 :                 xCorrMatrix[ch1][ch2] /= tmp;
     197             :             }
     198             :             else
     199             :             {
     200       30927 :                 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      100468 :     return;
     210             : }
     211             : 
     212             : 
     213             : /*-----------------------------------------------------------------*
     214             :  * getBestCorrelation()
     215             :  *
     216             :  * searches for the best correlated channel pair
     217             :  *------------------------------------------------------------------*/
     218             : 
     219       96286 : 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       96286 :     *_ch1 = -1;
     229       96286 :     *_ch2 = -1;
     230       96286 :     *max_corr = 0.f;
     231             : 
     232      640090 :     for ( ch1 = 0; ch1 < ( hMCT->nchan_out_woLFE ); ch1++ )
     233             :     {
     234     1984954 :         for ( ch2 = ch1 + 1; ch2 < ( hMCT->nchan_out_woLFE ); ch2++ )
     235             :         {
     236     1441150 :             if ( fabsf( *max_corr ) < fabsf( xCorrMatrix[ch1][ch2] ) )
     237             :             {
     238      198940 :                 *max_corr = xCorrMatrix[ch1][ch2];
     239             : 
     240      198940 :                 *_ch1 = ch1;
     241      198940 :                 *_ch2 = ch2;
     242             :             }
     243             :         }
     244             :     }
     245             : 
     246       96286 :     return;
     247             : }
     248             : 
     249             : 
     250             : /*----------------------------------------------------------------------*
     251             :  * getBlockValues()
     252             :  * stereo processing for the channels of current block
     253             :  *----------------------------------------------------------------------*/
     254             : 
     255       97008 : 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       97008 :     hBlock->isActive = 1;
     273             : 
     274             :     /* map vectors to current block channels */
     275      291024 :     for ( n = 0; n < 2; n++ )
     276             :     {
     277      194016 :         p_mdst_spectrum[0][n] = mdst_spectrum[ch1][n];
     278      194016 :         p_mdst_spectrum[1][n] = mdst_spectrum[ch2][n];
     279      194016 :         p_inv_spectrum[0][n] = inv_spectrum[ch1][n];
     280      194016 :         p_inv_spectrum[1][n] = inv_spectrum[ch2][n];
     281      194016 :         p_inv_mdst_spectrum[0][n] = inv_mdst_spectrum[ch1][n];
     282      194016 :         p_inv_mdst_spectrum[1][n] = inv_mdst_spectrum[ch2][n];
     283             :     }
     284       97008 :     p_st[0] = sts[ch1];
     285       97008 :     p_st[1] = sts[ch2];
     286             : 
     287       97008 :     stereo_coder_tcx( hBlock->hStereoMdct, p_st, hBlock->mask, p_mdst_spectrum, p_inv_spectrum, p_inv_mdst_spectrum, 1 );
     288             : 
     289       97008 :     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        4906 :         hBlock->isActive = 0;
     292             :     }
     293             : 
     294       97008 :     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       92102 : 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      618787 :     for ( ch1 = 0; ch1 < ( hMCT->nchan_out_woLFE ); ch1++ )
     316             :     {
     317     2511266 :         for ( ch2 = ch1; ch2 < ( hMCT->nchan_out_woLFE ); ch2++ )
     318             :         {
     319     1984581 :             if ( sts[ch1]->core == sts[ch2]->core && sts[ch1]->mct_chan_mode != MCT_CHAN_MODE_IGNORE &&
     320     1932027 :                  sts[ch2]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     321             :             {
     322     1915937 :                 int16_t nSubframes = ( sts[ch1]->core == TCX_20_CORE ? 1 : NB_DIV );
     323             : 
     324     1915937 :                 if ( ch1 == _ch1 || ch2 == _ch2 || ch1 == _ch2 || ch2 == _ch1 )
     325             :                 {
     326     1883885 :                     for ( n = 0; n < nSubframes; n++ )
     327             :                     {
     328      950099 :                         xCorrMatrix[ch1][ch2] = 0; /*disable combinations with channels already processed */
     329             :                     }
     330             :                 }
     331             :             }
     332             :         }
     333             :     }
     334             : 
     335       92102 :     return;
     336             : }
     337             : 
     338             : 
     339             : /*----------------------------------------------------------*
     340             :  * channelPairToIndex()
     341             :  * get the index of each channel pair
     342             :  *----------------------------------------------------------*/
     343             : 
     344       92102 : 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       92102 :     pairIdx = 0;
     353             : 
     354      351148 :     for ( ch2 = 1; ch2 < nChannels; ch2++ )
     355             :     {
     356     1141182 :         for ( ch1 = 0; ch1 < ch2; ch1++ )
     357             :         {
     358      882136 :             if ( ch1 == chIdx1 && ch2 == chIdx2 )
     359             :             {
     360       92102 :                 return pairIdx;
     361             :             }
     362             :             else
     363             :             {
     364      790034 :                 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      100468 : 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      100468 :     float meanE = 0.f, ratio, qratio;
     387      100468 :     int16_t cnt = 0;
     388             : 
     389             :     /*Initializations*/
     390      100468 :     set_s( hMCT->lowE_ch, 0, nchan );
     391             : 
     392      100468 :     getChannelEnergies( sts, nrg, nchan );
     393             : 
     394             :     /*calculate total energy without LFE*/
     395      580177 :     for ( ch = 0; ch < nchan; ch++ )
     396             :     {
     397      479709 :         if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     398             :         {
     399      472896 :             meanE += nrg[ch];
     400      472896 :             cnt++;
     401             :         }
     402             :     }
     403             : 
     404             :     /*calculate mean energy*/
     405      100468 :     assert( cnt >= 2 );
     406      100468 :     meanE = max( meanE / cnt, EPSILON );
     407      580177 :     for ( ch = 0; ch < nchan; ch++ )
     408             :     {
     409      479709 :         if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     410             :         {
     411      472896 :             nSubframes = ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
     412      472896 :             L_subframe = sts[ch]->hTcxEnc->L_frameTCX / nSubframes;
     413             : 
     414      472896 :             if ( nrg[ch] > meanE ) /*change it to meanE if final solution*/
     415             :             {
     416      174586 :                 ratio = meanE / nrg[ch];
     417      174586 :                 hMCT->mc_global_ild[ch] = max( 1, min( SMDCT_ILD_RANGE - 1, (int16_t) ( SMDCT_ILD_RANGE * ratio + 0.5f ) ) );
     418      174586 :                 qratio = (float) hMCT->mc_global_ild[ch] / SMDCT_ILD_RANGE;
     419             :             }
     420             :             else
     421             :             {
     422      298310 :                 ratio = nrg[ch] / meanE;
     423      298310 :                 hMCT->lowE_ch[ch] = 1;
     424      298310 :                 hMCT->mc_global_ild[ch] = max( 1, min( SMDCT_ILD_RANGE - 1, (int16_t) ( SMDCT_ILD_RANGE * ratio + 0.5f ) ) );
     425      298310 :                 qratio = (float) SMDCT_ILD_RANGE / hMCT->mc_global_ild[ch];
     426             :             }
     427             : 
     428      956438 :             for ( k = 0; k < nSubframes; k++ )
     429             :             {
     430      483542 :                 v_multc( sts[ch]->hTcxEnc->spectrum[k], qratio, sts[ch]->hTcxEnc->spectrum[k], L_subframe );
     431      483542 :                 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      100468 :     return;
     443             : }
     444             : 
     445             : 
     446             : /*--------------------------------------------------------------------*
     447             :  * apply_MCT_enc()
     448             :  *
     449             :  * apply MCT algorithm to input channels
     450             :  *--------------------------------------------------------------------*/
     451             : 
     452      100939 : 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      100939 :     int16_t count_active_ch = 0;
     472             : 
     473      100939 :     push_wmops( "mct_core_enc_mct" );
     474             : 
     475      100939 :     forceKeepTree = 1;
     476      100939 :     inactiveBlockDetected = 0;
     477      100939 :     set_s( cpEle, 0, MCT_MAX_CHANNELS );
     478             : 
     479             :     /*Determine active channels*/
     480      582726 :     for ( ch = 0; ch < nchan; ch++ )
     481             :     {
     482      481787 :         if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     483             :         {
     484      473222 :             count_active_ch++;
     485             :         }
     486             :         else
     487             :         {
     488        8565 :             hMCT->mc_global_ild[ch] = 0;
     489             :         }
     490             :     }
     491             : 
     492             :     /*there should be at least one cp*/
     493      100939 :     if ( count_active_ch >= CPE_CHANNELS )
     494             :     {
     495             :         /*Normalize energies with global ILD*/
     496      100468 :         getGlobalILD( sts, hMCT, mdst_spectrum, nchan );
     497             : #ifndef DEBUG_FORCE_MCT_CP
     498      100468 :         getCorrelationMatrix( sts, hMCT, xCorrMatrix );
     499             : 
     500             :         /*check if previous tree should be kept*/
     501      100468 :         sumCorrDiff = 0.0f;
     502      100468 :         thr = 0.15f * (float) ( count_active_ch ) * ( count_active_ch - 1 ) / 2.0f;
     503      479709 :         for ( ch2 = 1; ch2 < nchan; ch2++ )
     504             :         {
     505     1436893 :             for ( ch1 = 0; ch1 < ch2; ch1++ )
     506             :             {
     507     1057652 :                 if ( sts[ch1]->mct_chan_mode != MCT_CHAN_MODE_IGNORE &&
     508     1055622 :                      sts[ch2]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     509             :                 {
     510     1026725 :                     sumCorrDiff += fabsf( hMCT->lastxCorrMatrix[ch1][ch2] - xCorrMatrix[ch1][ch2] );
     511             :                 }
     512             :             }
     513             :         }
     514             : 
     515      100468 :         if ( sumCorrDiff > thr )
     516             :         {
     517       40758 :             forceKeepTree = 0;
     518             :         }
     519             : 
     520             :         /* check if keepTree is applied on unallowed blocks (e.g. channel pairs with different cores) */
     521      100468 :         if ( forceKeepTree )
     522             :         {
     523       59710 :             if ( !hMCT->currBlockDataCnt )
     524             :             {
     525       22670 :                 forceKeepTree = 0;
     526             :             }
     527             :             else
     528             :             {
     529      102366 :                 for ( pair = 0; pair < hMCT->currBlockDataCnt; pair++ )
     530             :                 {
     531       65326 :                     if ( xCorrMatrix[hMCT->hBlockData[pair]->ch1][hMCT->hBlockData[pair]->ch2] == 0.0f )
     532             :                     {
     533         127 :                         forceKeepTree = 0;
     534             :                     }
     535             :                 }
     536             :             }
     537             :         }
     538             : 
     539             :         /*save initial correlation matrix for next frame*/
     540      580177 :         for ( ch1 = 0; ch1 < nchan; ch1++ )
     541             :         {
     542     2017070 :             for ( ch2 = ch1; ch2 < nchan; ch2++ )
     543             :             {
     544     1537361 :                 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      100468 :         currBlockDataCnt = 0;
     553      197379 :         while ( currBlockDataCnt < hMCT->nchan_out_woLFE )
     554             :         {
     555             :             /* find best fitting channel pair: */
     556      197379 :             ch1 = -1;
     557      197379 :             ch2 = -1;
     558      197379 :             max_corr = 0.f;
     559             : 
     560      197379 :             if ( !forceKeepTree )
     561             :             {
     562      101093 :                 getNextBestCorrelation( xCorrMatrix, &ch1, &ch2, &max_corr, inactiveBlockDetected, nchan );
     563             :             }
     564             :             else
     565             :             {
     566       96286 :                 getBestCorrelation( hMCT, &tmp_ch1, &tmp_ch2, &tmp_max_corr, xCorrMatrix );
     567             : 
     568       96286 :                 if ( currBlockDataCnt == hMCT->currBlockDataCnt )
     569             :                 {
     570       31380 :                     break;
     571             :                 }
     572             :                 else
     573             :                 {
     574       64906 :                     ch1 = hMCT->hBlockData[currBlockDataCnt]->ch1;
     575       64906 :                     ch2 = hMCT->hBlockData[currBlockDataCnt]->ch2;
     576             : 
     577             :                     /*don't allow forcing of channel-pair if their correlation is under the  threshold*/
     578       64906 :                     max_corr = xCorrMatrix[ch1][ch2];
     579       64906 :                     if ( fabsf( max_corr ) <= 0.3f )
     580             :                     {
     581        5007 :                         ch1 = tmp_ch1;
     582        5007 :                         ch2 = tmp_ch2;
     583        5007 :                         max_corr = tmp_max_corr;
     584        5007 :                         forceKeepTree = 0;
     585             :                     }
     586             :                 }
     587             :             }
     588             : 
     589      165999 :             if ( ( fabsf( max_corr ) > DEFAULT_CORR_THRES && !hMCT->hbr_mct ) || ( fabsf( max_corr ) > SPAR_CORR_THRES && hMCT->hbr_mct ) )
     590             :             {
     591       97008 :                 if ( !forceKeepTree )
     592             :                 {
     593             :                     /*save channel pair*/
     594       37126 :                     hMCT->hBlockData[currBlockDataCnt]->ch1 = ch1;
     595       37126 :                     hMCT->hBlockData[currBlockDataCnt]->ch2 = ch2;
     596             :                 }
     597             : 
     598             :                 /* calculate all related values: */
     599       97008 :                 assert( sts[ch1]->mct_chan_mode != MCT_CHAN_MODE_IGNORE && sts[ch2]->mct_chan_mode != MCT_CHAN_MODE_IGNORE );
     600             : 
     601       97008 :                 getBlockValues( sts, ch1, ch2, hMCT->hBlockData[currBlockDataCnt], mdst_spectrum, inv_spectrum, inv_mdst_spectrum );
     602             : 
     603       97008 :                 if ( hMCT->hBlockData[currBlockDataCnt]->isActive == 0 )
     604             :                 {
     605        4906 :                     inactiveBlockDetected++;
     606        4906 :                     if ( inactiveBlockDetected > hMCT->nchan_out_woLFE / 2 )
     607             :                     {
     608          97 :                         break;
     609             :                     }
     610        4809 :                     forceKeepTree = 0;
     611             : 
     612        4809 :                     continue; /* skip inactive blocks where stereo mode is dual-mono */
     613             :                 }
     614             : 
     615       92102 :                 updateCorrelationMatrix( sts, hMCT, ch1, ch2, xCorrMatrix );
     616       92102 :                 cpEle[ch1] = 1;
     617       92102 :                 cpEle[ch2] = 1;
     618             : 
     619       92102 :                 currBlockDataCnt++;
     620             :             }
     621             :             else
     622             :             {
     623             :                 break;
     624             :             }
     625             :         }
     626             : 
     627             :         /*save number of blocks for next frame*/
     628      100468 :         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      580177 :         for ( ch = 0; ch < nchan; ch++ )
     683             :         {
     684      479709 :             if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     685             :             {
     686      472896 :                 if ( ( !cpEle[ch] ) || hMCT->currBlockDataCnt == 0 )
     687             :                 {
     688      288692 :                     nSubframes = ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV;
     689      288692 :                     L_subframeTCX = sts[ch]->hTcxEnc->L_frameTCX / nSubframes;
     690             : 
     691      288692 :                     if ( hMCT->lowE_ch[ch] )
     692             :                     {
     693      183258 :                         qratio = (float) hMCT->mc_global_ild[ch] / SMDCT_ILD_RANGE;
     694             :                     }
     695             :                     else
     696             :                     {
     697      105434 :                         qratio = (float) SMDCT_ILD_RANGE / hMCT->mc_global_ild[ch];
     698             :                     }
     699             : 
     700      584016 :                     for ( k = 0; k < nSubframes; k++ )
     701             :                     {
     702      295324 :                         v_multc( sts[ch]->hTcxEnc->spectrum[k], qratio, sts[ch]->hTcxEnc->spectrum[k], L_subframeTCX );
     703      295324 :                         v_multc( mdst_spectrum[ch][k], qratio, mdst_spectrum[ch][k], L_subframeTCX );
     704      295324 :                         set_zero( inv_spectrum[ch][k], L_subframeTCX );
     705             :                     }
     706      288692 :                     hMCT->mc_global_ild[ch] = 0;
     707             :                 }
     708             :             }
     709             :         }
     710             :     }
     711             :     else
     712             :     {
     713         471 :         hMCT->currBlockDataCnt = 0;
     714        2549 :         for ( ch = 0; ch < nchan; ch++ )
     715             :         {
     716        2078 :             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      100939 :     pop_wmops();
     739             : 
     740      100939 :     return;
     741             : }
     742             : 
     743             : 
     744             : /*--------------------------------------------------------------------*
     745             :  * write_mct_bitstream()
     746             :  *
     747             :  * write mct metadata to bitstream
     748             :  *--------------------------------------------------------------------*/
     749             : 
     750      100939 : 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      100939 :     BSTR_ENC_HANDLE hBstr = sts[0]->hBstr;
     762             : 
     763      100939 :     nbits_start = hBstr->nb_bits_tot;
     764             : 
     765      100939 :     push_next_indice( hBstr, hMCT->currBlockDataCnt, MCT_NUM_BLOCK_DATA_BITS );
     766             : 
     767             :     /* first write core info and overlap mode for all channels */
     768      582726 :     for ( ch = 0; ch < nchan; ch++ )
     769             :     {
     770      481787 :         if ( hMCT->currBlockDataCnt && sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     771             :         {
     772      291749 :             push_next_indice( hBstr, hMCT->mc_global_ild[ch], SMDCT_GLOBAL_ILD_BITS );
     773             :         }
     774             :     }
     775             : 
     776      100939 :     if ( hMCT->currBlockDataCnt )
     777             :     {
     778      351591 :         for ( ch = 0; ch < nchan; ch++ )
     779             :         {
     780      295035 :             if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
     781             :             {
     782      291749 :                 push_next_indice( hBstr, hMCT->lowE_ch[ch], 1 );
     783             :             }
     784             :         }
     785             :     }
     786             : 
     787             :     /* Do for each stereo block */
     788      193041 :     for ( pair = hMCT->currBlockDataCnt - 1; pair >= 0; pair-- )
     789             :     {
     790       92102 :         hBlock = hMCT->hBlockData[pair];
     791             : 
     792             :         /*calculate channel pair index and write it to BS*/
     793       92102 :         channelPairIndex = channelPairToIndex( hBlock->ch1, hBlock->ch2, nchan );
     794       92102 :         push_next_indice( hBstr, channelPairIndex, hMCT->bitsChannelPairIndex );
     795             : 
     796             :         /*point to encoder states of actual channels to write block pair bits*/
     797       92102 :         p_st[0] = sts[hBlock->ch1];
     798       92102 :         p_st[1] = sts[hBlock->ch2];
     799             : 
     800             :         /*then business as usual for each block pair */
     801       92102 :         write_stereo_to_bitstream( hMCT->hBlockData[pair]->hStereoMdct, p_st, hBlock->mask, 1, hBstr );
     802             :     }
     803             : 
     804      100939 :     hMCT->nBitsMCT = hBstr->nb_bits_tot - nbits_start;
     805             : 
     806      100939 :     return;
     807             : }
     808             : 
     809             : 
     810             : /*--------------------------------------------------------------------*
     811             :  * mctStereoIGF_enc()
     812             :  *
     813             :  * IGF analysis of channels after MCT processing
     814             :  *--------------------------------------------------------------------*/
     815             : 
     816       35766 : 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       35766 :     L_subframeTCX = 0; /* to avoid compilation warning */
     837       35766 :     set_s( singleChEle, 1, hMCT->nchan_out_woLFE );
     838             : 
     839       96336 :     for ( b = 0; b < hMCT->currBlockDataCnt; b++ )
     840             :     {
     841       60570 :         ch1 = hMCT->hBlockData[b]->ch1;
     842       60570 :         ch2 = hMCT->hBlockData[b]->ch2;
     843             : 
     844       60570 :         p_ch[0] = ch1;
     845       60570 :         p_ch[1] = ch2;
     846             : 
     847       60570 :         singleChEle[hMCT->hBlockData[b]->ch1] = 0;
     848       60570 :         singleChEle[hMCT->hBlockData[b]->ch2] = 0;
     849             : 
     850             :         /* point to encoder states of actual channels to write block pair bits */
     851       60570 :         p_st[0] = sts[ch1];
     852       60570 :         p_st[1] = sts[ch2];
     853             : 
     854       60570 :         if ( ch1 > 0 )
     855             :         {
     856       37210 :             sts[ch1]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
     857             :         }
     858             : 
     859       60570 :         if ( ch2 > 0 )
     860             :         {
     861       60570 :             sts[ch2]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
     862             :         }
     863             : 
     864       60570 :         p_powerSpec[0] = powerSpec[ch1];
     865       60570 :         p_powerSpec[1] = powerSpec[ch2];
     866             : 
     867             :         /* Band-wise M/S for MDST */
     868       60570 :         nSubframes = p_st[0]->hTcxEnc->tcxMode == TCX_20 ? 1 : NB_DIV;
     869      122637 :         for ( n = 0; n < nSubframes; n++ )
     870             :         {
     871       62067 :             p_orig_spectrum[0][n] = orig_spectrum[ch1][n];
     872       62067 :             p_orig_spectrum[1][n] = orig_spectrum[ch2][n];
     873       62067 :             p_powerSpecMsInv[0][n] = powerSpecMsInv[ch1][n];
     874       62067 :             p_powerSpecMsInv[1][n] = powerSpecMsInv[ch2][n];
     875       62067 :             p_inv_spectrum[0][n] = inv_spectrum[ch1][n];
     876       62067 :             p_inv_spectrum[1][n] = inv_spectrum[ch2][n];
     877             : 
     878       62067 :             if ( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n] != hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[n] ||
     879       31153 :                  hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n] == SMDCT_BW_MS )
     880             :             {
     881       32949 :                 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       87354 :                 for ( ch = 0; ch < CPE_CHANNELS; ch++ )
     886             :                 {
     887       58236 :                     st = p_st[ch];
     888             : 
     889       58236 :                     L_subframeTCX = st->hTcxEnc->L_frameTCX / nSubframes;
     890             : 
     891       58236 :                     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       35766 :     if ( sum_s( singleChEle, ( hMCT->nchan_out_woLFE ) ) != 0 )
     899             :     {
     900      210593 :         for ( ch = 0; ch < ( hMCT->nchan_out_woLFE ); ch++ )
     901             :         {
     902      174831 :             if ( singleChEle[ch] )
     903             :             {
     904       53707 :                 st = sts[ch];
     905             : 
     906       53707 :                 if (
     907       53707 :                     st->mct_chan_mode == MCT_CHAN_MODE_IGNORE )
     908             :                 {
     909        1253 :                     continue;
     910             :                 }
     911             : 
     912       52454 :                 if ( ch > 0 )
     913             :                 {
     914       40048 :                     st->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
     915             :                 }
     916             : 
     917       52454 :                 nSubframes = st->hTcxEnc->tcxMode == TCX_20 ? 1 : NB_DIV;
     918      106448 :                 for ( n = 0; n < nSubframes; n++ )
     919             :                 {
     920       53994 :                     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       35766 :     return;
     927             : }

Generated by: LCOV version 1.14