LCOV - code coverage report
Current view: top level - lib_enc - cod2t32_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 43b7b28dcb1471ff5d355252c4b8f37ee7ecc268 Lines: 167 168 99.4 %
Date: 2025-11-02 02:02:47 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       15082 : 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             : 
      51             :     /*----------------------------------------------------------------*
      52             :      * Compute rrixix[][] needed for the codebook search.
      53             :      *----------------------------------------------------------------*/
      54             : 
      55             :     /* Init pointers to last position of rrixix[] */
      56       15082 :     p0 = &rrixix[0][NB_POS_FCB_2T - 1];
      57       15082 :     p1 = &rrixix[1][NB_POS_FCB_2T - 1];
      58             : 
      59       15082 :     ptr_h1 = h;
      60       15082 :     L_cor = L_deposit_h( 1 );
      61      497706 :     FOR( i = 0; i < NB_POS_FCB_2T; i++ )
      62             :     {
      63      482624 :         L_cor = L_mac_sat( L_cor, *ptr_h1, *ptr_h1 );
      64      482624 :         ptr_h1++;
      65      482624 :         *p1-- = extract_h( L_cor );
      66      482624 :         move16(); /*Q9 Q7*/
      67      482624 :         L_cor = L_mac_sat( L_cor, *ptr_h1, *ptr_h1 );
      68      482624 :         ptr_h1++;
      69      482624 :         *p0-- = extract_h( L_cor );
      70      482624 :         move16(); /*Q9 Q7*/
      71             :     }
      72             : 
      73       15082 :     p0 = rrixix[0];
      74       15082 :     p1 = rrixix[1];
      75             : 
      76      497706 :     FOR( i = 0; i < NB_POS_FCB_2T; i++ )
      77             :     {
      78      482624 :         *p0 = shr( *p0, 1 );
      79      482624 :         move16();
      80      482624 :         p0++;
      81      482624 :         *p1 = shr( *p1, 1 );
      82      482624 :         move16();
      83      482624 :         p1++;
      84             :     }
      85             : 
      86             :     /*------------------------------------------------------------*
      87             :      * Compute rrixiy[][] needed for the codebook search.
      88             :      *------------------------------------------------------------*/
      89             : 
      90       15082 :     pos = MSIZE - 1;
      91       15082 :     move16();
      92       15082 :     pos2 = MSIZE - 2;
      93       15082 :     move16();
      94       15082 :     ptr_hf = h + 1;
      95             : 
      96      497706 :     FOR( k = 0; k < NB_POS_FCB_2T; k++ )
      97             :     {
      98             :         /* Init pointers to last position of diagonals */
      99      482624 :         p1 = &rrixiy[pos];
     100      482624 :         p0 = &rrixiy[pos2];
     101             : 
     102      482624 :         ptr_h1 = h;
     103      482624 :         ptr_h2 = ptr_hf;
     104             : 
     105      482624 :         L_cor = L_mult( *ptr_h1++, *ptr_h2++ ); // Q(12+12+1)
     106     7963296 :         FOR( i = k; i < NB_POS_FCB_2T - 1; i++ )
     107             :         {
     108     7480672 :             *p1 = round_fx_sat( L_cor ); // Q(25-16)
     109     7480672 :             L_cor = L_mac_sat( L_cor, *ptr_h1++, *ptr_h2++ );
     110     7480672 :             *p0 = round_fx_sat( L_cor ); // Q(9)
     111     7480672 :             L_cor = L_mac_sat( L_cor, *ptr_h1++, *ptr_h2++ );
     112     7480672 :             move16();
     113     7480672 :             move16();
     114     7480672 :             p1 -= ( NB_POS_FCB_2T + 1 );
     115     7480672 :             p0 -= ( NB_POS_FCB_2T + 1 );
     116             :         }
     117             : 
     118      482624 :         *p1 = round_fx_sat( L_cor ); // Q9
     119      482624 :         pos -= NB_POS_FCB_2T;
     120      482624 :         move16();
     121      482624 :         pos2--;
     122      482624 :         ptr_hf += STEP;
     123             :     }
     124             : 
     125             :     /*----------------------------------------------------------------*
     126             :      * computing reference vector and pre-selection of polarities
     127             :      *----------------------------------------------------------------*/
     128             : 
     129       15082 :     L_tmp = L_deposit_h( dn[0] );
     130      980330 :     FOR( i = 0; i < L_SUBFR; i++ )
     131             :     {
     132             :         /* FIR high-pass filtering */
     133      965248 :         IF( i == 0 )
     134             :         {
     135       15082 :             L_tmp = L_msu( L_tmp, dn[1], 11469 /*.3f Q15*/ );
     136             :         }
     137      950166 :         ELSE IF( EQ_16( i, L_SUBFR - 1 ) )
     138             :         {
     139       15082 :             L_tmp = L_deposit_h( dn[i] );
     140       15082 :             L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ );
     141             :         }
     142             :         ELSE
     143             :         {
     144      935084 :             L_tmp = L_deposit_h( dn[i] );
     145      935084 :             L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ );
     146      935084 :             L_tmp = L_msu( L_tmp, dn[i + 1], 11469 /*.3f Q15*/ );
     147             :         }
     148             : 
     149             :         /* pre-selection of polarities */
     150      965248 :         IF( L_tmp >= 0 )
     151             :         {
     152      460915 :             pol[i] = 1;
     153      460915 :             move16();
     154      460915 :             dn_p[i] = dn[i];
     155      460915 :             move16();
     156             :         }
     157             :         ELSE
     158             :         {
     159      504333 :             pol[i] = -1;
     160      504333 :             move16();
     161      504333 :             dn_p[i] = negate( dn[i] );
     162      504333 :             move16();
     163             :         }
     164             :     }
     165             : 
     166             :     /*----------------------------------------------------------------*
     167             :      * compute denominator ( multiplied by polarity )
     168             :      *----------------------------------------------------------------*/
     169             : 
     170       15082 :     k = 0;
     171       15082 :     ii = 0;
     172       15082 :     move16();
     173       15082 :     move16();
     174      497706 :     FOR( i = 0; i < NB_POS_FCB_2T; i++ )
     175             :     {
     176      482624 :         jj = 1;
     177      482624 :         move16();
     178    15926592 :         FOR( j = 0; j < NB_POS_FCB_2T; j++ )
     179             :         {
     180    15443968 :             test();
     181    15443968 :             if ( EQ_16( s_and( pol[ii], pol[jj] ), 1 ) && EQ_16( s_or( pol[ii], pol[jj] ), -1 ) )
     182             :             {
     183     6139244 :                 rrixiy[k + j] = negate( rrixiy[k + j] );
     184     6139244 :                 move16();
     185             :             }
     186    15443968 :             jj = add( jj, 2 );
     187             :         }
     188      482624 :         ii = add( ii, 2 );
     189      482624 :         k = add( k, NB_POS_FCB_2T );
     190             :     }
     191             : 
     192             :     /*----------------------------------------------------------------*
     193             :      * search 2 pulses
     194             :      * All combinaisons are tested:
     195             :      * 32 pos x 32 pos x 2 signs = 2048 tests
     196             :      *----------------------------------------------------------------*/
     197             : 
     198       15082 :     p0 = rrixix[0];
     199       15082 :     p1 = rrixix[1];
     200       15082 :     p2 = rrixiy;
     201       15082 :     psk = -1;
     202       15082 :     move16();
     203       15082 :     alpk = 1;
     204       15082 :     move16();
     205       15082 :     ix = 0;
     206       15082 :     move16();
     207       15082 :     iy = 1;
     208       15082 :     move16();
     209             : 
     210      497706 :     FOR( i0 = 0; i0 < L_SUBFR; i0 += STEP )
     211             :     {
     212      482624 :         ps1 = dn_p[i0];
     213      482624 :         move16();
     214      482624 :         alp1 = *p0++;
     215      482624 :         move16();
     216      482624 :         pos = -1;
     217      482624 :         move16();
     218    15926592 :         FOR( i1 = 1; i1 < L_SUBFR; i1 += STEP )
     219             :         {
     220    15443968 :             ps2 = add( ps1, dn_p[i1] );
     221    15443968 :             alp2 = add_sat( alp1, add_sat( *p1++, *p2++ ) );
     222    15443968 :             sq = mult( ps2, ps2 );
     223    15443968 :             s = L_msu_sat( L_mult( alpk, sq ), psk, alp2 );
     224    15443968 :             IF( s > 0 )
     225             :             {
     226      186441 :                 psk = sq;
     227      186441 :                 move16();
     228      186441 :                 alpk = alp2;
     229      186441 :                 move16();
     230      186441 :                 pos = i1;
     231      186441 :                 move16();
     232             :             }
     233             :         }
     234      482624 :         p1 -= NB_POS_FCB_2T;
     235             : 
     236      482624 :         IF( pos >= 0 )
     237             :         {
     238       76374 :             ix = i0;
     239       76374 :             move16();
     240       76374 :             iy = pos;
     241       76374 :             move16();
     242             :         }
     243             :     }
     244             : 
     245       15082 :     i0 = shr( ix, 1 );
     246       15082 :     i1 = shr( iy, 1 );
     247             : 
     248       15082 :     sign0 = shl( pol[ix], 9 ); // Q9
     249       15082 :     sign1 = shl( pol[iy], 9 ); // Q9
     250             : 
     251             :     /*-------------------------------------------------------------------*
     252             :      * Build the codeword, the filtered codeword and index of codevector.
     253             :      *-------------------------------------------------------------------*/
     254             : 
     255       15082 :     set16_fx( code, 0, L_SUBFR );
     256             : 
     257       15082 :     code[ix] = sign0;
     258       15082 :     move16();
     259       15082 :     code[iy] = sign1;
     260       15082 :     move16();
     261             : 
     262       15082 :     index = add( shl( i0, 6 ), i1 );
     263             : 
     264             : 
     265       15082 :     if ( sign0 < 0 )
     266             :     {
     267        7615 :         index = add( index, 0x800 );
     268             :     }
     269       15082 :     if ( sign1 < 0 )
     270             :     {
     271        7593 :         index = add( index, 0x20 ); /* move16();*/
     272             :     }
     273             : 
     274       15082 :     set16_fx( y, 0, L_SUBFR );
     275             :     /* y_Q9 = sign_Q9<<3 * h_Q12 */
     276             : 
     277       15082 :     sign0 = shl( sign0, 3 );
     278       15082 :     sign1 = shl( sign1, 3 );
     279             : 
     280      489236 :     FOR( i = ix; i < L_SUBFR; i++ )
     281             :     {
     282      474154 :         y[i] = mult_r( sign0, h[i - ix] ); // Q9
     283      474154 :         move16();
     284             :     }
     285      428176 :     FOR( i = iy; i < L_SUBFR; i++ )
     286             :     {
     287      413094 :         y[i] = round_fx( L_mac( L_deposit_h( y[i] ), sign1, h[i - iy] ) ); // Q9
     288      413094 :         move16();
     289             :     }
     290             :     {
     291             :         /* write index to array of indices */
     292       15082 :         push_indice( hBstr, IND_ALG_CDBK_2T32, index, 12 );
     293             :     }
     294       15082 :     return;
     295             : }
     296             : 
     297             : 
     298             : /*----------------------------------------------------------------------------------
     299             :  * Function  acelp_1t64()
     300             :  *
     301             :  * 7 bits algebraic codebook.
     302             :  * 1 track x 64 positions per track = 64 samples.
     303             :  *
     304             :  * The pulse can have 64 possible positions and two (2) possible amplitudes: +1 or -1.
     305             :  *----------------------------------------------------------------------------------*/
     306             : 
     307         367 : void acelp_1t64_fx(
     308             :     BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle                          */
     309             :     const Word16 dn[],     /* i  : corr. between target and h[].                   Qx*/
     310             :     const Word16 h[],      /* i  : impulse response of weighted synthesis filter Q12 */
     311             :     Word16 code[],         /* o  : algebraic (fixed) codebook excitation         Q9  */
     312             :     Word16 y[],            /* o  : filtered fixed codebook excitation            Q9  */
     313             :     const Word16 L_subfr   /* i  : subframe length                                   */
     314             : )
     315             : {
     316             :     Word16 i, pos, sgn, index;
     317             :     Word32 L_tmp;
     318             : 
     319             :     /*-------------------------------------------------------------------*
     320             :      * Find position and sign of maximum impulse.
     321             :      *-------------------------------------------------------------------*/
     322             : 
     323         367 :     pos = emaximum_fx( 0, dn, L_subfr, &L_tmp );
     324             : 
     325         367 :     IF( dn[pos] < 0 )
     326             :     {
     327         191 :         sgn = -512; //-1 in Q9
     328         191 :         move16();
     329             :     }
     330             :     ELSE
     331             :     {
     332         176 :         sgn = 512; // 1 in Q9
     333         176 :         move16();
     334             :     }
     335             : 
     336             :     /*-------------------------------------------------------------------*
     337             :      * Build the codeword, the filtered codeword and index of codevector.
     338             :      *-------------------------------------------------------------------*/
     339             : 
     340         367 :     set16_fx( code, 0, L_subfr );
     341         367 :     code[pos] = sgn;
     342         367 :     move16();
     343             : 
     344         367 :     set16_fx( y, 0, L_subfr );
     345             : 
     346       16071 :     FOR( i = pos; i < L_subfr; i++ )
     347             :     {
     348       15704 :         IF( sgn > 0 )
     349             :         {
     350        7940 :             y[i] = shr_r( h[i - pos], 3 ); // Q9
     351        7940 :             move16();
     352             :         }
     353             :         ELSE
     354             :         {
     355        7764 :             y[i] = negate( shr_r( h[i - pos], 3 ) ); // Q9
     356        7764 :             move16();
     357             :         }
     358             :     }
     359             : 
     360         367 :     index = pos;
     361         367 :     move16();
     362         367 :     if ( sgn > 0 )
     363             :     {
     364         176 :         index = add( index, L_subfr );
     365             :     }
     366         367 :     IF( EQ_16( L_subfr, L_SUBFR ) )
     367             :     {
     368         367 :         push_indice( hBstr, IND_ALG_CDBK_1T64, index, 7 );
     369             :     }
     370             :     ELSE /* L_subfr == 2*L_SUBFR */
     371             :     {
     372           0 :         push_indice( hBstr, IND_ALG_CDBK_1T64, index, 8 );
     373             :     }
     374             : 
     375         367 :     return;
     376             : }

Generated by: LCOV version 1.14