LCOV - code coverage report
Current view: top level - lib_enc - cod2t32_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 167 168 99.4 %
Date: 2025-09-14 03:13:15 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h"     /* Compilation switches                   */
       6             : #include "cnst.h"        /* Common constants                       */
       7             : #include "rom_com.h"     /* Common constants                       */
       8             : #include "prot_fx.h"     /* Function prototypes                    */
       9             : #include "prot_fx_enc.h" /* Function prototypes                    */
      10             : 
      11             : /*-------------------------------------------------------------------*
      12             :  * Local Constants
      13             :  *-------------------------------------------------------------------*/
      14             : 
      15             : #define STEP  2
      16             : #define MSIZE 1024
      17             : 
      18             : /*----------------------------------------------------------------------------------
      19             :  * Function  acelp_2t32()
      20             :  *
      21             :  * 12 bits algebraic codebook.
      22             :  * 2 tracks x 32 positions per track = 64 samples.
      23             :  *
      24             :  * 12 bits --> 2 pulses in a frame of 64 samples.
      25             :  *
      26             :  * All pulses can have two (2) possible amplitudes: +1 or -1.
      27             :  * Each pulse can have 32 possible positions.
      28             :  *----------------------------------------------------------------------------------*/
      29             : 
      30       15118 : void acelp_2t32_fx(
      31             :     BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle                      */
      32             :     const Word16 dn[],     /* i  : corr. between target and h[].                 Qx*/
      33             :     const Word16 h[],      /* i  : impulse response of weighted synthesis filter Q12*/
      34             :     Word16 code[],         /* o  : algebraic (fixed) codebook excitation         Q9*/
      35             :     Word16 y[]             /* o  : filtered fixed codebook excitation            Q9*/
      36             : )
      37             : {
      38             :     Word16 i, j, k, i0, i1, ix, iy, pos, pos2, sign0, sign1, index;
      39             :     Word16 ps1, ps2, alpk, alp1, alp2;
      40             :     Word16 sq, psk;
      41             :     Word16 pol[L_SUBFR], dn_p[L_SUBFR];
      42             :     Word16 ii, jj;
      43             :     Word16 *p0, *p1, *p2;
      44             :     const Word16 *ptr_h1, *ptr_h2, *ptr_hf;
      45             : 
      46             :     Word32 s, L_cor;
      47             :     Word32 L_tmp;
      48             :     Word16 rrixix[NB_TRACK_FCB_2T][NB_POS_FCB_2T];
      49             :     Word16 rrixiy[MSIZE];
      50             : #ifndef ISSUE_1867_replace_overflow_libenc
      51             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      52             :     Flag Overflow = 0;
      53             :     move32();
      54             : #endif
      55             : #endif
      56             :     /*----------------------------------------------------------------*
      57             :      * Compute rrixix[][] needed for the codebook search.
      58             :      *----------------------------------------------------------------*/
      59             : 
      60             :     /* Init pointers to last position of rrixix[] */
      61       15118 :     p0 = &rrixix[0][NB_POS_FCB_2T - 1];
      62       15118 :     p1 = &rrixix[1][NB_POS_FCB_2T - 1];
      63             : 
      64       15118 :     ptr_h1 = h;
      65       15118 :     L_cor = L_deposit_h( 1 );
      66      498894 :     FOR( i = 0; i < NB_POS_FCB_2T; i++ )
      67             :     {
      68             : #ifdef ISSUE_1867_replace_overflow_libenc
      69      483776 :         L_cor = L_mac_sat( L_cor, *ptr_h1, *ptr_h1 );
      70             : #else
      71             :         L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow );
      72             : #endif
      73      483776 :         ptr_h1++;
      74      483776 :         *p1-- = extract_h( L_cor );
      75      483776 :         move16(); /*Q9 Q7*/
      76             : #ifdef ISSUE_1867_replace_overflow_libenc
      77      483776 :         L_cor = L_mac_sat( L_cor, *ptr_h1, *ptr_h1 );
      78             : #else
      79             :         L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow );
      80             : #endif
      81      483776 :         ptr_h1++;
      82      483776 :         *p0-- = extract_h( L_cor );
      83      483776 :         move16(); /*Q9 Q7*/
      84             :     }
      85             : 
      86       15118 :     p0 = rrixix[0];
      87       15118 :     p1 = rrixix[1];
      88             : 
      89      498894 :     FOR( i = 0; i < NB_POS_FCB_2T; i++ )
      90             :     {
      91      483776 :         *p0 = shr( *p0, 1 );
      92      483776 :         move16();
      93      483776 :         p0++;
      94      483776 :         *p1 = shr( *p1, 1 );
      95      483776 :         move16();
      96      483776 :         p1++;
      97             :     }
      98             : 
      99             :     /*------------------------------------------------------------*
     100             :      * Compute rrixiy[][] needed for the codebook search.
     101             :      *------------------------------------------------------------*/
     102             : 
     103       15118 :     pos = MSIZE - 1;
     104       15118 :     move16();
     105       15118 :     pos2 = MSIZE - 2;
     106       15118 :     move16();
     107       15118 :     ptr_hf = h + 1;
     108             : 
     109      498894 :     FOR( k = 0; k < NB_POS_FCB_2T; k++ )
     110             :     {
     111             :         /* Init pointers to last position of diagonals */
     112      483776 :         p1 = &rrixiy[pos];
     113      483776 :         p0 = &rrixiy[pos2];
     114             : 
     115      483776 :         ptr_h1 = h;
     116      483776 :         ptr_h2 = ptr_hf;
     117             : 
     118      483776 :         L_cor = L_mult( *ptr_h1++, *ptr_h2++ ); // Q(12+12+1)
     119     7982304 :         FOR( i = k; i < NB_POS_FCB_2T - 1; i++ )
     120             :         {
     121             : #ifdef ISSUE_1867_replace_overflow_libenc
     122     7498528 :             *p1 = round_fx_sat( L_cor ); // Q(25-16)
     123     7498528 :             L_cor = L_mac_sat( L_cor, *ptr_h1++, *ptr_h2++ );
     124     7498528 :             *p0 = round_fx_sat( L_cor ); // Q(9)
     125     7498528 :             L_cor = L_mac_sat( L_cor, *ptr_h1++, *ptr_h2++ );
     126             : #else
     127             :             *p1 = round_fx_o( L_cor, &Overflow ); // Q(25-16)
     128             :             L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow );
     129             :             *p0 = round_fx_o( L_cor, &Overflow ); // Q(9)
     130             :             L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow );
     131             : #endif
     132     7498528 :             move16();
     133     7498528 :             move16();
     134     7498528 :             p1 -= ( NB_POS_FCB_2T + 1 );
     135     7498528 :             p0 -= ( NB_POS_FCB_2T + 1 );
     136             :         }
     137             : 
     138             : #ifdef ISSUE_1867_replace_overflow_libenc
     139      483776 :         *p1 = round_fx_sat( L_cor ); // Q9
     140             : #else
     141             :         *p1 = round_fx_o( L_cor, &Overflow ); // Q9
     142             : #endif
     143      483776 :         pos -= NB_POS_FCB_2T;
     144      483776 :         move16();
     145      483776 :         pos2--;
     146      483776 :         ptr_hf += STEP;
     147             :     }
     148             : 
     149             :     /*----------------------------------------------------------------*
     150             :      * computing reference vector and pre-selection of polarities
     151             :      *----------------------------------------------------------------*/
     152             : 
     153       15118 :     L_tmp = L_deposit_h( dn[0] );
     154      982670 :     FOR( i = 0; i < L_SUBFR; i++ )
     155             :     {
     156             :         /* FIR high-pass filtering */
     157      967552 :         IF( i == 0 )
     158             :         {
     159       15118 :             L_tmp = L_msu( L_tmp, dn[1], 11469 /*.3f Q15*/ );
     160             :         }
     161      952434 :         ELSE IF( EQ_16( i, L_SUBFR - 1 ) )
     162             :         {
     163       15118 :             L_tmp = L_deposit_h( dn[i] );
     164       15118 :             L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ );
     165             :         }
     166             :         ELSE
     167             :         {
     168      937316 :             L_tmp = L_deposit_h( dn[i] );
     169      937316 :             L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ );
     170      937316 :             L_tmp = L_msu( L_tmp, dn[i + 1], 11469 /*.3f Q15*/ );
     171             :         }
     172             : 
     173             :         /* pre-selection of polarities */
     174      967552 :         IF( L_tmp >= 0 )
     175             :         {
     176      462385 :             pol[i] = 1;
     177      462385 :             move16();
     178      462385 :             dn_p[i] = dn[i];
     179      462385 :             move16();
     180             :         }
     181             :         ELSE
     182             :         {
     183      505167 :             pol[i] = -1;
     184      505167 :             move16();
     185      505167 :             dn_p[i] = negate( dn[i] );
     186      505167 :             move16();
     187             :         }
     188             :     }
     189             : 
     190             :     /*----------------------------------------------------------------*
     191             :      * compute denominator ( multiplied by polarity )
     192             :      *----------------------------------------------------------------*/
     193             : 
     194       15118 :     k = 0;
     195       15118 :     ii = 0;
     196       15118 :     move16();
     197       15118 :     move16();
     198      498894 :     FOR( i = 0; i < NB_POS_FCB_2T; i++ )
     199             :     {
     200      483776 :         jj = 1;
     201      483776 :         move16();
     202    15964608 :         FOR( j = 0; j < NB_POS_FCB_2T; j++ )
     203             :         {
     204    15480832 :             test();
     205    15480832 :             if ( EQ_16( s_and( pol[ii], pol[jj] ), 1 ) && EQ_16( s_or( pol[ii], pol[jj] ), -1 ) )
     206             :             {
     207     6149964 :                 rrixiy[k + j] = negate( rrixiy[k + j] );
     208     6149964 :                 move16();
     209             :             }
     210    15480832 :             jj = add( jj, 2 );
     211             :         }
     212      483776 :         ii = add( ii, 2 );
     213      483776 :         k = add( k, NB_POS_FCB_2T );
     214             :     }
     215             : 
     216             :     /*----------------------------------------------------------------*
     217             :      * search 2 pulses
     218             :      * All combinaisons are tested:
     219             :      * 32 pos x 32 pos x 2 signs = 2048 tests
     220             :      *----------------------------------------------------------------*/
     221             : 
     222       15118 :     p0 = rrixix[0];
     223       15118 :     p1 = rrixix[1];
     224       15118 :     p2 = rrixiy;
     225       15118 :     psk = -1;
     226       15118 :     move16();
     227       15118 :     alpk = 1;
     228       15118 :     move16();
     229       15118 :     ix = 0;
     230       15118 :     move16();
     231       15118 :     iy = 1;
     232       15118 :     move16();
     233             : 
     234      498894 :     FOR( i0 = 0; i0 < L_SUBFR; i0 += STEP )
     235             :     {
     236      483776 :         ps1 = dn_p[i0];
     237      483776 :         move16();
     238      483776 :         alp1 = *p0++;
     239      483776 :         move16();
     240      483776 :         pos = -1;
     241      483776 :         move16();
     242    15964608 :         FOR( i1 = 1; i1 < L_SUBFR; i1 += STEP )
     243             :         {
     244    15480832 :             ps2 = add( ps1, dn_p[i1] );
     245             : #ifdef ISSUE_1867_replace_overflow_libenc
     246    15480832 :             alp2 = add_sat( alp1, add_sat( *p1++, *p2++ ) );
     247    15480832 :             sq = mult( ps2, ps2 );
     248    15480832 :             s = L_msu_sat( L_mult( alpk, sq ), psk, alp2 );
     249             : #else
     250             :             alp2 = add_o( alp1, add_o( *p1++, *p2++, &Overflow ), &Overflow );
     251             :             sq = mult( ps2, ps2 );
     252             :             s = L_msu_o( L_mult( alpk, sq ), psk, alp2, &Overflow );
     253             : #endif
     254    15480832 :             IF( s > 0 )
     255             :             {
     256      186802 :                 psk = sq;
     257      186802 :                 move16();
     258      186802 :                 alpk = alp2;
     259      186802 :                 move16();
     260      186802 :                 pos = i1;
     261      186802 :                 move16();
     262             :             }
     263             :         }
     264      483776 :         p1 -= NB_POS_FCB_2T;
     265             : 
     266      483776 :         IF( pos >= 0 )
     267             :         {
     268       76471 :             ix = i0;
     269       76471 :             move16();
     270       76471 :             iy = pos;
     271       76471 :             move16();
     272             :         }
     273             :     }
     274             : 
     275       15118 :     i0 = shr( ix, 1 );
     276       15118 :     i1 = shr( iy, 1 );
     277             : 
     278       15118 :     sign0 = shl( pol[ix], 9 ); // Q9
     279       15118 :     sign1 = shl( pol[iy], 9 ); // Q9
     280             : 
     281             :     /*-------------------------------------------------------------------*
     282             :      * Build the codeword, the filtered codeword and index of codevector.
     283             :      *-------------------------------------------------------------------*/
     284             : 
     285       15118 :     set16_fx( code, 0, L_SUBFR );
     286             : 
     287       15118 :     code[ix] = sign0;
     288       15118 :     move16();
     289       15118 :     code[iy] = sign1;
     290       15118 :     move16();
     291             : 
     292       15118 :     index = add( shl( i0, 6 ), i1 );
     293             : 
     294             : 
     295       15118 :     if ( sign0 < 0 )
     296             :     {
     297        7592 :         index = add( index, 0x800 );
     298             :     }
     299       15118 :     if ( sign1 < 0 )
     300             :     {
     301        7629 :         index = add( index, 0x20 ); /* move16();*/
     302             :     }
     303             : 
     304       15118 :     set16_fx( y, 0, L_SUBFR );
     305             :     /* y_Q9 = sign_Q9<<3 * h_Q12 */
     306             : 
     307       15118 :     sign0 = shl( sign0, 3 );
     308       15118 :     sign1 = shl( sign1, 3 );
     309             : 
     310      491018 :     FOR( i = ix; i < L_SUBFR; i++ )
     311             :     {
     312      475900 :         y[i] = mult_r( sign0, h[i - ix] ); // Q9
     313      475900 :         move16();
     314             :     }
     315      428814 :     FOR( i = iy; i < L_SUBFR; i++ )
     316             :     {
     317      413696 :         y[i] = round_fx( L_mac( L_deposit_h( y[i] ), sign1, h[i - iy] ) ); // Q9
     318      413696 :         move16();
     319             :     }
     320             :     {
     321             :         /* write index to array of indices */
     322       15118 :         push_indice( hBstr, IND_ALG_CDBK_2T32, index, 12 );
     323             :     }
     324       15118 :     return;
     325             : }
     326             : /*----------------------------------------------------------------------------------
     327             :  * Function  acelp_1t64()
     328             :  *
     329             :  * 7 bits algebraic codebook.
     330             :  * 1 track x 64 positions per track = 64 samples.
     331             :  *
     332             :  * The pulse can have 64 possible positions and two (2) possible amplitudes: +1 or -1.
     333             :  *----------------------------------------------------------------------------------*/
     334             : 
     335         367 : void acelp_1t64_fx(
     336             :     BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle                      */
     337             :     const Word16 dn[],     /* i  : corr. between target and h[].                 Qx*/
     338             :     const Word16 h[],      /* i  : impulse response of weighted synthesis filter Q12 */
     339             :     Word16 code[],         /* o  : algebraic (fixed) codebook excitation       Q9  */
     340             :     Word16 y[],            /* o  : filtered fixed codebook excitation          Q9  */
     341             :     const Word16 L_subfr   /* i  : subframe length                               */
     342             : )
     343             : {
     344             :     Word16 i, pos, sgn, index;
     345             :     Word32 L_tmp;
     346             :     /*-------------------------------------------------------------------*
     347             :      * Find position and sign of maximum impulse.
     348             :      *-------------------------------------------------------------------*/
     349         367 :     pos = emaximum_fx( 0, dn, L_subfr, &L_tmp );
     350             : 
     351         367 :     IF( dn[pos] < 0 )
     352             :     {
     353         191 :         sgn = -512; //-1 in Q9
     354         191 :         move16();
     355             :     }
     356             :     ELSE
     357             :     {
     358         176 :         sgn = 512; // 1 in Q9
     359         176 :         move16();
     360             :     }
     361             : 
     362             :     /*-------------------------------------------------------------------*
     363             :      * Build the codeword, the filtered codeword and index of codevector.
     364             :      *-------------------------------------------------------------------*/
     365             : 
     366         367 :     set16_fx( code, 0, L_subfr );
     367         367 :     code[pos] = sgn;
     368         367 :     move16();
     369             : 
     370         367 :     set16_fx( y, 0, L_subfr );
     371             : 
     372       16071 :     FOR( i = pos; i < L_subfr; i++ )
     373             :     {
     374       15704 :         IF( sgn > 0 )
     375             :         {
     376        7940 :             y[i] = shr_r( h[i - pos], 3 ); // Q9
     377        7940 :             move16();
     378             :         }
     379             :         ELSE
     380             :         {
     381        7764 :             y[i] = negate( shr_r( h[i - pos], 3 ) ); // Q9
     382        7764 :             move16();
     383             :         }
     384             :     }
     385             : 
     386         367 :     index = pos;
     387         367 :     move16();
     388         367 :     if ( sgn > 0 )
     389             :     {
     390         176 :         index = add( index, L_subfr );
     391             :     }
     392         367 :     IF( EQ_16( L_subfr, L_SUBFR ) )
     393             :     {
     394         367 :         push_indice( hBstr, IND_ALG_CDBK_1T64, index, 7 );
     395             :     }
     396             :     ELSE /* L_subfr == 2*L_SUBFR */
     397             :     {
     398           0 :         push_indice( hBstr, IND_ALG_CDBK_1T64, index, 8 );
     399             :     }
     400             : 
     401         367 :     return;
     402             : }

Generated by: LCOV version 1.14