Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2012 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_B.c
     13  *
     14  * This file contains definition of funtions for decoding.
     15  * Decoding of lower-band, including normal-decoding and RCU decoding.
     16  * Decoding of upper-band, including 8-12 kHz, when the bandwidth is
     17  * 0-12 kHz, and 8-16 kHz, when the bandwidth is 0-16 kHz.
     18  *
     19  */
     20 
     21 
     22 #include "codec.h"
     23 #include "entropy_coding.h"
     24 #include "pitch_estimator.h"
     25 #include "bandwidth_estimator.h"
     26 #include "structs.h"
     27 #include "settings.h"
     28 
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <string.h>
     32 
     33 
     34 /*
     35  * function to decode the bitstream
     36  * returns the total number of bytes in the stream
     37  */
     38 int WebRtcIsac_DecodeLb(float* signal_out, ISACLBDecStruct* ISACdecLB_obj,
     39                         WebRtc_Word16* current_framesamples,
     40                         WebRtc_Word16 isRCUPayload) {
     41   int k;
     42   int len, err;
     43   WebRtc_Word16 bandwidthInd;
     44 
     45   float LP_dec_float[FRAMESAMPLES_HALF];
     46   float HP_dec_float[FRAMESAMPLES_HALF];
     47 
     48   double LPw[FRAMESAMPLES_HALF];
     49   double HPw[FRAMESAMPLES_HALF];
     50   double LPw_pf[FRAMESAMPLES_HALF];
     51 
     52   double lo_filt_coef[(ORDERLO + 1)*SUBFRAMES];
     53   double hi_filt_coef[(ORDERHI + 1)*SUBFRAMES];
     54 
     55   double real_f[FRAMESAMPLES_HALF];
     56   double imag_f[FRAMESAMPLES_HALF];
     57 
     58   double PitchLags[4];
     59   double PitchGains[4];
     60   double AvgPitchGain;
     61   WebRtc_Word16 PitchGains_Q12[4];
     62   WebRtc_Word16 AvgPitchGain_Q12;
     63 
     64   float gain;
     65 
     66   int frame_nb; /* counter */
     67   int frame_mode; /* 0 30ms, 1 for 60ms */
     68   /* Processed_samples: 480 (30, 60 ms). Cannot take other values. */
     69 
     70   WebRtcIsac_ResetBitstream(&(ISACdecLB_obj->bitstr_obj));
     71 
     72   len = 0;
     73 
     74   /* Decode framelength and BW estimation - not used,
     75      only for stream pointer*/
     76   err = WebRtcIsac_DecodeFrameLen(&ISACdecLB_obj->bitstr_obj,
     77                                   current_framesamples);
     78   if (err < 0) {
     79     return err;
     80   }
     81 
     82   /* Frame_mode:
     83    * 0: indicates 30 ms frame (480 samples)
     84    * 1: indicates 60 ms frame (960 samples) */
     85   frame_mode = *current_framesamples / MAX_FRAMESAMPLES;
     86 
     87   err = WebRtcIsac_DecodeSendBW(&ISACdecLB_obj->bitstr_obj, &bandwidthInd);
     88   if (err < 0) {
     89     return err;
     90   }
     91 
     92   /* One loop if it's one frame (20 or 30ms), 2 loops if 2 frames
     93      bundled together (60ms). */
     94   for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) {
     95     /* Decode & de-quantize pitch parameters */
     96     err = WebRtcIsac_DecodePitchGain(&ISACdecLB_obj->bitstr_obj,
     97                                      PitchGains_Q12);
     98     if (err < 0) {
     99       return err;
    100     }
    101 
    102     err = WebRtcIsac_DecodePitchLag(&ISACdecLB_obj->bitstr_obj, PitchGains_Q12,
    103                                     PitchLags);
    104     if (err < 0) {
    105       return err;
    106     }
    107 
    108     AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] +
    109         PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2;
    110 
    111     /* Decode & de-quantize filter coefficients. */
    112     err = WebRtcIsac_DecodeLpc(&ISACdecLB_obj->bitstr_obj, lo_filt_coef,
    113                                hi_filt_coef);
    114     if (err < 0) {
    115       return err;
    116     }
    117     /* Decode & de-quantize spectrum. */
    118     len = WebRtcIsac_DecodeSpec(&ISACdecLB_obj->bitstr_obj, AvgPitchGain_Q12,
    119                                 kIsacLowerBand, real_f, imag_f);
    120     if (len < 0) {
    121       return len;
    122     }
    123 
    124     /* Inverse transform. */
    125     WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw,
    126                          &ISACdecLB_obj->fftstr_obj);
    127 
    128     /* Convert PitchGains back to float for pitchfilter_post */
    129     for (k = 0; k < 4; k++) {
    130       PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096;
    131     }
    132     if (isRCUPayload) {
    133       for (k = 0; k < 240; k++) {
    134         LPw[k] *= RCU_TRANSCODING_SCALE_INVERSE;
    135         HPw[k] *= RCU_TRANSCODING_SCALE_INVERSE;
    136       }
    137     }
    138 
    139     /* Inverse pitch filter. */
    140     WebRtcIsac_PitchfilterPost(LPw, LPw_pf, &ISACdecLB_obj->pitchfiltstr_obj,
    141                                PitchLags, PitchGains);
    142     /* Convert AvgPitchGain back to float for computation of gain. */
    143     AvgPitchGain = ((float)AvgPitchGain_Q12) / 4096;
    144     gain = 1.0f - 0.45f * (float)AvgPitchGain;
    145 
    146     for (k = 0; k < FRAMESAMPLES_HALF; k++) {
    147       /* Reduce gain to compensate for pitch enhancer. */
    148       LPw_pf[k] *= gain;
    149     }
    150 
    151     if (isRCUPayload) {
    152       for (k = 0; k < FRAMESAMPLES_HALF; k++) {
    153         /* Compensation for transcoding gain changes. */
    154         LPw_pf[k] *= RCU_TRANSCODING_SCALE;
    155         HPw[k] *= RCU_TRANSCODING_SCALE;
    156       }
    157     }
    158     /* Perceptual post-filtering (using normalized lattice filter). */
    159     WebRtcIsac_NormLatticeFilterAr(
    160         ORDERLO, ISACdecLB_obj->maskfiltstr_obj.PostStateLoF,
    161         (ISACdecLB_obj->maskfiltstr_obj).PostStateLoG, LPw_pf, lo_filt_coef,
    162         LP_dec_float);
    163     WebRtcIsac_NormLatticeFilterAr(
    164         ORDERHI, ISACdecLB_obj->maskfiltstr_obj.PostStateHiF,
    165         (ISACdecLB_obj->maskfiltstr_obj).PostStateHiG, HPw, hi_filt_coef,
    166         HP_dec_float);
    167 
    168     /* Recombine the 2 bands. */
    169     WebRtcIsac_FilterAndCombineFloat(LP_dec_float, HP_dec_float,
    170                                      signal_out + frame_nb * FRAMESAMPLES,
    171                                      &ISACdecLB_obj->postfiltbankstr_obj);
    172   }
    173   return len;
    174 }
    175 
    176 
    177 /*
    178  * This decode function is called when the codec is operating in 16 kHz
    179  * bandwidth to decode the upperband, i.e. 8-16 kHz.
    180  *
    181  * Contrary to lower-band, the upper-band (8-16 kHz) is not split in
    182  * frequency, but split to 12 sub-frames, i.e. twice as lower-band.
    183  */
    184 int WebRtcIsac_DecodeUb16(float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
    185                           WebRtc_Word16 isRCUPayload) {
    186   int len, err;
    187 
    188   double halfFrameFirst[FRAMESAMPLES_HALF];
    189   double halfFrameSecond[FRAMESAMPLES_HALF];
    190 
    191   double percepFilterParam[(UB_LPC_ORDER + 1) * (SUBFRAMES << 1) +
    192                            (UB_LPC_ORDER + 1)];
    193 
    194   double real_f[FRAMESAMPLES_HALF];
    195   double imag_f[FRAMESAMPLES_HALF];
    196   const WebRtc_Word16 kAveragePitchGain = 0; /* No pitch-gain for upper-band. */
    197   len = 0;
    198 
    199   /* Decode & de-quantize filter coefficients. */
    200   memset(percepFilterParam, 0, sizeof(percepFilterParam));
    201   err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj,
    202                                        percepFilterParam, isac16kHz);
    203   if (err < 0) {
    204     return err;
    205   }
    206 
    207   /* Decode & de-quantize spectrum. */
    208   len = WebRtcIsac_DecodeSpec(&ISACdecUB_obj->bitstr_obj, kAveragePitchGain,
    209                               kIsacUpperBand16, real_f, imag_f);
    210   if (len < 0) {
    211     return len;
    212   }
    213   if (isRCUPayload) {
    214     int n;
    215     for (n = 0; n < 240; n++) {
    216       real_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
    217       imag_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
    218     }
    219   }
    220   /* Inverse transform. */
    221   WebRtcIsac_Spec2time(real_f, imag_f, halfFrameFirst, halfFrameSecond,
    222                        &ISACdecUB_obj->fftstr_obj);
    223 
    224   /* Perceptual post-filtering (using normalized lattice filter). */
    225   WebRtcIsac_NormLatticeFilterAr(
    226       UB_LPC_ORDER, ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
    227       (ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, halfFrameFirst,
    228       &percepFilterParam[(UB_LPC_ORDER + 1)], signal_out);
    229 
    230   WebRtcIsac_NormLatticeFilterAr(
    231       UB_LPC_ORDER, ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
    232       (ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, halfFrameSecond,
    233       &percepFilterParam[(UB_LPC_ORDER + 1) * SUBFRAMES + (UB_LPC_ORDER + 1)],
    234       &signal_out[FRAMESAMPLES_HALF]);
    235 
    236   return len;
    237 }
    238 
    239 /*
    240  * This decode function is called when the codec operates at 0-12 kHz
    241  * bandwidth to decode the upperband, i.e. 8-12 kHz.
    242  *
    243  * At the encoder the upper-band is split into two band, 8-12 kHz & 12-16
    244  * kHz, and only 8-12 kHz is encoded. At the decoder, 8-12 kHz band is
    245  * reconstructed and 12-16 kHz replaced with zeros. Then two bands
    246  * are combined, to reconstruct the upperband 8-16 kHz.
    247  */
    248 int WebRtcIsac_DecodeUb12(float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
    249                       WebRtc_Word16 isRCUPayload) {
    250   int len, err;
    251 
    252   float LP_dec_float[FRAMESAMPLES_HALF];
    253   float HP_dec_float[FRAMESAMPLES_HALF];
    254 
    255   double LPw[FRAMESAMPLES_HALF];
    256   double HPw[FRAMESAMPLES_HALF];
    257 
    258   double percepFilterParam[(UB_LPC_ORDER + 1)*SUBFRAMES];
    259 
    260   double real_f[FRAMESAMPLES_HALF];
    261   double imag_f[FRAMESAMPLES_HALF];
    262   const WebRtc_Word16 kAveragePitchGain = 0; /* No pitch-gain for upper-band. */
    263   len = 0;
    264 
    265   /* Decode & dequantize filter coefficients. */
    266   err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj,
    267                                        percepFilterParam, isac12kHz);
    268   if (err < 0) {
    269     return err;
    270   }
    271 
    272   /* Decode & de-quantize spectrum. */
    273   len = WebRtcIsac_DecodeSpec(&ISACdecUB_obj->bitstr_obj, kAveragePitchGain,
    274                               kIsacUpperBand12, real_f, imag_f);
    275   if (len < 0) {
    276     return len;
    277   }
    278 
    279   if (isRCUPayload) {
    280     int n;
    281     for (n = 0; n < 240; n++) {
    282       real_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
    283       imag_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
    284     }
    285   }
    286   /* Inverse transform. */
    287   WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw, &ISACdecUB_obj->fftstr_obj);
    288   /* perceptual post-filtering (using normalized lattice filter) */
    289   WebRtcIsac_NormLatticeFilterAr(UB_LPC_ORDER,
    290                                  ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
    291                                  (ISACdecUB_obj->maskfiltstr_obj).PostStateLoG,
    292                                  LPw, percepFilterParam, LP_dec_float);
    293   /* Zero for 12-16 kHz. */
    294   memset(HP_dec_float, 0, sizeof(float) * (FRAMESAMPLES_HALF));
    295   /* Recombine the 2 bands. */
    296   WebRtcIsac_FilterAndCombineFloat(HP_dec_float, LP_dec_float, signal_out,
    297                                    &ISACdecUB_obj->postfiltbankstr_obj);
    298   return len;
    299 }
    300