LCOV - code coverage report
Current view: top level - lib_dec - dec_acelp_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 181 200 90.5 %
Date: 2025-06-27 02:59:36 Functions: 3 3 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 <memory.h>
       7             : #include <assert.h>
       8             : #include "options.h"
       9             : #include "basop_util.h"
      10             : #include "prot_fx.h"
      11             : #include "rom_com.h"
      12             : #include "rom_basop_util.h"
      13             : #define _1_CODE 0x200 /*codebook excitation Q9 */
      14             : 
      15             : /*---------------------------------------------------------------------*
      16             :  * Local function prototypes
      17             :  *---------------------------------------------------------------------*/
      18             : static void D_ACELP_decode_arithtrack_fx( Word16 v[], Word32 s, Word16 p, Word16 trackstep, Word16 tracklen );
      19             : 
      20             : /*---------------------------------------------------------------------*
      21             :  * Function D_ACELP_indexing_fx()
      22             :  *
      23             :  *---------------------------------------------------------------------*/
      24             : 
      25      514781 : void D_ACELP_indexing_fx(
      26             :     Word16 code[], // Q9
      27             :     PulseConfig config,
      28             :     Word16 num_tracks,
      29             :     Word16 index[],
      30             :     Word16 *BER_detect )
      31             : {
      32             :     Word16 track, pulses, k, pulsestrack[NB_TRACK_FCB_4T];
      33             :     Word32 s;
      34             :     Word16 trackpos;
      35             :     UWord16 *idxs;
      36             :     UWord32 idxs32[4], index_n[NB_TRACK_FCB_4T];
      37             :     Word16 restpulses, wordcnt, wordcnt32;
      38             : 
      39      514781 :     assert( EQ_16( num_tracks, NB_TRACK_FCB_4T ) );
      40             : 
      41      514781 :     wordcnt = shr( add( config.bits, 15 ), 4 ); /* ceil(bits/16) */
      42             : 
      43             :     /* check if some tracks have more pulses */
      44      514781 :     restpulses = s_and( (Word16) config.nb_pulse, sub( num_tracks, 1 ) );
      45             : 
      46             :     /* cast to short */
      47      514781 :     idxs = (UWord16 *) idxs32;
      48     2167514 :     FOR( k = 0; k < wordcnt; k++ )
      49             :     {
      50     1652733 :         idxs[k] = (UWord16) index[k];
      51     1652733 :         move16();
      52             :     }
      53      514781 :     idxs[wordcnt] = 0;
      54      514781 :     move16();
      55             : 
      56             :     /*init 32bits wordcnt*/
      57      514781 :     wordcnt32 = shr( add( wordcnt, 1 ), 1 );
      58             : 
      59      514781 :     IF( restpulses )
      60             :     {
      61             :         /* check if we need to code track positions */
      62      369304 :         SWITCH( config.codetrackpos )
      63             :         {
      64       59682 :             case TRACKPOS_FREE_THREE:
      65             :                 /* Find track with less pulses */
      66       59682 :                 trackpos = extract_l( L_and( idxs[0], 3 ) );
      67       59682 :                 longshr( idxs32, 2, wordcnt32 );
      68             : 
      69             :                 /* set number of pulses per track */
      70       59682 :                 set16_fx( pulsestrack, add( shr( (Word16) config.nb_pulse, 2 ), 1 ), 4 );
      71       59682 :                 cast16();
      72       59682 :                 pulsestrack[trackpos] = sub( pulsestrack[trackpos], 1 ); /* this one has less pulses */
      73       59682 :                 move16();
      74       59682 :                 BREAK;
      75       18527 :             case TRACKPOS_FREE_ONE:
      76             :                 /* Find track with more pulses */
      77       18527 :                 trackpos = extract_l( L_and( idxs[0], 3 ) );
      78       18527 :                 longshr( idxs32, 2, wordcnt32 );
      79             : 
      80             :                 /* set number of pulses per track */
      81       18527 :                 set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
      82       18527 :                 cast16();
      83       18527 :                 pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 ); /* this one has less pulses */
      84       18527 :                 move16();
      85       18527 :                 BREAK;
      86           0 :             case TRACKPOS_FIXED_EVEN:
      87             :                 /* Pulses on even tracks */
      88           0 :                 pulsestrack[0] = shr( add( (Word16) config.nb_pulse, 1 ), 1 );
      89           0 :                 cast16();
      90           0 :                 move16();
      91           0 :                 pulsestrack[1] = 0;
      92           0 :                 move16();
      93           0 :                 pulsestrack[2] = shr( (Word16) config.nb_pulse, 1 );
      94           0 :                 cast16();
      95           0 :                 move16();
      96           0 :                 pulsestrack[3] = 0;
      97           0 :                 move16();
      98           0 :                 BREAK;
      99      222921 :             case TRACKPOS_FIXED_FIRST:
     100             :                 /* set number of pulses per track */
     101      222921 :                 set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
     102      222921 :                 cast16();
     103      666584 :                 FOR( k = 0; k < restpulses; k++ )
     104             :                 {
     105      443663 :                     pulsestrack[k] = add( pulsestrack[k], 1 );
     106      443663 :                     move16();
     107             :                 }
     108      222921 :                 BREAK;
     109       68174 :             case TRACKPOS_FIXED_TWO:
     110             :                 /* 1100, 0110, 0011, 1001 */
     111             :                 /* Find track with less pulses */
     112       68174 :                 trackpos = extract_l( L_and( idxs[0], 3 ) );
     113       68174 :                 longshr( idxs32, 2, wordcnt32 );
     114             : 
     115             :                 /* set number of pulses per track */
     116       68174 :                 set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
     117       68174 :                 cast16();
     118       68174 :                 pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 );
     119       68174 :                 move16();
     120       68174 :                 trackpos = add( trackpos, 1 );
     121       68174 :                 trackpos = s_and( trackpos, 3 );
     122       68174 :                 pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 );
     123       68174 :                 move16();
     124       68174 :                 BREAK;
     125           0 :             default:
     126           0 :                 assert( 0 );
     127             :                 BREAK;
     128             :         }
     129             :     }
     130             :     ELSE
     131             :     {
     132             :         /* set number of pulses per track */
     133      145477 :         set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
     134      145477 :         cast16();
     135             :     }
     136             : 
     137      514781 :     IF( EQ_16( config.bits, 43 ) )
     138             :     {
     139       32873 :         D_ACELP_decode_43bit_fx( idxs, code, pulsestrack );
     140             :     }
     141             :     ELSE
     142             :     {
     143      481908 :         fcb_pulse_track_joint_decode_fx( idxs, wordcnt, index_n, pulsestrack, num_tracks );
     144     1927632 :         FOR( track = ( num_tracks - 1 ); track >= 1; track-- )
     145             :         {
     146     1445724 :             pulses = pulsestrack[track];
     147     1445724 :             move16();
     148             : 
     149     1445724 :             IF( pulses )
     150             :             {
     151             :                 /* divide by number of possible states: rest is actual state and
     152             :                  * the integer part goes to next track */
     153     1431531 :                 s = index_n[track];
     154     1431531 :                 move32();
     155             :                 /* decode state to actual pulse positions on track */
     156     1431531 :                 D_ACELP_decode_arithtrack_fx( code + track, s, pulses, num_tracks, 16 );
     157             :             }
     158             :             ELSE /* track is empty */
     159             :             {
     160      241281 :                 FOR( k = track; k < ( 16 * num_tracks ); k += num_tracks )
     161             :                 {
     162      227088 :                     code[k] = 0;
     163      227088 :                     move16();
     164             :                 }
     165             :             }
     166             :         }
     167             : 
     168      481908 :         s = L_add( index_n[0], 0 );
     169      481908 :         pulses = pulsestrack[0];
     170      481908 :         move16();
     171             : 
     172             : 
     173      481908 :         IF( pulses )
     174             :         {
     175             :             /* safety check in case of bit errors */
     176      477431 :             IF( GE_64( s, pulsestostates[16][pulses - 1] ) )
     177             :             {
     178           0 :                 set16_fx( code, 0, L_SUBFR );
     179           0 :                 *BER_detect = 1;
     180           0 :                 move16();
     181           0 :                 return;
     182             :             }
     183      477431 :             D_ACELP_decode_arithtrack_fx( code, s, pulses, num_tracks, 16 );
     184             :         }
     185             :         ELSE
     186             :         { /* track is empty */
     187       76109 :             FOR( k = 0; k < imult1616( 16, num_tracks ); k += num_tracks )
     188             :             {
     189       71632 :                 code[k] = 0;
     190       71632 :                 move16();
     191             :             }
     192             :         }
     193             :     }
     194             : }
     195             : 
     196     1908962 : static void D_ACELP_decode_arithtrack_fx( Word16 v[], Word32 s, Word16 p, Word16 trackstep, Word16 tracklen )
     197             : {
     198             :     Word16 k, idx;
     199             : 
     200             :     /*initialy s was UWords32 but it seems that s is never greater then 0x80000000*/
     201             :     /*this assumption reduces complexity but if it is not true than exit*/
     202     1908962 :     assert( s >= 0 );
     203             : 
     204    32452354 :     FOR( k = (tracklen) -1; k >= 0; k-- )
     205             :     {
     206    30543392 :         idx = imult1616( k, trackstep );
     207    30543392 :         v[idx] = 0; /* default: there is no pulse here */
     208    30543392 :         move16();
     209             : 
     210    35543010 :         FOR( ; p; p-- ) /* one pulse placed, so one less left */
     211             :         {
     212    25152724 :             IF( LT_32( s, pulsestostates[k][p - 1] ) )
     213             :             {
     214    20153106 :                 BREAK;
     215             :             }
     216             : 
     217     4999618 :             s = L_sub( s, pulsestostates[k][p - 1] );
     218             : 
     219     4999618 :             IF( v[idx] != 0 ) /* there is a pulse here already = sign is known */
     220             :             {
     221      280864 :                 IF( v[idx] > 0 )
     222             :                 {
     223      138653 :                     v[idx] = add( v[idx], _1_CODE ); /* place one more pulse here */
     224      138653 :                     move16();
     225             :                 }
     226      280864 :                 IF( v[idx] <= 0 )
     227             :                 {
     228      142211 :                     v[idx] = sub( v[idx], _1_CODE ); /* place one more pulse here */
     229      142211 :                     move16();
     230             :                 }
     231             :             }
     232             :             ELSE /* this is the first pulse here -> determine sign */
     233             :             {
     234     4718754 :                 v[idx] = _1_CODE; /* place a negative pulse here */
     235     4718754 :                 move16();
     236     4718754 :                 IF( L_and( s, 0x1 ) != 0 )
     237             :                 {
     238     2364713 :                     v[idx] = negate( _1_CODE ); /* place a negative pulse here */
     239     2364713 :                     move16();
     240             :                 }
     241     4718754 :                 s = L_lshr( s, 1 );
     242             :             }
     243             :         }
     244             :     }
     245     1908962 : }
     246             : 
     247      481908 : void fcb_pulse_track_joint_decode_fx( UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, Word16 *pulse_num, Word16 track_num )
     248             : {
     249      481908 :     Word16 hi_to_low[10] = { 0, 0, 0, 3, 9, 5, 3, 1, 8, 8 };
     250             : 
     251             :     UWord32 index;
     252             :     Word32 indx_tmp;
     253             :     Word16 indx_flag, indx_flag_1;
     254             :     Word16 track, track_num1, pulse_num0, pulse_num1;
     255             :     Word32 div_tmp;
     256             :     Word16 indx_flag_2;
     257             : 
     258      481908 :     indx_flag = 0;
     259      481908 :     move16();
     260      481908 :     indx_flag_1 = 0;
     261      481908 :     move16();
     262      481908 :     indx_flag_2 = 0;
     263      481908 :     move16();
     264             : 
     265     2409540 :     FOR( track = 0; track < track_num; track++ )
     266             :     {
     267     1927632 :         indx_flag = add( indx_flag, shr( pulse_num[track], 2 ) );
     268     1927632 :         indx_flag_1 = add( indx_flag_1, shr( pulse_num[track], 1 ) );
     269     1927632 :         indx_flag_2 = add( indx_flag_2, shr( pulse_num[track], 3 ) );
     270             :     }
     271             : 
     272      481908 :     hi_to_low[4] = 1;
     273      481908 :     move16();
     274      481908 :     if ( GE_16( indx_flag, track_num ) )
     275             :     {
     276       70385 :         hi_to_low[4] = 9;
     277       70385 :         move16();
     278             :     }
     279             : 
     280      481908 :     hi_to_low[7] = 1;
     281      481908 :     move16();
     282      481908 :     if ( GE_16( indx_flag_2, 1 ) )
     283             :     {
     284          25 :         hi_to_low[7] = 9;
     285          25 :         move16();
     286             :     }
     287             : 
     288      481908 :     IF( GE_16( indx_flag_1, track_num ) )
     289             :     {
     290      311872 :         IF( GE_16( indx_flag, track_num ) )
     291             :         {
     292       70385 :             index = 0;
     293       70385 :             move32();
     294       70385 :             IF( GE_16( indx_flag_2, 1 ) )
     295             :             {
     296          25 :                 FOR( track = sub( wordcnt, 1 ); track >= 6; track-- )
     297             :                 {
     298           0 :                     index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
     299             :                 }
     300          25 :                 index_n[3] = L_add( L_lshl( idxs[5], 8 ), L_and( L_lshr( idxs[4], 8 ), 0xFF ) );
     301          25 :                 move32();
     302          25 :                 index_n[2] = L_and( L_add( L_lshl( idxs[4], 16 ), idxs[3] ), 0xFFFFFF );
     303          25 :                 move32();
     304          25 :                 index_n[1] = L_add( L_lshl( idxs[2], 8 ), L_and( L_lshr( idxs[1], 8 ), 0xFF ) );
     305          25 :                 move32();
     306          25 :                 index_n[0] = L_and( L_add( L_lshl( idxs[1], 16 ), idxs[0] ), 0xFFFFFF );
     307          25 :                 move32();
     308             :             }
     309             :             ELSE
     310             :             {
     311      145263 :                 FOR( track = sub( wordcnt, 1 ); track >= track_num; track-- )
     312             :                 {
     313       74903 :                     index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
     314             :                 }
     315      351800 :                 FOR( track = 0; track < track_num; track++ )
     316             :                 {
     317      281440 :                     index_n[track] = (UWord32) idxs[track];
     318      281440 :                     move32();
     319             :                 }
     320             :             }
     321             :         }
     322             :         ELSE
     323             :         {
     324      241487 :             index = 0;
     325      241487 :             move32();
     326      594308 :             FOR( track = ( wordcnt - 1 ); track >= 2; track-- )
     327             :             {
     328      352821 :                 index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
     329             :             }
     330             : 
     331      241487 :             index_n[3] = L_and( (Word32) idxs[1], 0xFF );
     332      241487 :             move32();
     333      241487 :             index_n[2] = L_lshr( (Word32) idxs[1], 8 );
     334      241487 :             move32();
     335      241487 :             index_n[1] = L_and( (Word32) idxs[0], 0xFF );
     336      241487 :             move32();
     337      241487 :             index_n[0] = L_lshr( (Word32) idxs[0], 8 );
     338      241487 :             move32();
     339             :         }
     340             : 
     341      311872 :         track_num1 = sub( track_num, 1 );
     342      311872 :         pulse_num1 = pulse_num[track_num1];
     343      311872 :         move16();
     344      311872 :         index = L_add( L_lshl( index, hi_to_low[pulse_num1] ), L_lshr( index_n[track_num1], low_len[pulse_num1] ) );
     345     1247488 :         FOR( track = ( track_num - 1 ); track > 0; track-- )
     346             :         {
     347      935616 :             track_num1 = sub( track, 1 );
     348      935616 :             pulse_num0 = pulse_num[track_num1];
     349      935616 :             move16();
     350      935616 :             pulse_num1 = pulse_num[track];
     351      935616 :             move16();
     352      935616 :             index = L_add( L_lshl( index, hi_to_low[pulse_num0] ), L_lshr( index_n[track_num1], low_len[pulse_num0] ) );
     353             : 
     354      935616 :             iDiv_and_mod_32( index, indx_fact[pulse_num1], &div_tmp, &indx_tmp, 0 );
     355      935616 :             index_n[track] = L_add( L_and( index_n[track], low_mask[pulse_num1] ), L_lshl( indx_tmp, low_len[pulse_num1] ) );
     356      935616 :             move32();
     357      935616 :             index = L_add( div_tmp, 0 );
     358             :         }
     359      311872 :         pulse_num1 = pulse_num[0];
     360      311872 :         move16();
     361      311872 :         index_n[0] = L_add( L_and( index_n[0], low_mask[pulse_num1] ), L_lshl( index, low_len[pulse_num1] ) );
     362      311872 :         move32();
     363             :     }
     364             :     ELSE
     365             :     {
     366      170036 :         index = 0;
     367      170036 :         move32();
     368      531862 :         FOR( track = ( wordcnt - 1 ); track >= 0; track-- )
     369             :         {
     370      361826 :             index = (UWord32) W_add( UL_lshl( index, 16 ), (UWord32) idxs[track] );
     371             :         }
     372      680144 :         FOR( track = 3; track > 0; track-- )
     373             :         {
     374      510108 :             pulse_num1 = pulse_num[track];
     375      510108 :             move16();
     376      510108 :             index_n[track] = UL_and( index, index_mask_ACELP[pulse_num1] );
     377      510108 :             move32();
     378      510108 :             index = UL_lshr( index, index_len[pulse_num1] );
     379             :         }
     380      170036 :         index_n[0] = index;
     381      170036 :         move32();
     382             :     }
     383             : 
     384      481908 :     return;
     385             : }

Generated by: LCOV version 1.14