LCOV - code coverage report
Current view: top level - lib_lc3plus - dec_lc3.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 0 215 0.0 %
Date: 2025-08-23 01:22:27 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             : *                        ETSI TS 103 634 V1.5.1                               *
       3             : *              Low Complexity Communication Codec Plus (LC3plus)              *
       4             : *                                                                             *
       5             : * Copyright licence is solely granted through ETSI Intellectual Property      *
       6             : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
       7             : * estoppel or otherwise.                                                      *
       8             : ******************************************************************************/
       9             : 
      10             : #include "functions.h"
      11             : 
      12           0 : static int Dec_LC3PLUS_Channel(LC3PLUS_Dec *decoder, int channel, int bits_per_sample, UWord8 *bs_in, void *s_out, Word16 bfi,
      13             :                            Word8 *scratchBuffer)
      14             : {
      15             :     Word16 scale;
      16             :     Word32 offset;
      17             :     Word16 fill_bits;
      18           0 :     Word16 nf_seed, gg_idx, fac_ns_idx, q_fx_exp = 0;
      19             :     Word16 bp_side, mask_side;
      20             :     Word16 tns_numfilters, lsbMode, lastnz, BW_cutoff_idx, BW_cutoff_idx_nf;
      21           0 :     Word16 zero_frame = 0;
      22             : #ifdef ENABLE_RFRAME
      23           0 :     Word16 rframe = 0;
      24             : #endif
      25             :     Word16 ltpf_idx[3];
      26           0 :     Word16 spec_inv_idx = 0;
      27             :     Counter i;
      28             : 
      29             :     /* Buffers */
      30             :     Word16 *int_scf_fx_exp, tns_order[TNS_NUMFILTERS_MAX];
      31             :     UWord8 *resBitBuf;
      32             : #ifdef ENABLE_HR_MODE
      33             :     Word32 *sqQdec;
      34             : #else
      35             :     Word16 *  sqQdec;
      36             :     Word16 *  int_scf_fx;
      37             : #endif
      38             :     Word16 *  x_fx, *indexes;
      39             :     Word16    scf_q[M];
      40             :     Word32 *  L_scf_idx;
      41             :     Word32 *  q_d_fx;
      42             :     Word8 *   currentScratch;
      43           0 :     DecSetup *h_DecSetup = decoder->channel_setup[channel];
      44             : #ifdef ENABLE_HR_MODE
      45             :     Word32 *x_fx_ip;
      46             :     Word32 *int_scf_fx_ip;
      47             :     Word32 scf_q_ip[M];
      48             : #endif
      49             : 
      50             : #ifdef DYNMEM_COUNT
      51             :     struct _dynmem
      52             :     {
      53             :         Counter i;
      54             :         Word16  scale;
      55             :         Word32  offset;
      56             :         Word16  fill_bits;
      57             :         Word16  nf_seed, gg_idx, fac_ns_idx, q_fx_exp;
      58             :         Word16  bp_side, mask_side;
      59             :         Word16  tns_numfilters, lsbMode, lastnz, BW_cutoff_idx, BW_cutoff_idx_nf;
      60             :         Word16  zero_frame;
      61             :         Word16  ltpf_idx[3];
      62             : #ifdef ENABLE_RFRAME
      63             :         Word16 rframe;
      64             : #endif
      65             :         Word16 spec_inv_idx;
      66             : 
      67             :         /* Buffers */
      68             :         Word16 *int_scf_fx_exp, tns_order[TNS_NUMFILTERS_MAX];
      69             :         UWord8 *resBitBuf;
      70             : #ifdef ENABLE_HR_MODE
      71             :         Word32 *sqQdec;
      72             : #else
      73             :         Word16 *sqQdec;
      74             : #endif
      75             :         Word16 *int_scf_fx, *x_fx, *indexes;
      76             :         Word32 *L_scf_idx;
      77             :         Word32 *q_d_fx;
      78             :         Word8 * currentScratch;
      79             :         Word16 scf_q[M];
      80             : #ifdef ENABLE_HR_MODE
      81             :         Word32 scf_q_ip[M];
      82             : #endif
      83             :     };
      84             :     Dyn_Mem_In("Dec_LC3_Channel", sizeof(struct _dynmem));
      85             : #endif
      86             : 
      87             : #ifdef DISABLE_PLC
      88             :     UNUSED(decoder->plcMeth);
      89             : #endif
      90             : 
      91             : 
      92             :     /* BUFFER INITIALISATION. Some buffers may overlap since they are not used in the whole decoding process */
      93           0 :     q_d_fx    = scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN bytes */
      94             : #ifdef ENABLE_HR_MODE
      95             :     /* allocate memory for residual bits */
      96           0 :     if (decoder->hrmode)
      97             :     {
      98           0 :         resBitBuf = scratchAlign(q_d_fx, sizeof(*q_d_fx) *
      99             :                                              decoder->frame_length);
     100           0 :         basop_memset(resBitBuf, 0, sizeof(*resBitBuf) * MAX_RESBITS_LEN);
     101             :     }
     102             :     else
     103             : #endif
     104             :     {
     105           0 :         resBitBuf = scratchAlign(q_d_fx, sizeof(*q_d_fx) *
     106             :                                  decoder->frame_length); /* Size = 2 * NPRM_RESQ = 2 * MAX_LEN bytes for
     107             :                                                             normal case and 2*MAX_RESBITS_LEN for hrmode */
     108           0 :         basop_memset(resBitBuf, 0, sizeof(*resBitBuf) * 2 * decoder->frame_length); 
     109             :     }
     110             :     
     111             : #ifdef ENABLE_HR_MODE
     112           0 :         indexes = scratchAlign(resBitBuf, sizeof(*resBitBuf) * MAX_RESBITS_LEN);
     113             : #else
     114             :         indexes = scratchAlign(resBitBuf, sizeof(*resBitBuf) * 2 * decoder->frame_length);
     115             : #endif
     116           0 :         memset(indexes, 0, sizeof(*indexes) * TNS_NUMFILTERS_MAX * MAXLAG);
     117             : 
     118             :     /* indexes Size = 2 * TNS_NUMFILTERS_MAX * MAXLAG = 32 bytes */
     119             : 
     120           0 :     L_scf_idx      = scratchAlign(indexes, sizeof(*indexes) * TNS_NUMFILTERS_MAX *
     121             :                                           MAXLAG); /* Size = 4 * SCF_MAX_PARAM = 28 bytes -> aligned to 32 bytes */
     122           0 :     sqQdec         = scratchAlign(L_scf_idx, sizeof(*L_scf_idx) * (SCF_MAX_PARAM));   /* Size = 2 * MAX_LEN bytes */
     123           0 :     int_scf_fx_exp = scratchAlign(sqQdec, sizeof(*sqQdec) * decoder->frame_length); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */
     124             : #ifndef ENABLE_HR_MODE
     125             :     int_scf_fx     = scratchAlign(int_scf_fx_exp,
     126             :                               sizeof(*int_scf_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */
     127             : #endif
     128             : #ifdef ENABLE_HR_MODE
     129           0 :     x_fx =
     130           0 :         scratchAlign(int_scf_fx_exp, sizeof(*int_scf_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * (MAX_LEN + MDCT_MEM_LEN_MAX) = 2
     131             :                                                                         * MAX_LEN + 1.25 * MAX_LEN = 3.25 * MAX_LEN */
     132             : #else
     133             :     x_fx =
     134             :         scratchAlign(q_d_fx, sizeof(*q_d_fx) * decoder->frame_length); /* Size = 2 * (MAX_LEN + MDCT_MEM_LEN_MAX) = 2
     135             :                                                                         * MAX_LEN + 1.25 * MAX_LEN = 3.25 * MAX_LEN */
     136             : #endif
     137             :     
     138             : #ifdef ENABLE_HR_MODE
     139           0 :     x_fx_ip        = scratchAlign(x_fx, sizeof(*x_fx) * (decoder->frame_length + decoder->stDec_ola_mem_fx_len));
     140           0 :     int_scf_fx_ip  = scratchAlign(x_fx_ip, sizeof(*x_fx_ip) * (decoder->frame_length + decoder->stDec_ola_mem_fx_len));
     141             :     
     142           0 :     currentScratch = scratchAlign(int_scf_fx_ip, sizeof(*int_scf_fx_ip) * 2 * MAX_BANDS_NUMBER); /* Size = 4 * MAX_LEN */
     143             : #else
     144             :     currentScratch = scratchAlign(x_fx, sizeof(*x_fx) * 4 * MAX_LEN); /* Size = 4 * MAX_LEN */
     145             : #endif
     146             : 
     147             : #ifdef DISABLE_PLC
     148             :     memset(q_d_fx, 0, decoder->frame_length * sizeof(*q_d_fx));
     149             : #endif
     150             : 
     151             : #ifdef WMOPS
     152             :     push_wmops("Decoder");
     153             : #endif
     154             : 
     155             : #ifdef ENABLE_RFRAME
     156           0 :     IF (sub(bfi, 3) == 0)
     157             :     {
     158           0 :         bfi = 2;
     159           0 :         move16();
     160           0 :         rframe = 1;
     161           0 :         move16();
     162             :     }
     163             : #endif
     164             : 
     165           0 :     if (bfi != 1)
     166             :     {
     167             : #ifdef WMOPS
     168             :         push_wmops("Dec(bfi=0)");
     169             : #endif
     170             :     }
     171             :     else
     172             :     {
     173             : #ifdef WMOPS
     174             :         push_wmops("Dec(bfi=1)");
     175             : #endif
     176             :     }
     177             : 
     178             : #ifdef WMOPS
     179             :     push_wmops("Entropy dec");
     180             : #endif
     181           0 :     IF (sub(bfi, 1) != 0)
     182             :     {
     183           0 :         processDecoderEntropy_fx(bs_in, &bp_side, &mask_side, h_DecSetup->total_bits, decoder->yLen, decoder->fs_idx,
     184           0 :                                  decoder->BW_cutoff_bits, &tns_numfilters, &lsbMode, &lastnz, &bfi, tns_order,
     185           0 :                                  &fac_ns_idx, &gg_idx, &BW_cutoff_idx, ltpf_idx, L_scf_idx, decoder->frame_dms);
     186           0 :         BW_cutoff_idx_nf = BW_cutoff_idx;
     187           0 :         move16();
     188             :     }
     189             : #ifdef WMOPS
     190             :     pop_wmops(); /* Entropy dec */
     191             : #endif
     192             : 
     193             : #ifdef WMOPS
     194             :     push_wmops("Ari dec");
     195             : #endif
     196           0 :     IF (sub(bfi, 1) != 0)
     197             :     {
     198           0 :         processAriDecoder_fx(bs_in, &bp_side, &mask_side, h_DecSetup->total_bits, decoder->yLen, decoder->fs_idx,
     199           0 :                              h_DecSetup->enable_lpc_weighting, tns_numfilters, lsbMode, lastnz, &bfi, tns_order,
     200           0 :                              fac_ns_idx, gg_idx, decoder->frame_dms,
     201           0 :                              decoder->n_pc, decoder->be_bp_left, decoder->be_bp_right, 0, &spec_inv_idx, &scale,
     202             :                              &fill_bits, sqQdec, &nf_seed, resBitBuf, indexes, &zero_frame, currentScratch
     203             : #ifdef ENABLE_HR_MODE
     204           0 :                              , decoder->hrmode
     205             : #endif
     206             :         );
     207             :         
     208             : #ifdef ENABLE_RFRAME
     209           0 :         test();test();
     210           0 :         IF (sub(rframe, 1) == 0 && zero_frame == 0 && sub(bfi, 1) != 0)
     211             :         {
     212           0 :             bfi = 2;
     213           0 :             move16();
     214           0 :             Word16 max_bw_stopband = BW_cutoff_bin_all[BW_cutoff_idx];
     215           0 :             SWITCH (decoder->frame_dms)
     216             :             {
     217           0 :             case 25:
     218           0 :                 max_bw_stopband  = shr_pos(max_bw_stopband, 2);
     219           0 :                 BREAK;
     220           0 :             case 50:
     221           0 :                 max_bw_stopband  = shr_pos(max_bw_stopband, 1);
     222           0 :                 BREAK;
     223           0 :             case 75:
     224           0 :                 max_bw_stopband = add(shr_pos(max_bw_stopband, 2), add(shr_pos(max_bw_stopband, 2), shr_pos(max_bw_stopband, 2)));
     225           0 :                 BREAK;
     226           0 :             case 100:
     227           0 :                 BREAK;
     228             :             }
     229             :             
     230           0 :             spec_inv_idx = s_max(lastnz, max_bw_stopband);
     231           0 :             move16();
     232             :         }
     233             : #endif
     234             :         
     235           0 :         IF (bfi == 0)
     236             :         {
     237           0 :             processAriDecoderScaling_fx(sqQdec, decoder->yLen, q_d_fx, &q_fx_exp);
     238             :         }
     239             :     }
     240             : #ifdef WMOPS
     241             :     pop_wmops(); /* Ari dec */
     242             : #endif
     243             : 
     244             : #ifdef WMOPS
     245             :     push_wmops("SnsQuantScfDec");
     246             : #endif
     247           0 :     IF (sub(bfi, 1) != 0)
     248             :     {
     249             :         /* currentScratch Size = 96 bytes */
     250             : #ifdef ENABLE_HR_MODE
     251           0 :         processSnsQuantizeScfDecoder_fx(L_scf_idx, scf_q_ip, currentScratch);
     252           0 :         downshift_w32_arr(scf_q_ip, scf_q, 15, M); /* required for PLC */
     253             : #else
     254             :         processSnsQuantizeScfDecoder_fx(L_scf_idx, scf_q, currentScratch);
     255             : #endif
     256             :     }
     257             : #ifdef WMOPS
     258             :     pop_wmops();
     259             : #endif
     260             : 
     261             : #ifdef WMOPS
     262             :     push_wmops("PLC::ComputeStabFac");
     263             : #endif
     264           0 :     if (h_DecSetup->plcAd)
     265             :     {
     266           0 :         processPLCcomputeStabFac_main(scf_q, h_DecSetup->plcAd->old_scf_q, h_DecSetup->plcAd->old_old_scf_q, bfi,
     267           0 :                                       h_DecSetup->prev_bfi, h_DecSetup->prev_prev_bfi, &h_DecSetup->plcAd->stab_fac);
     268             :     }
     269             : #ifdef WMOPS
     270             :     pop_wmops();
     271             : #endif
     272             : 
     273             : #ifdef WMOPS
     274             :     push_wmops("Partial Concealment");
     275             : #endif
     276           0 :     IF (sub(bfi, 1) != 0)
     277             :     {
     278           0 :         scale = 32767;
     279           0 :         move16();
     280             : 
     281           0 :         IF (h_DecSetup->plcAd)
     282             :         {
     283           0 :             scale = h_DecSetup->plcAd->stab_fac;
     284             :         }
     285             : 
     286           0 :         processPCmain_fx(rframe, &bfi, decoder->yLen, decoder->frame_dms, h_DecSetup->q_old_res_fx,
     287           0 :                          &h_DecSetup->q_old_res_fx_exp, sqQdec, h_DecSetup->q_old_d_fx, spec_inv_idx, ltpf_idx[0],
     288           0 :                          scale, q_d_fx, &q_fx_exp, gg_idx, h_DecSetup->quantizedGainOff, &h_DecSetup->prev_gg,
     289             :                          &h_DecSetup->prev_gg_e, &BW_cutoff_idx_nf, &h_DecSetup->prev_BW_cutoff_idx_nf, fac_ns_idx,
     290             :                          &h_DecSetup->prev_fac_ns_fx, &h_DecSetup->pc_nbLostFramesInRow);
     291             :     }
     292             : #ifdef WMOPS
     293             :     pop_wmops();
     294             : #endif
     295             : 
     296           0 :     IF (sub(bfi, 1) != 0)
     297             :     {
     298             : #ifdef WMOPS
     299             :         push_wmops("Residual dec");
     300             : #endif
     301           0 :         processResidualDecoding_fx(q_d_fx, q_fx_exp, decoder->yLen, resBitBuf, fill_bits
     302             : #ifdef ENABLE_HR_MODE
     303           0 :                                    , decoder->hrmode
     304             : #endif
     305             :         );
     306             : #ifdef WMOPS
     307             :         pop_wmops();
     308             : #endif
     309             : 
     310             : #ifdef WMOPS
     311             :         push_wmops("Noisefill");
     312             : #endif
     313             :         /* currentScratch Size = 2 * MAX_LEN bytes */
     314           0 :         IF (zero_frame == 0)
     315             :         {
     316           0 :             processNoiseFilling_fx(q_d_fx, nf_seed, q_fx_exp, fac_ns_idx, BW_cutoff_idx_nf, decoder->frame_dms,
     317           0 :                                    h_DecSetup->prev_fac_ns_fx, spec_inv_idx, currentScratch
     318             : #ifdef ENABLE_HR_MODE 
     319           0 :                                    , decoder->hrmode
     320             : #endif
     321             :             );
     322             :         }
     323             : #ifdef WMOPS
     324             :         pop_wmops();
     325             : #endif
     326             : 
     327             : #ifdef WMOPS
     328             :         push_wmops("applyGlobalGain");
     329             : #endif
     330           0 :         processApplyGlobalGain_fx(q_d_fx, &q_fx_exp, decoder->yLen, gg_idx, h_DecSetup->quantizedGainOff);
     331             : #ifdef WMOPS
     332             :         pop_wmops();
     333             : #endif
     334             : 
     335             : #ifdef WMOPS
     336             :         push_wmops("Tns_dec");
     337             : #endif
     338             :         /* currentScratch Size = 48 bytes */
     339           0 :         processTnsDecoder_fx(indexes, q_d_fx, decoder->yLen, tns_order, &q_fx_exp, BW_cutoff_idx, decoder->frame_dms,
     340             :                              currentScratch
     341             : #ifdef ENABLE_HR_MODE
     342           0 :                              , decoder->hrmode
     343             : #endif
     344             :         );
     345             : #ifdef WMOPS
     346             :         pop_wmops();
     347             : #endif
     348             : 
     349             : #ifdef ENABLE_HR_MODE
     350             : #ifdef WMOPS
     351             :         push_wmops("SnsInterpScfDec");
     352             : #endif
     353           0 :         processSnsInterpolateScf_fx(scf_q_ip, int_scf_fx_ip, int_scf_fx_exp, 0, decoder->bands_number, currentScratch);
     354             : 
     355             : #ifdef WMOPS
     356             :         pop_wmops();
     357             : #endif
     358             : 
     359             : #ifdef WMOPS
     360             :         push_wmops("Mdct shaping_dec");
     361             : #endif
     362           0 :         processScfScaling(int_scf_fx_exp, decoder->bands_number, &q_fx_exp);
     363             : 
     364           0 :         processMdctShaping_fx(q_d_fx, int_scf_fx_ip, int_scf_fx_exp, decoder->bands_offset, decoder->bands_number);
     365             : #ifdef WMOPS
     366             :         pop_wmops();
     367             : #endif
     368             : #else
     369             : #ifdef WMOPS
     370             :         push_wmops("SnsInterpScfDec");
     371             : #endif
     372             :         /* currentScratch Size = 128 bytes */
     373             :         processSnsInterpolateScf_fx(scf_q, int_scf_fx, int_scf_fx_exp, 0, decoder->bands_number, currentScratch);
     374             : #ifdef WMOPS
     375             :         pop_wmops();
     376             : #endif
     377             : 
     378             : #ifdef WMOPS
     379             :         push_wmops("Mdct shaping_dec");
     380             : #endif
     381             :         processScfScaling(int_scf_fx_exp, decoder->bands_number, &q_fx_exp);
     382             :         processMdctShaping_fx(q_d_fx, int_scf_fx, int_scf_fx_exp, decoder->bands_offset, decoder->bands_number);
     383             : #ifdef WMOPS
     384             :         pop_wmops();
     385             : #endif
     386             :         /* end int_scf_fx */
     387             : #endif /* ENABLE_HR_MODE */
     388             :     }
     389             :     
     390             :     /* x_fx_ip will be used to store h_DecSetup->stDec_ola_mem_fx returned by PLCmain_fx*/
     391             :     /* This will be upshifted to 32 bit overlap buffer outside of the PLCmain function */
     392             : #ifdef ENABLE_HR_MODE
     393           0 :     Word16 *plc_ola_mem = (Word16 *)x_fx_ip;
     394           0 :     IF(sub(bfi, 1) == 0)
     395             :     {
     396           0 :         FOR(i = 0; i < decoder->stDec_ola_mem_fx_len; i++)
     397             :         {
     398           0 :             plc_ola_mem[i] =  round_fx(h_DecSetup->stDec_ola_mem_fx[i]);
     399             :         }
     400             :     }
     401             : #endif
     402             : 
     403             : #ifdef WMOPS
     404             :     push_wmops("PLC::Main");
     405             : #endif
     406             :     /* currentScratch Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */
     407           0 :     processPLCmain_fx(decoder->plcMeth, &h_DecSetup->concealMethod, &h_DecSetup->nbLostFramesInRow, bfi,
     408           0 :                       h_DecSetup->prev_bfi, decoder->frame_length, decoder->la_zeroes, decoder->W_fx, x_fx,
     409             : #ifdef ENABLE_HR_MODE
     410             :                       plc_ola_mem,
     411             : #else
     412             :                       h_DecSetup->stDec_ola_mem_fx,
     413             : #endif
     414             :                       &h_DecSetup->stDec_ola_mem_fx_exp, h_DecSetup->q_old_d_fx,
     415           0 :                       &h_DecSetup->q_old_fx_exp, q_d_fx, &q_fx_exp, decoder->yLen, decoder->fs_idx,
     416           0 :                       decoder->bands_offset, decoder->bands_number, &h_DecSetup->plc_damping, h_DecSetup->ltpf_mem_pitch_int,
     417           0 :                       h_DecSetup->ltpf_mem_pitch_fr, &h_DecSetup->ns_cum_alpha, &h_DecSetup->ns_seed, h_DecSetup->plcAd,
     418           0 :                       decoder->frame_dms, currentScratch, &h_DecSetup->pc_nbLostFramesInRow
     419             : #ifdef ENABLE_HR_MODE
     420           0 :                       , decoder->hrmode
     421             : #endif
     422             :                       , h_DecSetup->rel_pitch_change
     423           0 :                       , decoder->alpha_type_2_table
     424             :                       );
     425             : #ifdef WMOPS
     426             :     pop_wmops();
     427             : #endif
     428             :     
     429             : #ifdef ENABLE_HR_MODE
     430           0 :     IF(sub(bfi, 1) == 0)
     431             :     {
     432           0 :         FOR(i = 0; i < decoder->stDec_ola_mem_fx_len; i++)
     433             :         {
     434           0 :             h_DecSetup->stDec_ola_mem_fx[i] = L_deposit_h(plc_ola_mem[i]);
     435             :         }
     436             :     }
     437             : #endif
     438             : 
     439             : #ifdef WMOPS
     440             :     push_wmops("PLC/PC::DampingScrambling");
     441             : #endif
     442           0 :     if (h_DecSetup->plcAd)
     443             :     {
     444           0 :         processPLCDampingScrambling_main_fx(
     445           0 :             bfi, h_DecSetup->concealMethod, h_DecSetup->nbLostFramesInRow, &h_DecSetup->plcAd->cum_fflcAtten,
     446           0 :             h_DecSetup->pc_nbLostFramesInRow, &h_DecSetup->ns_seed, &h_DecSetup->pc_seed,
     447           0 :             h_DecSetup->ltpf_mem_pitch_int, ltpf_idx[0], q_d_fx, &q_fx_exp, h_DecSetup->q_old_d_fx,
     448           0 :             &h_DecSetup->q_old_fx_exp, decoder->yLen, h_DecSetup->plcAd->stab_fac, decoder->frame_dms,
     449           0 :             &h_DecSetup->plcAd->cum_fading_slow, &h_DecSetup->plcAd->cum_fading_fast, spec_inv_idx
     450           0 :             , h_DecSetup->plcAd->plc_fadeout_type               
     451             :         );
     452             :     }
     453             : #ifdef WMOPS
     454             :     pop_wmops();
     455             : #endif
     456             : 
     457             : #ifdef WMOPS
     458             :     push_wmops("Imdct");
     459             : #endif
     460             :     /* currentScratch Size = 4 * MAX_LEN */
     461           0 :     ProcessingIMDCT(q_d_fx, &q_fx_exp, decoder->W_fx, h_DecSetup->stDec_ola_mem_fx, &h_DecSetup->stDec_ola_mem_fx_exp,
     462             : #ifdef ENABLE_HR_MODE
     463             :                     x_fx_ip,
     464             : #else
     465             :                     x_fx,
     466             : #endif
     467           0 :                     decoder->W_size, decoder->frame_length, decoder->stDec_ola_mem_fx_len, decoder->frame_dms,
     468           0 :                     h_DecSetup->concealMethod, bfi, h_DecSetup->prev_bfi, h_DecSetup->nbLostFramesInRow,
     469             :                     h_DecSetup->plcAd,
     470             :                     currentScratch
     471             : #ifdef ENABLE_HR_MODE
     472           0 :                     , decoder->hrmode
     473             : #endif
     474             :     );
     475             :     
     476             : #ifdef ENABLE_HR_MODE
     477           0 :         IF(sub(bfi, 1) != 0 || sub(h_DecSetup->concealMethod, LC3_CON_TEC_NS_STD) == 0 || sub(h_DecSetup->concealMethod, LC3_CON_TEC_NS_ADV) == 0 || sub(h_DecSetup->concealMethod, LC3_CON_TEC_FREQ_MUTING) == 0)
     478             :         {
     479           0 :             round_w32tow16_arr(x_fx_ip, x_fx, decoder->frame_length);
     480             :         }
     481             :         ELSE
     482             :         {
     483           0 :             FOR(i = 0; i < decoder->frame_length; i++)
     484             :             {
     485           0 :                 x_fx_ip[i] = L_deposit_h(x_fx[i]);
     486             :             }
     487             :         }
     488             : #endif /* ENABLE_HR_MODE */
     489             : 
     490             : #ifdef WMOPS
     491             :     pop_wmops();
     492             : #endif
     493             : 
     494             : #ifdef WMOPS
     495             :     push_wmops("PLC::Update");
     496             : #endif
     497             : 
     498           0 :     processPLCupdate_fx(h_DecSetup->plcAd, x_fx, q_fx_exp, h_DecSetup->concealMethod, decoder->frame_length,
     499           0 :                         decoder->fs_idx, &h_DecSetup->nbLostFramesInRow, &h_DecSetup->prev_prev_bfi,
     500             :                         &h_DecSetup->prev_bfi, bfi, scf_q, &h_DecSetup->ns_cum_alpha
     501             : #ifdef ENABLE_HR_MODE
     502           0 :                         , decoder->hrmode
     503             : #endif
     504             :                         );
     505             : #ifdef WMOPS
     506             :     pop_wmops();
     507             : #endif
     508             : 
     509             : #ifdef WMOPS
     510             :     push_wmops("LtpfDec");
     511             : #endif
     512             :     /* currentScratch Size = 0.5 * MAX_LEN + 20 bytes */
     513           0 :     process_ltpf_decoder_fx(&q_fx_exp, decoder->frame_length, decoder->ltpf_mem_x_len, decoder->fs_idx,
     514           0 :                             decoder->ltpf_mem_y_len, &h_DecSetup->ltpf_mem_e, x_fx, h_DecSetup->ltpf_mem_x, x_fx,
     515           0 :                             h_DecSetup->ltpf_mem_y, ltpf_idx[0], ltpf_idx[1], ltpf_idx[2],
     516             :                             &h_DecSetup->ltpf_mem_pitch_int, &h_DecSetup->ltpf_mem_pitch_fr, &h_DecSetup->ltpf_mem_gain,
     517           0 :                             &h_DecSetup->ltpf_mem_active, h_DecSetup->ltpf_scale_fac_idx, bfi,
     518           0 :                             h_DecSetup->concealMethod,
     519           0 :                             h_DecSetup->plc_damping, &h_DecSetup->ltpf_mem_scale_fac_idx, 
     520           0 :                             &h_DecSetup->rel_pitch_change, decoder->hrmode, decoder->frame_dms,
     521             :                             currentScratch);
     522             : #ifdef WMOPS
     523             :     pop_wmops();
     524             : #endif
     525             :     
     526             : #ifdef ENABLE_HR_MODE
     527           0 :     IF (!(decoder->hrmode))
     528             :     {
     529           0 :         FOR (i = 0; i < decoder->frame_length; i++)
     530             :         {
     531           0 :             x_fx_ip[i] = L_deposit_h(x_fx[i]);
     532             :         }
     533             :     }
     534             : #endif
     535             :     
     536             : #ifdef WMOPS
     537             :     push_wmops("Output scaling");
     538             : #endif
     539             :     {
     540           0 :         scale  = sub(sub(31 + 16, bits_per_sample), q_fx_exp);
     541           0 :         offset = L_shr_sat(32768, sub(16, scale));
     542           0 :         IF (bits_per_sample == 16)
     543             :         {
     544           0 :             scale = sub(15, q_fx_exp);
     545           0 :             FOR (i = 0; i < decoder->frame_length; i++)
     546             :             {
     547             : #ifdef ENABLE_HR_MODE
     548           0 :                 ((Word16 *)s_out)[i] = round_fx_sat(L_shr_sat(x_fx_ip[i], scale));
     549             : #else
     550             :                 ((Word16 *)s_out)[i] = round_fx_sat(L_shr_sat(L_deposit_h(x_fx[i]), scale));
     551             : #endif
     552           0 :                 move16();
     553             :             }
     554             :         }
     555             :         ELSE
     556             :         {
     557           0 :             FOR (i = 0; i < decoder->frame_length; i++)
     558             :             {
     559             : #ifdef ENABLE_HR_MODE
     560           0 :                 ((Word32 *)s_out)[i] = L_shr_sat(L_add_sat(x_fx_ip[i], offset), scale);
     561             : #else
     562             :                 ((Word32 *)s_out)[i] = L_shr_sat(L_add_sat(L_deposit_h(x_fx[i]), offset), scale);
     563             : #endif
     564           0 :                 move32();
     565             :             }
     566             :         }
     567             :     }
     568             : #ifdef WMOPS
     569             :     pop_wmops(); /* Output scaling */
     570             : #endif
     571             : 
     572             : #ifdef WMOPS
     573             :     pop_wmops();
     574             : #endif
     575             : 
     576             : #ifdef WMOPS
     577             :     pop_wmops(); /* Decoder */
     578             : #endif
     579             : 
     580             : 
     581             : #ifdef DYNMEM_COUNT
     582             :     Dyn_Mem_Out();
     583             : #endif
     584           0 :     return bfi;
     585             : }
     586             : 
     587             : /* num_bytes = 0 -> bad frame */
     588           0 : LC3PLUS_Error Dec_LC3PLUS(LC3PLUS_Dec *decoder, UWord8 *input, int num_bytes, void **output, int bits_per_sample, void *scratch,
     589             :                   int bfi_ext)
     590             : {
     591           0 :     int       ch = 0, bfi = bfi_ext;
     592           0 :     LC3PLUS_Error err = LC3PLUS_OK;
     593             :     int       fec_num_bytes;
     594             :     int       lc3_num_bytes;
     595             :     int       lc3_channel_num_bytes;
     596             :     int       channel_bfi, out_bfi;
     597             :     Word16    channel_epmr;
     598             : 
     599           0 :     if (bfi == 0)
     600             :     {
     601           0 :         bfi = !num_bytes;
     602             :     }
     603             : 
     604           0 :     if (decoder->ep_enabled)
     605             :     {
     606           0 :         decoder->combined_channel_coding = decoder->channels > 1 && num_bytes <= 160;
     607             : 
     608           0 :         if (decoder->combined_channel_coding)
     609             :         {
     610           0 :             fec_num_bytes = num_bytes;
     611             : 
     612             : #ifdef WMOPS
     613             :             push_wmops("fec_dec");
     614             : #endif
     615             : 
     616           0 :             decoder->error_report =
     617           0 :                 fec_decoder(input, fec_num_bytes, &lc3_num_bytes, &decoder->epmr, decoder->combined_channel_coding,
     618             :                             &decoder->n_pccw, &bfi, &decoder->be_bp_left, &decoder->be_bp_right, &decoder->n_pc,
     619             :                             &decoder->m_fec, scratch);
     620             : 
     621             : #ifdef WMOPS
     622             :             pop_wmops();
     623             : #endif
     624             : 
     625           0 :             for (ch = 0; ch < decoder->channels; ch++)
     626             :             {
     627           0 :                 lc3_channel_num_bytes = lc3_num_bytes / decoder->channels + (ch < (lc3_num_bytes % decoder->channels));
     628             : 
     629             : 
     630           0 :                 if (bfi != 1 && lc3_channel_num_bytes != decoder->channel_setup[ch]->last_size)
     631             :                 {
     632           0 :                     err = update_dec_bitrate(decoder, ch, lc3_channel_num_bytes);
     633             : 
     634           0 :                     if (err)
     635             :                     {
     636           0 :                         bfi = 1;
     637             :                     }
     638             :                     else
     639             :                     {
     640           0 :                         decoder->channel_setup[ch]->last_size = lc3_channel_num_bytes;
     641             :                     }
     642             :                 }
     643             : 
     644           0 :                 bfi = Dec_LC3PLUS_Channel(decoder, ch, bits_per_sample, input, output[ch], bfi, scratch);
     645           0 :                 if (input != NULL)
     646             :                 {
     647           0 :                     input += decoder->channel_setup[ch]->targetBytes;
     648             :                 }
     649             :             }
     650             :         }
     651             :         else
     652             :         {
     653           0 :             decoder->epmr = 12;
     654           0 :             out_bfi       = 0;
     655             : 
     656           0 :             for (ch = 0; ch < decoder->channels; ch++)
     657             :             {
     658           0 :                 fec_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels));
     659             : 
     660             : #ifdef WMOPS
     661             :                 push_wmops("fec_dec");
     662             : #endif
     663             : 
     664           0 :                 channel_bfi = bfi;
     665             : 
     666           0 :                 decoder->error_report =
     667           0 :                     fec_decoder(input, fec_num_bytes, &lc3_num_bytes, &channel_epmr, decoder->combined_channel_coding,
     668             :                                 &decoder->n_pccw, &channel_bfi, &decoder->be_bp_left, &decoder->be_bp_right,
     669             :                                 &decoder->n_pc, &decoder->m_fec, scratch);
     670             : 
     671             : #ifdef WMOPS
     672             :                 pop_wmops();
     673             : #endif
     674             : 
     675           0 :                 decoder->epmr = MIN(decoder->epmr, channel_epmr);
     676             : 
     677             : 
     678             : #ifdef ENABLE_PADDING
     679           0 :                 if (channel_bfi != 1)
     680             :                 {
     681             :                     Word16 padding_len, np_zero;
     682             : 
     683           0 :                     if (paddingDec_fx(input, shl(lc3_num_bytes, 3), decoder->yLen, decoder->BW_cutoff_bits,
     684           0 :                                       decoder->ep_enabled, &padding_len, &np_zero))
     685             :                     {
     686           0 :                         channel_bfi = 1;
     687             :                     }
     688             : 
     689           0 :                     if (input != NULL)
     690             :                     {
     691           0 :                         input     = input + np_zero;
     692             :                     }
     693           0 :                     decoder->n_pc = s_max(decoder->n_pc - (2 * np_zero), 0);
     694             : 
     695           0 :                     if (channel_bfi == 2)
     696             :                     {
     697           0 :                         if (decoder->be_bp_right < (8 * np_zero))
     698             :                         {
     699           0 :                             channel_bfi          = 0;
     700           0 :                             decoder->be_bp_left  = -1;
     701           0 :                             decoder->be_bp_right = -1;
     702             :                         }
     703             :                         else
     704             :                         {
     705           0 :                             decoder->be_bp_right = decoder->be_bp_right - (8 * np_zero);
     706           0 :                             decoder->be_bp_left  = s_max(decoder->be_bp_left - (8 * np_zero), 0);
     707             :                         }
     708             :                     }
     709             : 
     710           0 :                     lc3_num_bytes = lc3_num_bytes - padding_len;
     711             :                 }
     712             : #endif
     713             : 
     714           0 :                 if (channel_bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size)
     715             :                 {
     716           0 :                     err = update_dec_bitrate(decoder, ch, lc3_num_bytes);
     717           0 :                     if (err)
     718             :                     {
     719           0 :                         channel_bfi = 1;
     720             :                     }
     721             :                     else
     722             :                     {
     723           0 :                         decoder->channel_setup[ch]->last_size = lc3_num_bytes;
     724             :                     }
     725             :                 }
     726             : 
     727           0 :                 channel_bfi = Dec_LC3PLUS_Channel(decoder, ch, bits_per_sample, input, output[ch], channel_bfi, scratch);
     728             : 
     729           0 :                 out_bfi |= channel_bfi;
     730           0 :                 if (input != NULL)
     731             :                 {
     732           0 :                     input += fec_num_bytes;
     733             :                 }
     734             :             }
     735             : 
     736           0 :             bfi = out_bfi & 1;
     737             :         }
     738             :     }
     739             :     else
     740             :     {
     741           0 :         for (ch = 0; ch < decoder->channels; ch++)
     742             :         {
     743           0 :             lc3_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels));
     744             : 
     745             : #ifdef ENABLE_PADDING
     746           0 :             if (bfi != 1)
     747             :             {
     748             :                 Word16 padding_len, np_zero;
     749             : 
     750           0 :                 if (paddingDec_fx(input, shl(lc3_num_bytes, 3), decoder->yLen, decoder->BW_cutoff_bits,
     751           0 :                                   decoder->ep_enabled, &padding_len, &np_zero))
     752             :                 {
     753           0 :                     bfi = 1;
     754             :                 }
     755             : 
     756           0 :                 lc3_num_bytes = lc3_num_bytes - padding_len;
     757           0 :                 if (lc3_num_bytes < 20 || lc3_num_bytes > LC3PLUS_MAX_BYTES)
     758             :                 {
     759           0 :                     bfi = 1; /* mark frame as broken if frame sizeif below the minimum of 20 bytes */
     760             :                 }
     761             :             }
     762             : #endif
     763             : 
     764           0 :             if (bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size)
     765             :             {
     766           0 :                 err = update_dec_bitrate(decoder, ch, lc3_num_bytes);
     767           0 :                 if (err)
     768             :                 {
     769           0 :                     bfi = 1;
     770             :                 }
     771             :                 else
     772             :                 {
     773           0 :                     decoder->channel_setup[ch]->last_size = lc3_num_bytes;
     774             :                 }
     775             :             }
     776             : 
     777           0 :             bfi = Dec_LC3PLUS_Channel(decoder, ch, bits_per_sample, input, output[ch], bfi, scratch);
     778           0 :             if (input != NULL)
     779             :             {
     780           0 :                 input += decoder->channel_setup[ch]->targetBytes;
     781             :             }
     782             :         }
     783             :     }
     784             : 
     785           0 :     return bfi == 1 ? LC3PLUS_DECODE_ERROR : LC3PLUS_OK;
     786             : }

Generated by: LCOV version 1.14