LCOV - code coverage report
Current view: top level - lib_enc - igf_scf_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 105 140 75.0 %
Date: 2025-05-03 01:55:50 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include "options.h"
       7             : #include "cnst.h"
       8             : //#include "prot_fx.h"
       9             : #include "stat_enc.h"
      10             : #include "stat_com.h"
      11             : #include "basop_util.h"
      12             : #include "prot_fx.h"     /* Function prototypes                    */
      13             : #include "prot_fx_enc.h" /* Function prototypes                    */
      14             : 
      15             : 
      16             : /**********************************************************************/ /**
      17             : initialization of an instance of this module
      18             : **************************************************************************/
      19       35820 : void IGFSCFEncoderOpen_fx(
      20             :     IGFSCFENC_INSTANCE_HANDLE hPublicData, /* i/o: handle to public data       */
      21             :     H_IGF_INFO hIgfInfo,                   /* i  : IGF info handle             */
      22             :     const Word32 total_brate,              /* i  : total bitrate               */
      23             :     const Word16 bwidth,                   /* i  : audio bandwidth             */
      24             :     const Word16 element_mode,             /* i  : IVAS element mode           */
      25             :     const Word16 rf_mode                   /* i  : flag to signal the RF mode  */
      26             : )
      27             : {
      28             : 
      29             : 
      30       35820 :     hPublicData->ptrBitIndex = 0;
      31       35820 :     move16();
      32       35820 :     hPublicData->bitCount = 0;
      33       35820 :     move16();
      34       35820 :     hPublicData->Tsave = 0;
      35       35820 :     move16();
      36       35820 :     hPublicData->contex_saved = 0;
      37       35820 :     move16();
      38       35820 :     hPublicData->acState.low = 0;
      39       35820 :     move32();
      40       35820 :     hPublicData->acState.high = 0;
      41       35820 :     move32();
      42       35820 :     hPublicData->acState.value = 0;
      43       35820 :     move16();
      44       35820 :     set16_fx( hPublicData->prev, 0, 64 );
      45       35820 :     set16_fx( hPublicData->prevSave, 0, 64 );
      46             : 
      47       35820 :     hPublicData->scfCountLongBlock[0] = sub( hIgfInfo->grid[0].swb_offset_len, 1 );
      48       35820 :     move16();
      49       35820 :     hPublicData->scfCountLongBlock[1] = sub( hIgfInfo->grid[1].swb_offset_len, 1 );
      50       35820 :     move16();
      51       35820 :     hPublicData->scfCountLongBlock[2] = sub( hIgfInfo->grid[2].swb_offset_len, 1 );
      52       35820 :     move16();
      53             : 
      54       35820 :     hPublicData->t = 0;
      55       35820 :     move16(); /* protect against the invalid request of starting encoding with a dependent block */
      56             : 
      57       35820 :     IGFCommonFuncsIGFGetCFTables_fx( total_brate, bwidth, element_mode, rf_mode, &hPublicData->cf_se00, &hPublicData->cf_se01, &hPublicData->cf_off_se01, &hPublicData->cf_se02, &hPublicData->cf_off_se02, &hPublicData->cf_se10, &hPublicData->cf_off_se10, &hPublicData->cf_se11, &hPublicData->cf_off_se11 );
      58       35820 : }
      59             : 
      60             : 
      61        6904 : static Word16 quant_ctx(
      62             :     Word16 ctx /* i: the context value to be quantized */
      63             : )
      64             : {
      65             :     /*
      66             :       ctx ... -5 -4 -3 -2 -1 0 1 2 3 4 5 ...
      67             :     Q(ctx)... -3 -3 -3 -2 -1 0 1 2 3 3 3 ...
      68             :     */
      69             :     Word16 result;
      70             : 
      71             : 
      72        6904 :     result = s_min( abs_s( ctx ), IGF_CTX_OFFSET ); /* limit the absolute value to IGF_CTX_OFFSET */
      73        6904 :     if ( ctx < 0 )                                  /* add the sign back, if needed */
      74             :     {
      75        3264 :         result = negate( result );
      76             :     }
      77             : 
      78        6904 :     return result;
      79             : }
      80             : 
      81             : 
      82        1324 : static void arith_encode_bits(
      83             :     IGFSCFENC_INSTANCE_HANDLE hPrivateData, /* i/o: instance handle */
      84             :     Word16 *ptr,                            /* i/o: pointer to expanded bit buffer, one bit in each Word16 */
      85             :     Word16 x,                               /* i: value to encode */
      86             :     Word16 nBits                            /* i: number of bits to encode */
      87             : )
      88             : {
      89             :     Word16 i;
      90             :     Word16 bit;
      91             : 
      92             : 
      93        3972 :     FOR( i = nBits - 1; i >= 0; --i ) /* nBits > 0 */
      94             :     {
      95        2648 :         bit = s_and( shr( x, i ), 1 );
      96        5296 :         hPrivateData->ptrBitIndex = ari_encode_14bits_sign_fx( ptr,
      97        2648 :                                                                hPrivateData->ptrBitIndex,
      98             :                                                                32767, /* disable the bit count limitation */
      99             :                                                                &hPrivateData->acState_fx,
     100             :                                                                bit );
     101        2648 :         move16();
     102             :     }
     103        1324 : }
     104             : 
     105        8228 : static void arith_encode_residual(
     106             :     IGFSCFENC_INSTANCE_HANDLE hPrivateData,  /* i/o: instance handle */
     107             :     Word16 *ptr,                             /* i/o: pointer to expanded bit buffer, one bit in each Word16 */
     108             :     Word16 x,                                /* i: residual value to encode */
     109             :     const UWord16 *cumulativeFrequencyTable, /* i: cumulative frequency table to be used */
     110             :     Word16 tableOffset                       /* i: offset used to align the table */
     111             : )
     112             : {
     113             :     Word16 extra;
     114             :     Word16 extra_tmp;
     115             :     Word16 extra_safety;
     116             : 
     117             : 
     118        8228 :     x = add( x, tableOffset );
     119             : 
     120        8228 :     test();
     121        8228 :     IF( ( GE_16( x, IGF_MIN_ENC_SEPARATE ) ) && ( LE_16( x, IGF_MAX_ENC_SEPARATE ) ) )
     122             :     {
     123        8228 :         x = sub( x, IGF_MIN_ENC_SEPARATE - 1 ); /* (x - IGF_MIN_ENC_SEPARATE) + 1 */
     124             :         /* encode one of the IGF_SYMBOLS_IN_TABLE == 27 alphabet symbols using the new raw AC function */
     125       16456 :         hPrivateData->ptrBitIndex = ari_encode_14bits_ext_fx( ptr,
     126        8228 :                                                               hPrivateData->ptrBitIndex,
     127             :                                                               &hPrivateData->acState_fx,
     128             :                                                               x,
     129             :                                                               cumulativeFrequencyTable );
     130        8228 :         move16();
     131        8228 :         return;
     132             :     }
     133             : 
     134           0 :     IF( LT_16( x, IGF_MIN_ENC_SEPARATE ) )
     135             :     {
     136             :         /* send escape code 0 to indicate x <= IGF_MIN_ENC_SEPARATE - 1 */
     137           0 :         extra = sub( IGF_MIN_ENC_SEPARATE - 1, x );
     138           0 :         hPrivateData->ptrBitIndex = ari_encode_14bits_ext_fx( ptr,
     139           0 :                                                               hPrivateData->ptrBitIndex,
     140             :                                                               &hPrivateData->acState_fx,
     141             :                                                               0,
     142             :                                                               cumulativeFrequencyTable );
     143           0 :         move16();
     144             :     }
     145             :     ELSE /* x > IGF_MAX_ENC_SEPARATE */
     146             :     {
     147             :         /* send escape code (IGF_SYMBOLS_IN_TABLE - 1) to indicate x >= IGF_MAX_ENC_SEPARATE + 1 */
     148           0 :         extra = sub( x, IGF_MAX_ENC_SEPARATE + 1 );
     149           0 :         hPrivateData->ptrBitIndex = ari_encode_14bits_ext_fx( ptr,
     150           0 :                                                               hPrivateData->ptrBitIndex,
     151             :                                                               &hPrivateData->acState_fx,
     152             :                                                               IGF_SYMBOLS_IN_TABLE - 1,
     153             :                                                               cumulativeFrequencyTable );
     154           0 :         move16();
     155             :     }
     156             : 
     157             :     /* encode one of the tails of the distribution */
     158           0 :     extra_tmp = sub( extra, 15 );
     159           0 :     IF( extra_tmp < 0 )
     160             :     {
     161             :         /* encode extra with 4 bits if extra < 15 */
     162           0 :         arith_encode_bits( hPrivateData, ptr, extra, 4 );
     163             :     }
     164             :     ELSE /* extra >= 15 */
     165             :     {
     166             :         /* send escape code 15 to indicate extra >= 15 */
     167           0 :         arith_encode_bits( hPrivateData, ptr, 15, 4 );
     168             : 
     169           0 :         extra_safety = sub( extra_tmp, 63 );
     170           0 :         IF( extra_safety < 0 )
     171             :         {
     172             :             /* encode additional extra with 6 bits */
     173           0 :             arith_encode_bits( hPrivateData, ptr, extra_tmp, 6 );
     174             :         }
     175             :         ELSE
     176             :         { /* extra_tmp >= 63 */
     177             :             /* encode safety extra with 7 bits */
     178           0 :             arith_encode_bits( hPrivateData, ptr, extra_safety, 7 );
     179             :         }
     180             :     }
     181             : }
     182             : 
     183             : 
     184        1324 : static void encode_sfe_vector(
     185             :     IGFSCFENC_INSTANCE_HANDLE hPrivateData, /* i/o: instance handle                                        */
     186             :     Word16 *ptr,                            /* i  : pointer to expanded bit buffer, one bit in each short  */
     187             :     const Word16 t,                         /* i  : frame counter reset to 0 at each independent frame     */
     188             :     Word16 *prev_x,                         /* i  : previous vector                                        */
     189             :     Word16 *x,                              /* i  : current vector to encode                               */
     190             :     const Word16 length                     /* i  : number of elements to encode                           */
     191             : )
     192             : {
     193             :     /*
     194             :        f
     195             :        ^
     196             :        |  d a x
     197             :        |    c b
     198             :        |      e  --> t
     199             :     */
     200             :     Word16 f;
     201             :     Word16 pred;
     202             :     Word16 res;
     203             :     Word16 ctx;
     204             :     Word16 ctx_f;
     205             :     Word16 ctx_t;
     206             :     Word16 prev_offset;
     207             :     Word32 index1;
     208             :     Word32 index2;
     209             : 
     210             : 
     211       10876 :     FOR( f = 0; f < length; ++f )
     212             :     {
     213        9552 :         IF( t == 0 )
     214             :         {
     215        9552 :             IF( f == 0 )
     216             :             {
     217             :                 /* (t == 0) && (f == 0) */
     218             :                 /* encode one of the IGF_SYMBOLS_IN_TABLE == 27 alphabet symbols using the new raw AC function */
     219        3972 :                 hPrivateData->ptrBitIndex = ari_encode_14bits_ext_fx( ptr,
     220        1324 :                                                                       hPrivateData->ptrBitIndex,
     221             :                                                                       &hPrivateData->acState_fx,
     222        1324 :                                                                       shr( x[f], 2 ),
     223             :                                                                       (const UWord16 *) hPrivateData->cf_se00 );
     224        1324 :                 move16();
     225        1324 :                 arith_encode_bits( hPrivateData, ptr, s_and( x[f], 3 ), 2 ); /* LSBs as 2 bit raw */
     226             :             }
     227        8228 :             ELSE IF( EQ_16( f, 1 ) )
     228             :             {
     229             :                 /* (t == 0) && (f == 1) */
     230        1324 :                 res = sub( x[f], x[0] ); /* pred = b */
     231        1324 :                 arith_encode_residual( hPrivateData,
     232             :                                        ptr,
     233             :                                        res,
     234             :                                        hPrivateData->cf_se01,
     235        1324 :                                        hPrivateData->cf_off_se01 );
     236             :             }
     237             :             ELSE
     238             :             {
     239             :                 /* (t == 0) && (f >= 2) */
     240        6904 :                 prev_offset = sub( f, 1 );
     241        6904 :                 res = sub( x[f], x[prev_offset] );
     242        6904 :                 ctx = quant_ctx( sub( x[prev_offset], x[sub( prev_offset, 1 )] ) ); /* Q(b - e) */
     243             :                 /* index1 is (IGF_SYMBOLS_IN_TABLE + 1) * (CTX_OFFSET + ctx) */
     244        6904 :                 index1 = L_mac0( ( IGF_SYMBOLS_IN_TABLE + 1 ) * IGF_CTX_OFFSET, ( IGF_SYMBOLS_IN_TABLE + 1 ), ctx );
     245             :                 /* index2 is IGF_CTX_OFFSET + ctx */
     246        6904 :                 index2 = L_mac0( IGF_CTX_OFFSET, 1, ctx );
     247        6904 :                 arith_encode_residual( hPrivateData,
     248             :                                        ptr,
     249             :                                        res,
     250        6904 :                                        hPrivateData->cf_se02 + index1,
     251        6904 :                                        hPrivateData->cf_off_se02[index2] );
     252             :             }
     253             :         }
     254             :         ELSE
     255             :         {
     256             :             /* t == 1 */
     257           0 :             IF( f == 0 )
     258             :             {
     259             :                 /* (t == 1) && (f == 0) */
     260           0 :                 res = sub( x[f], prev_x[f] );
     261           0 :                 move16(); /* pred = a */
     262           0 :                 arith_encode_residual( hPrivateData,
     263             :                                        ptr,
     264             :                                        res,
     265             :                                        hPrivateData->cf_se10,
     266           0 :                                        hPrivateData->cf_off_se10 );
     267             :             }
     268             :             ELSE
     269             :             {
     270             :                 /* (t == 1) && (f >= 1) */
     271           0 :                 prev_offset = sub( f, 1 );
     272           0 :                 pred = add( prev_x[f], x[prev_offset] );
     273           0 :                 pred = sub( pred, prev_x[prev_offset] ); /* pred = a + b - c */
     274           0 :                 res = sub( x[f], pred );
     275           0 :                 ctx_f = quant_ctx( sub( prev_x[f], prev_x[prev_offset] ) );      /* Q(a - c) */
     276           0 :                 ctx_t = quant_ctx( sub( x[prev_offset], prev_x[prev_offset] ) ); /* Q(b - c) */
     277             :                 /* index1 is (IGF_SYMBOLS_IN_TABLE + 1) * IGF_CTX_COUNT * (IGF_CTX_OFFSET + ctx_t)
     278             :                    + (IGF_SYMBOLS_IN_TABLE + 1) * (IGF_CTX_OFFSET + ctx_f) */
     279           0 :                 index1 = L_mac0(
     280             :                     ( ( IGF_SYMBOLS_IN_TABLE + 1 ) * IGF_CTX_COUNT + ( IGF_SYMBOLS_IN_TABLE + 1 ) ) * IGF_CTX_OFFSET,
     281             :                     ( IGF_SYMBOLS_IN_TABLE + 1 ) * IGF_CTX_COUNT, ctx_t );
     282           0 :                 index1 = L_mac0( index1, ( IGF_SYMBOLS_IN_TABLE + 1 ), ctx_f );
     283             :                 /* index2 is IGF_CTX_COUNT * (IGF_CTX_OFFSET + ctx_t) + (IGF_CTX_OFFSET + ctx_f) */
     284           0 :                 index2 = L_mac0( ( IGF_CTX_COUNT + 1 ) * IGF_CTX_OFFSET, IGF_CTX_COUNT, ctx_t );
     285           0 :                 index2 = L_mac0( index2, 1, ctx_f );
     286           0 :                 arith_encode_residual( hPrivateData,
     287             :                                        ptr,
     288             :                                        res,
     289           0 :                                        hPrivateData->cf_se11 + index1,
     290           0 :                                        hPrivateData->cf_off_se11[index2] );
     291             :             }
     292             :         }
     293             :     }
     294        1324 : }
     295             : 
     296             : 
     297             : /**********************************************************************/ /**
     298             : resets the internal encoder memory (context memory)
     299             : **************************************************************************/
     300     1152176 : void IGFSCFEncoderReset_fx(
     301             :     IGFSCFENC_INSTANCE_HANDLE hPublicData /* i/o: handle to public data */
     302             : )
     303             : {
     304             : 
     305             : 
     306             :     /* reset of coder */
     307     1152176 :     hPublicData->t = 0;
     308     1152176 :     move16(); /* indicate that an independent block follows */
     309             :     /* we do not need to fill hPublicData->prev with zeros, because when t = 0 no previous information is used */
     310     1152176 : }
     311             : 
     312             : /**********************************************************************/ /**
     313             : main encoder function
     314             : **************************************************************************/
     315        1324 : Word16 IGFSCFEncoderEncode_fx(
     316             :     IGFSCFENC_INSTANCE_HANDLE hPublicData, /* i  : handle to public data or NULL in case there was no instance created          */
     317             :     BSTR_ENC_HANDLE hBstr,                 /* i/o: encoder bitstream handle                                                     */
     318             :     const Word16 bitCount,                 /* i  : offset to the first bit in bitbuffer which should be readed by iisArithDecoderDecode function */
     319             :     Word16 *sfe,                           /* i  : ptr to an array which contain quantized scalefactor energies                 */
     320             :     const Word16 igfGridIdx,               /* i  : igf grid index see declaration of IGF_GRID_IDX for details                   */
     321             :     const Word16 indepFlag                 /* i  : if 1 frame is independent, 0 = frame is coded with data from previous frame  */
     322             : )
     323             : {
     324             :     Word16 ptr[IGF_BITBUFSIZE]; /* temporary expanded bit buffer, one bit in each Word16 */
     325             :     Word16 i;
     326             : 
     327             : 
     328             :     /* insert data: */
     329        1324 :     hPublicData->ptrBitIndex = 0;
     330        1324 :     move16();
     331        1324 :     hPublicData->bitCount = bitCount;
     332        1324 :     move16();
     333        1324 :     ari_start_encoding_14bits_fx( &hPublicData->acState_fx ); /* start AC encoding */
     334             : 
     335             :     /* check if coder needs a reset and do it if necessary */
     336        1324 :     IF( indepFlag != 0 )
     337             :     {
     338             :         /* reset of coder */
     339        1324 :         IGFSCFEncoderReset_fx( hPublicData );
     340             :     }
     341             : 
     342        1324 :     encode_sfe_vector( hPublicData, ptr, hPublicData->t, hPublicData->prev, sfe, hPublicData->scfCountLongBlock[igfGridIdx] );
     343             : 
     344        2648 :     hPublicData->ptrBitIndex = ari_done_encoding_14bits_fx( ptr,
     345        1324 :                                                             hPublicData->ptrBitIndex,
     346             :                                                             &hPublicData->acState_fx ); /* finish AC encoding */
     347        1324 :     hPublicData->bitCount = add( hPublicData->bitCount, hPublicData->ptrBitIndex );
     348        1324 :     move16();
     349        1324 :     move16();
     350             : 
     351             :     /* advance history */
     352        1324 :     Copy( sfe, hPublicData->prev, hPublicData->scfCountLongBlock[igfGridIdx] );
     353        1324 :     hPublicData->t = add( hPublicData->t, 1 );
     354        1324 :     move16();
     355             : 
     356             :     /* copy the bits from the temporary bit buffer, if doRealEncoding is enabled */
     357        1324 :     IF( hBstr )
     358             :     {
     359       18501 :         FOR( i = 0; i < hPublicData->ptrBitIndex; ++i )
     360             :         {
     361       17839 :             push_next_indice( hBstr, ptr[i], 1 );
     362             :         }
     363             :     }
     364             : 
     365             :     /* return next bit offset in the stream */
     366        1324 :     return hPublicData->bitCount;
     367             : }
     368             : 
     369             : /**********************************************************************/ /**
     370             : for a closed loop encoder, the SCF encoder needs to memorize the context
     371             : **************************************************************************/
     372      570566 : void IGFSCFEncoderSaveContextState_fx(
     373             :     IGFSCFENC_INSTANCE_HANDLE hPublicData, /* i/o: handle to public data */
     374             :     const Word16 igfGridIdx                /* i  : igf grid index see declaration of IGF_GRID_IDX for details          */
     375             : )
     376             : {
     377      570566 :     hPublicData->Tsave = hPublicData->t;
     378      570566 :     move16();
     379      570566 :     Copy( hPublicData->prev, hPublicData->prevSave, hPublicData->scfCountLongBlock[igfGridIdx] );
     380      570566 : }
     381             : 
     382             : /**********************************************************************/ /**
     383             : for a closed loop encoder, the SCF encoder needs to memorize the context
     384             : **************************************************************************/
     385      570566 : void IGFSCFEncoderRestoreContextState_fx(
     386             :     IGFSCFENC_INSTANCE_HANDLE hPublicData, /* i/o: handle to public data */
     387             :     const Word16 igfGridIdx                /* i  : igf grid index see declaration of IGF_GRID_IDX for details          */
     388             : )
     389             : {
     390             : 
     391             : 
     392      570566 :     hPublicData->t = hPublicData->Tsave;
     393      570566 :     move16();
     394             : 
     395      570566 :     Copy( hPublicData->prevSave, hPublicData->prev, hPublicData->scfCountLongBlock[igfGridIdx] );
     396      570566 : }

Generated by: LCOV version 1.14