Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 /*
     12  * decode.c
     13  *
     14  * This C file contains the internal decoding function.
     15  *
     16  */
     17 
     18 #include <string.h>
     19 
     20 #include "bandwidth_estimator.h"
     21 #include "codec.h"
     22 #include "entropy_coding.h"
     23 #include "pitch_estimator.h"
     24 #include "settings.h"
     25 #include "structs.h"
     26 
     27 
     28 
     29 
     30 int WebRtcIsacfix_DecodeImpl(int16_t* signal_out16,
     31                              IsacFixDecoderInstance* ISACdec_obj,
     32                              size_t* current_framesamples)
     33 {
     34   int k;
     35   int err;
     36   int16_t BWno;
     37   int len = 0;
     38 
     39   int16_t model;
     40 
     41 
     42   int16_t Vector_Word16_1[FRAMESAMPLES/2];
     43   int16_t Vector_Word16_2[FRAMESAMPLES/2];
     44 
     45   int32_t Vector_Word32_1[FRAMESAMPLES/2];
     46   int32_t Vector_Word32_2[FRAMESAMPLES/2];
     47 
     48   int16_t lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs
     49   int16_t hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs
     50   int32_t gain_lo_hiQ17[2*SUBFRAMES];
     51 
     52   int16_t PitchLags_Q7[PITCH_SUBFRAMES];
     53   int16_t PitchGains_Q12[PITCH_SUBFRAMES];
     54   int16_t AvgPitchGain_Q12;
     55 
     56   int16_t tmp_1, tmp_2;
     57   int32_t tmp32a;
     58   int16_t gainQ13;
     59 
     60 
     61   size_t frame_nb; /* counter */
     62   size_t frame_mode; /* 0 for 30ms, 1 for 60ms */
     63   static const size_t kProcessedSamples = 480; /* 480 (for both 30, 60 ms) */
     64 
     65   /* PLC */
     66   int16_t overlapWin[ 240 ];
     67 
     68   (ISACdec_obj->bitstr_obj).W_upper = 0xFFFFFFFF;
     69   (ISACdec_obj->bitstr_obj).streamval = 0;
     70   (ISACdec_obj->bitstr_obj).stream_index = 0;
     71   (ISACdec_obj->bitstr_obj).full = 1;
     72 
     73 
     74   /* decode framelength and BW estimation - not used, only for stream pointer*/
     75   err = WebRtcIsacfix_DecodeFrameLen(&ISACdec_obj->bitstr_obj, current_framesamples);
     76   if (err<0)  // error check
     77     return err;
     78 
     79   frame_mode = *current_framesamples / MAX_FRAMESAMPLES;  /* 0, or 1 */
     80 
     81   err = WebRtcIsacfix_DecodeSendBandwidth(&ISACdec_obj->bitstr_obj, &BWno);
     82   if (err<0)  // error check
     83     return err;
     84 
     85   /* one loop if it's one frame (30ms), two loops if two frames bundled together
     86    * (60ms) */
     87   for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) {
     88 
     89     /* decode & dequantize pitch parameters */
     90     err = WebRtcIsacfix_DecodePitchGain(&(ISACdec_obj->bitstr_obj), PitchGains_Q12);
     91     if (err<0)  // error check
     92       return err;
     93 
     94     err = WebRtcIsacfix_DecodePitchLag(&ISACdec_obj->bitstr_obj, PitchGains_Q12, PitchLags_Q7);
     95     if (err<0)  // error check
     96       return err;
     97 
     98     AvgPitchGain_Q12 = (int16_t)(((int32_t)PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3])>>2);
     99 
    100     /* decode & dequantize FiltCoef */
    101     err = WebRtcIsacfix_DecodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15,
    102                                   &ISACdec_obj->bitstr_obj, &model);
    103 
    104     if (err<0)  // error check
    105       return err;
    106 
    107     /* decode & dequantize spectrum */
    108     len = WebRtcIsacfix_DecodeSpec(&ISACdec_obj->bitstr_obj, Vector_Word16_1, Vector_Word16_2, AvgPitchGain_Q12);
    109     if (len < 0)  // error check
    110       return len;
    111 
    112     // Why does this need Q16 in and out? /JS
    113     WebRtcIsacfix_Spec2Time(Vector_Word16_1, Vector_Word16_2, Vector_Word32_1, Vector_Word32_2);
    114 
    115     for (k=0; k<FRAMESAMPLES/2; k++) {
    116       // Q16 -> Q9.
    117       Vector_Word16_1[k] = (int16_t)((Vector_Word32_1[k] + 64) >> 7);
    118     }
    119 
    120     /* ----  If this is recovery frame ---- */
    121     if( (ISACdec_obj->plcstr_obj).used == PLC_WAS_USED )
    122     {
    123       (ISACdec_obj->plcstr_obj).used = PLC_NOT_USED;
    124       if( (ISACdec_obj->plcstr_obj).B < 1000 )
    125       {
    126         (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 4000;
    127       }
    128 
    129       ISACdec_obj->plcstr_obj.decayCoeffPriodic = WEBRTC_SPL_WORD16_MAX;    /* DECAY_RATE is in Q15 */
    130       ISACdec_obj->plcstr_obj.decayCoeffNoise = WEBRTC_SPL_WORD16_MAX;    /* DECAY_RATE is in Q15 */
    131       ISACdec_obj->plcstr_obj.pitchCycles = 0;
    132 
    133       PitchGains_Q12[0] = (int16_t)(PitchGains_Q12[0] * 700 >> 10);
    134 
    135       /* ---- Add-overlap ---- */
    136       WebRtcSpl_GetHanningWindow( overlapWin, RECOVERY_OVERLAP );
    137       for( k = 0; k < RECOVERY_OVERLAP; k++ )
    138         Vector_Word16_1[k] = WebRtcSpl_AddSatW16(
    139             (int16_t)(ISACdec_obj->plcstr_obj.overlapLP[k] *
    140                 overlapWin[RECOVERY_OVERLAP - k - 1] >> 14),
    141             (int16_t)(Vector_Word16_1[k] * overlapWin[k] >> 14));
    142 
    143 
    144 
    145     }
    146 
    147     /* --- Store side info --- */
    148     if( frame_nb == frame_mode )
    149     {
    150       /* --- LPC info */
    151       WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).lofilt_coefQ15, &lofilt_coefQ15[(SUBFRAMES-1)*ORDERLO], ORDERLO );
    152       WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).hifilt_coefQ15, &hifilt_coefQ15[(SUBFRAMES-1)*ORDERHI], ORDERHI );
    153       (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0] = gain_lo_hiQ17[(SUBFRAMES-1) * 2];
    154       (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1] = gain_lo_hiQ17[(SUBFRAMES-1) * 2 + 1];
    155 
    156       /* --- LTP info */
    157       (ISACdec_obj->plcstr_obj).AvgPitchGain_Q12 = PitchGains_Q12[3];
    158       (ISACdec_obj->plcstr_obj).lastPitchGain_Q12 = PitchGains_Q12[3];
    159       (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = PitchLags_Q7[3];
    160 
    161       if( PitchLags_Q7[3] < 3000 )
    162         (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 += PitchLags_Q7[3];
    163 
    164       WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvIn, Vector_Word16_1, FRAMESAMPLES/2 );
    165 
    166     }
    167     /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    168 
    169     /* inverse pitch filter */
    170     WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2, &ISACdec_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 4);
    171 
    172     if( frame_nb == frame_mode )
    173     {
    174       WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvOut, &(Vector_Word16_2[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10)]), PITCH_MAX_LAG );
    175     }
    176 
    177 
    178     /* reduce gain to compensate for pitch enhancer */
    179     /* gain = 1.0f - 0.45f * AvgPitchGain; */
    180     tmp32a = AvgPitchGain_Q12 * 29;  // Q18
    181     gainQ13 = (int16_t)((262144 - tmp32a) >> 5);  // Q18 -> Q13.
    182 
    183     for (k = 0; k < FRAMESAMPLES/2; k++)
    184     {
    185       Vector_Word32_1[k] = (Vector_Word16_2[k] * gainQ13) << 3;  // Q25
    186     }
    187 
    188 
    189     /* perceptual post-filtering (using normalized lattice filter) */
    190     WebRtcIsacfix_NormLatticeFilterAr(ORDERLO, (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0,
    191                                       Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1);
    192 
    193     /* --- Store Highpass Residual --- */
    194     for (k = 0; k < FRAMESAMPLES/2; k++)
    195       Vector_Word32_1[k] = Vector_Word32_2[k] << 9;  // Q16 -> Q25
    196 
    197     for( k = 0; k < PITCH_MAX_LAG + 10; k++ )
    198       (ISACdec_obj->plcstr_obj).prevHP[k] = Vector_Word32_1[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10) + k];
    199 
    200 
    201     WebRtcIsacfix_NormLatticeFilterAr(ORDERHI, (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0,
    202                                       Vector_Word32_1, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2);
    203 
    204     /* recombine the 2 bands */
    205 
    206     /* Form the polyphase signals, and compensate for DC offset */
    207     for (k=0;k<FRAMESAMPLES/2;k++) {
    208       tmp_1 = (int16_t)WebRtcSpl_SatW32ToW16(((int32_t)Vector_Word16_1[k]+Vector_Word16_2[k] + 1)); /* Construct a new upper channel signal*/
    209       tmp_2 = (int16_t)WebRtcSpl_SatW32ToW16(((int32_t)Vector_Word16_1[k]-Vector_Word16_2[k])); /* Construct a new lower channel signal*/
    210       Vector_Word16_1[k] = tmp_1;
    211       Vector_Word16_2[k] = tmp_2;
    212     }
    213 
    214     WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1,
    215                                     Vector_Word16_2,
    216                                     signal_out16 + frame_nb * kProcessedSamples,
    217                                     &ISACdec_obj->postfiltbankstr_obj);
    218 
    219   }
    220   return len;
    221 }
    222