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  * encode.c
     13  *
     14  * This file contains definition of funtions for encoding.
     15  * Decoding of upper-band, including 8-12 kHz, when the bandwidth is
     16  * 0-12 kHz, and 8-16 kHz, when the bandwidth is 0-16 kHz.
     17  *
     18  */
     19 
     20 #include <stdlib.h>
     21 #include <string.h>
     22 #include <stdio.h>
     23 
     24 #include "structs.h"
     25 #include "codec.h"
     26 #include "pitch_estimator.h"
     27 #include "entropy_coding.h"
     28 #include "arith_routines.h"
     29 #include "pitch_gain_tables.h"
     30 #include "pitch_lag_tables.h"
     31 #include "spectrum_ar_model_tables.h"
     32 #include "lpc_tables.h"
     33 #include "lpc_analysis.h"
     34 #include "bandwidth_estimator.h"
     35 #include "lpc_shape_swb12_tables.h"
     36 #include "lpc_shape_swb16_tables.h"
     37 #include "lpc_gain_swb_tables.h"
     38 
     39 
     40 #define UB_LOOKAHEAD 24
     41 
     42 
     43 /*
     44   Rate allocation tables of lower and upper-band bottleneck for
     45   12kHz & 16kHz bandwidth.
     46 
     47   12 kHz bandwidth
     48   -----------------
     49   The overall bottleneck of the coder is between 38 kbps and 45 kbps. We have
     50   considered 7 enteries, uniformly distributed in this interval, i.e. 38,
     51   39.17, 40.33, 41.5, 42.67, 43.83 and 45. For every entery, the lower-band
     52   and the upper-band bottlenecks are specified in
     53   'kLowerBandBitRate12' and 'kUpperBandBitRate12'
     54   tables, respectively. E.g. the overall rate of 41.5 kbps corresponts to a
     55   bottleneck of 31 kbps for lower-band and 27 kbps for upper-band. Given an
     56   overall bottleneck of the codec, we use linear interpolation to get
     57   lower-band and upper-band bottlenecks.
     58 
     59   16 kHz bandwidth
     60   -----------------
     61   The overall bottleneck of the coder is between 50 kbps and 56 kbps. We have
     62   considered 7 enteries, uniformly distributed in this interval, i.e. 50, 51.2,
     63   52.4, 53.6, 54.8 and 56. For every entery, the lower-band and the upper-band
     64   bottlenecks are specified in 'kLowerBandBitRate16' and
     65   'kUpperBandBitRate16' tables, respectively. E.g. the overall rate
     66   of 53.6 kbps corresponts to a bottleneck of 32 kbps for lower-band and 30
     67   kbps for upper-band. Given an overall bottleneck of the codec, we use linear
     68   interpolation to get lower-band and upper-band bottlenecks.
     69 
     70  */
     71 
     72 /*     38  39.17  40.33   41.5  42.67  43.83     45 */
     73 static const WebRtc_Word16 kLowerBandBitRate12[7] = {
     74     29000, 30000, 30000, 31000, 31000, 32000, 32000 };
     75 static const WebRtc_Word16 kUpperBandBitRate12[7] = {
     76     25000, 25000, 27000, 27000, 29000, 29000, 32000 };
     77 
     78 /*    50     51.2  52.4   53.6   54.8    56 */
     79 static const WebRtc_Word16 kLowerBandBitRate16[6] = {
     80     31000, 31000, 32000, 32000, 32000, 32000 };
     81 static const WebRtc_Word16 kUpperBandBitRate16[6] = {
     82     28000, 29000, 29000, 30000, 31000, 32000 };
     83 
     84 /******************************************************************************
     85  * WebRtcIsac_RateAllocation()
     86  * Internal function to perform a rate-allocation for upper and lower-band,
     87  * given a total rate.
     88  *
     89  * Input:
     90  *   - inRateBitPerSec           : a total bottleneck in bits/sec.
     91  *
     92  * Output:
     93  *   - rateLBBitPerSec           : a bottleneck allocated to the lower-band
     94  *                                 in bits/sec.
     95  *   - rateUBBitPerSec           : a bottleneck allocated to the upper-band
     96  *                                 in bits/sec.
     97  *
     98  * Return value                  : 0 if rate allocation has been successful.
     99  *                                -1 if failed to allocate rates.
    100  */
    101 
    102 WebRtc_Word16 WebRtcIsac_RateAllocation(WebRtc_Word32 inRateBitPerSec,
    103                                         double* rateLBBitPerSec,
    104                                         double* rateUBBitPerSec,
    105                                         enum ISACBandwidth* bandwidthKHz) {
    106   WebRtc_Word16 idx;
    107   double idxD;
    108   double idxErr;
    109   if (inRateBitPerSec < 38000) {
    110     /* If the given overall bottleneck is less than 38000 then
    111      * then codec has to operate in wideband mode, i.e. 8 kHz
    112      * bandwidth. */
    113     *rateLBBitPerSec = (WebRtc_Word16)((inRateBitPerSec > 32000) ?
    114         32000 : inRateBitPerSec);
    115     *rateUBBitPerSec = 0;
    116     *bandwidthKHz = isac8kHz;
    117   } else if ((inRateBitPerSec >= 38000) && (inRateBitPerSec < 50000)) {
    118     /* At a bottleneck between 38 and 50 kbps the codec is operating
    119      * at 12 kHz bandwidth. Using xxxBandBitRate12[] to calculates
    120      * upper/lower bottleneck */
    121 
    122     /* Find the bottlenecks by linear interpolation,
    123      * step is (45000 - 38000)/6.0 we use the inverse of it. */
    124     const double stepSizeInv = 8.5714286e-4;
    125     idxD = (inRateBitPerSec - 38000) * stepSizeInv;
    126     idx = (idxD >= 6) ? 6 : ((WebRtc_Word16)idxD);
    127     idxErr = idxD - idx;
    128     *rateLBBitPerSec = kLowerBandBitRate12[idx];
    129     *rateUBBitPerSec = kUpperBandBitRate12[idx];
    130 
    131     if (idx < 6) {
    132       *rateLBBitPerSec += (WebRtc_Word16)(
    133           idxErr * (kLowerBandBitRate12[idx + 1] - kLowerBandBitRate12[idx]));
    134       *rateUBBitPerSec += (WebRtc_Word16)(
    135           idxErr * (kUpperBandBitRate12[idx + 1] - kUpperBandBitRate12[idx]));
    136     }
    137     *bandwidthKHz = isac12kHz;
    138   } else if ((inRateBitPerSec >= 50000) && (inRateBitPerSec <= 56000)) {
    139     /* A bottleneck between 50 and 56 kbps corresponds to bandwidth
    140      * of 16 kHz. Using xxxBandBitRate16[] to calculates
    141      * upper/lower bottleneck. */
    142 
    143     /* Find the bottlenecks by linear interpolation
    144      * step is (56000 - 50000)/5 we use the inverse of it. */
    145     const double stepSizeInv = 8.3333333e-4;
    146     idxD = (inRateBitPerSec - 50000) * stepSizeInv;
    147     idx = (idxD >= 5) ? 5 : ((WebRtc_Word16)idxD);
    148     idxErr = idxD - idx;
    149     *rateLBBitPerSec = kLowerBandBitRate16[idx];
    150     *rateUBBitPerSec  = kUpperBandBitRate16[idx];
    151 
    152     if (idx < 5) {
    153       *rateLBBitPerSec += (WebRtc_Word16)(idxErr *
    154           (kLowerBandBitRate16[idx + 1] -
    155               kLowerBandBitRate16[idx]));
    156 
    157       *rateUBBitPerSec += (WebRtc_Word16)(idxErr *
    158           (kUpperBandBitRate16[idx + 1] -
    159               kUpperBandBitRate16[idx]));
    160     }
    161     *bandwidthKHz = isac16kHz;
    162   } else {
    163     /* Out-of-range botlteneck value. */
    164     return -1;
    165   }
    166 
    167   /* limit the values. */
    168   *rateLBBitPerSec = (*rateLBBitPerSec > 32000) ? 32000 : *rateLBBitPerSec;
    169   *rateUBBitPerSec = (*rateUBBitPerSec > 32000) ? 32000 : *rateUBBitPerSec;
    170   return 0;
    171 }
    172 
    173 
    174 void WebRtcIsac_ResetBitstream(Bitstr* bit_stream) {
    175   bit_stream->W_upper = 0xFFFFFFFF;
    176   bit_stream->stream_index = 0;
    177   bit_stream->streamval = 0;
    178 }
    179 
    180 int WebRtcIsac_EncodeLb(float* in, ISACLBEncStruct* ISACencLB_obj,
    181                         WebRtc_Word16 codingMode,
    182                         WebRtc_Word16 bottleneckIndex) {
    183   int stream_length = 0;
    184   int err;
    185   int k;
    186   int iterCntr;
    187 
    188   double lofilt_coef[(ORDERLO + 1)*SUBFRAMES];
    189   double hifilt_coef[(ORDERHI + 1)*SUBFRAMES];
    190   float LP[FRAMESAMPLES_HALF];
    191   float HP[FRAMESAMPLES_HALF];
    192 
    193   double LP_lookahead[FRAMESAMPLES_HALF];
    194   double HP_lookahead[FRAMESAMPLES_HALF];
    195   double LP_lookahead_pf[FRAMESAMPLES_HALF + QLOOKAHEAD];
    196   double LPw[FRAMESAMPLES_HALF];
    197 
    198   double HPw[FRAMESAMPLES_HALF];
    199   double LPw_pf[FRAMESAMPLES_HALF];
    200   WebRtc_Word16 fre[FRAMESAMPLES_HALF];   /* Q7 */
    201   WebRtc_Word16 fim[FRAMESAMPLES_HALF];   /* Q7 */
    202 
    203   double PitchLags[4];
    204   double PitchGains[4];
    205   WebRtc_Word16 PitchGains_Q12[4];
    206   WebRtc_Word16 AvgPitchGain_Q12;
    207 
    208   int frame_mode; /* 0 for 30ms, 1 for 60ms */
    209   int status = 0;
    210   int my_index;
    211   transcode_obj transcodingParam;
    212   double bytesLeftSpecCoding;
    213   WebRtc_UWord16 payloadLimitBytes;
    214 
    215   /* Copy new frame-length and bottleneck rate only for the first 10 ms data */
    216   if (ISACencLB_obj->buffer_index == 0) {
    217     /* Set the framelength for the next packet. */
    218     ISACencLB_obj->current_framesamples = ISACencLB_obj->new_framelength;
    219   }
    220   /* 'frame_mode' is 0 (30 ms) or 1 (60 ms). */
    221   frame_mode = ISACencLB_obj->current_framesamples / MAX_FRAMESAMPLES;
    222 
    223   /* buffer speech samples (by 10ms packet) until the frame-length */
    224   /* is reached (30 or 60 ms).                                     */
    225   /*****************************************************************/
    226 
    227   /* fill the buffer with 10ms input data */
    228   for (k = 0; k < FRAMESAMPLES_10ms; k++) {
    229     ISACencLB_obj->data_buffer_float[k + ISACencLB_obj->buffer_index] = in[k];
    230   }
    231 
    232   /* If buffersize is not equal to current framesize then increase index
    233    * and return. We do no encoding untill we have enough audio.  */
    234   if (ISACencLB_obj->buffer_index + FRAMESAMPLES_10ms != FRAMESAMPLES) {
    235     ISACencLB_obj->buffer_index += FRAMESAMPLES_10ms;
    236     return 0;
    237   }
    238   /* If buffer reached the right size, reset index and continue with
    239    * encoding the frame. */
    240   ISACencLB_obj->buffer_index = 0;
    241 
    242   /* End of buffer function. */
    243   /**************************/
    244 
    245   /* Encoding */
    246   /************/
    247 
    248   if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) {
    249     /* This is to avoid Linux warnings until we change 'int' to 'Word32'
    250      * at all places. */
    251     int intVar;
    252     /* reset bitstream */
    253     WebRtcIsac_ResetBitstream(&(ISACencLB_obj->bitstr_obj));
    254 
    255     if ((codingMode == 0) && (frame_mode == 0) &&
    256         (ISACencLB_obj->enforceFrameSize == 0)) {
    257       ISACencLB_obj->new_framelength = WebRtcIsac_GetNewFrameLength(
    258           ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples);
    259     }
    260 
    261     ISACencLB_obj->s2nr = WebRtcIsac_GetSnr(
    262         ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples);
    263 
    264     /* Encode frame length. */
    265     status = WebRtcIsac_EncodeFrameLen(
    266         ISACencLB_obj->current_framesamples, &ISACencLB_obj->bitstr_obj);
    267     if (status < 0) {
    268       /* Wrong frame size. */
    269       return status;
    270     }
    271     /* Save framelength for multiple packets memory. */
    272     ISACencLB_obj->SaveEnc_obj.framelength =
    273         ISACencLB_obj->current_framesamples;
    274 
    275     /* To be used for Redundant Coding. */
    276     ISACencLB_obj->lastBWIdx = bottleneckIndex;
    277     intVar = (int)bottleneckIndex;
    278     WebRtcIsac_EncodeReceiveBw(&intVar, &ISACencLB_obj->bitstr_obj);
    279   }
    280 
    281   /* Split signal in two bands. */
    282   WebRtcIsac_SplitAndFilterFloat(ISACencLB_obj->data_buffer_float, LP, HP,
    283                                  LP_lookahead, HP_lookahead,
    284                                  &ISACencLB_obj->prefiltbankstr_obj);
    285 
    286   /* estimate pitch parameters and pitch-filter lookahead signal */
    287   WebRtcIsac_PitchAnalysis(LP_lookahead, LP_lookahead_pf,
    288                            &ISACencLB_obj->pitchanalysisstr_obj, PitchLags,
    289                            PitchGains);
    290 
    291   /* Encode in FIX Q12. */
    292 
    293   /* Convert PitchGain to Fixed point. */
    294   for (k = 0; k < PITCH_SUBFRAMES; k++) {
    295     PitchGains_Q12[k] = (WebRtc_Word16)(PitchGains[k] * 4096.0);
    296   }
    297 
    298   /* Set where to store data in multiple packets memory. */
    299   if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) {
    300     ISACencLB_obj->SaveEnc_obj.startIdx = 0;
    301   } else {
    302     ISACencLB_obj->SaveEnc_obj.startIdx = 1;
    303   }
    304 
    305   /* Quantize & encode pitch parameters. */
    306   WebRtcIsac_EncodePitchGain(PitchGains_Q12, &ISACencLB_obj->bitstr_obj,
    307                              &ISACencLB_obj->SaveEnc_obj);
    308   WebRtcIsac_EncodePitchLag(PitchLags, PitchGains_Q12,
    309                             &ISACencLB_obj->bitstr_obj,
    310                             &ISACencLB_obj->SaveEnc_obj);
    311 
    312   AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] +
    313       PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2;
    314 
    315   /* Find coefficients for perceptual pre-filters. */
    316   WebRtcIsac_GetLpcCoefLb(LP_lookahead_pf, HP_lookahead,
    317                           &ISACencLB_obj->maskfiltstr_obj, ISACencLB_obj->s2nr,
    318                           PitchGains_Q12, lofilt_coef, hifilt_coef);
    319 
    320   /* Code LPC model and shape - gains not quantized yet. */
    321   WebRtcIsac_EncodeLpcLb(lofilt_coef, hifilt_coef, &ISACencLB_obj->bitstr_obj,
    322                          &ISACencLB_obj->SaveEnc_obj);
    323 
    324   /* Convert PitchGains back to FLOAT for pitchfilter_pre. */
    325   for (k = 0; k < 4; k++) {
    326     PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096;
    327   }
    328 
    329   /* Store the state of arithmetic coder before coding LPC gains. */
    330   transcodingParam.W_upper = ISACencLB_obj->bitstr_obj.W_upper;
    331   transcodingParam.stream_index = ISACencLB_obj->bitstr_obj.stream_index;
    332   transcodingParam.streamval = ISACencLB_obj->bitstr_obj.streamval;
    333   transcodingParam.stream[0] =
    334       ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index -
    335                                        2];
    336   transcodingParam.stream[1] =
    337       ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index -
    338                                        1];
    339   transcodingParam.stream[2] =
    340       ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index];
    341 
    342   /* Store LPC Gains before encoding them. */
    343   for (k = 0; k < SUBFRAMES; k++) {
    344     transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k];
    345     transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k];
    346   }
    347 
    348   /* Code gains */
    349   WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef,
    350                              &ISACencLB_obj->bitstr_obj,
    351                              &ISACencLB_obj->SaveEnc_obj);
    352 
    353   /* Get the correct value for the payload limit and calculate the
    354    * number of bytes left for coding the spectrum. */
    355   if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) {
    356     /* It is a 60ms and we are in the first 30ms then the limit at
    357      * this point should be half of the assigned value. */
    358     payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 >> 1;
    359   } else if (frame_mode == 0) {
    360     /* It is a 30ms frame */
    361     /* Subract 3 because termination process may add 3 bytes. */
    362     payloadLimitBytes = ISACencLB_obj->payloadLimitBytes30 - 3;
    363   } else {
    364     /* This is the second half of a 60ms frame. */
    365     /* Subract 3 because termination process may add 3 bytes. */
    366     payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 - 3;
    367   }
    368   bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index;
    369 
    370   /* Perceptual pre-filtering (using normalized lattice filter). */
    371   /* Low-band filtering. */
    372   WebRtcIsac_NormLatticeFilterMa(ORDERLO,
    373                                  ISACencLB_obj->maskfiltstr_obj.PreStateLoF,
    374                                  ISACencLB_obj->maskfiltstr_obj.PreStateLoG,
    375                                  LP, lofilt_coef, LPw);
    376   /* High-band filtering. */
    377   WebRtcIsac_NormLatticeFilterMa(ORDERHI,
    378                                  ISACencLB_obj->maskfiltstr_obj.PreStateHiF,
    379                                  ISACencLB_obj->maskfiltstr_obj.PreStateHiG,
    380                                  HP, hifilt_coef, HPw);
    381   /* Pitch filter. */
    382   WebRtcIsac_PitchfilterPre(LPw, LPw_pf, &ISACencLB_obj->pitchfiltstr_obj,
    383                             PitchLags, PitchGains);
    384   /* Transform */
    385   WebRtcIsac_Time2Spec(LPw_pf, HPw, fre, fim, &ISACencLB_obj->fftstr_obj);
    386 
    387   /* Save data for multiple packets memory. */
    388   my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF;
    389   memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre));
    390   memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim));
    391 
    392   ISACencLB_obj->SaveEnc_obj.AvgPitchGain[ISACencLB_obj->SaveEnc_obj.startIdx] =
    393       AvgPitchGain_Q12;
    394 
    395   /* Quantization and loss-less coding. */
    396   err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand,
    397                               &ISACencLB_obj->bitstr_obj);
    398   if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    399     /* There has been an error but it was not too large payload
    400        (we can cure too large payload). */
    401     if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) {
    402       /* If this is the second 30ms of a 60ms frame reset
    403          this such that in the next call encoder starts fresh. */
    404       ISACencLB_obj->frame_nb = 0;
    405     }
    406     return err;
    407   }
    408   iterCntr = 0;
    409   while ((ISACencLB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
    410       (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    411     double bytesSpecCoderUsed;
    412     double transcodeScale;
    413 
    414     if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) {
    415       /* We were not able to limit the payload size */
    416       if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) {
    417         /* This was the first 30ms of a 60ms frame. Although
    418            the payload is larger than it should be but we let
    419            the second 30ms be encoded. Maybe together we
    420            won't exceed the limit. */
    421         ISACencLB_obj->frame_nb = 1;
    422         return 0;
    423       } else if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 1)) {
    424         ISACencLB_obj->frame_nb = 0;
    425       }
    426 
    427       if (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
    428         return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
    429       } else {
    430         return status;
    431       }
    432     }
    433 
    434     if (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
    435       bytesSpecCoderUsed = STREAM_SIZE_MAX;
    436       /* Being conservative */
    437       transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5;
    438     } else {
    439       bytesSpecCoderUsed = ISACencLB_obj->bitstr_obj.stream_index -
    440           transcodingParam.stream_index;
    441       transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed;
    442     }
    443 
    444     /* To be safe, we reduce the scale depending on
    445        the number of iterations. */
    446     transcodeScale *= (1.0 - (0.9 * (double)iterCntr /
    447         (double)MAX_PAYLOAD_LIMIT_ITERATION));
    448 
    449     /* Scale the LPC Gains. */
    450     for (k = 0; k < SUBFRAMES; k++) {
    451       lofilt_coef[(LPC_LOBAND_ORDER + 1) * k] =
    452           transcodingParam.loFiltGain[k] * transcodeScale;
    453       hifilt_coef[(LPC_HIBAND_ORDER + 1) * k] =
    454           transcodingParam.hiFiltGain[k] * transcodeScale;
    455       transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k];
    456       transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k];
    457     }
    458 
    459     /* Scale DFT coefficients. */
    460     for (k = 0; k < FRAMESAMPLES_HALF; k++) {
    461       fre[k] = (WebRtc_Word16)(fre[k] * transcodeScale);
    462       fim[k] = (WebRtc_Word16)(fim[k] * transcodeScale);
    463     }
    464 
    465     /* Save data for multiple packets memory. */
    466     my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF;
    467     memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre));
    468     memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim));
    469 
    470     /* Re-store the state of arithmetic coder before coding LPC gains. */
    471     ISACencLB_obj->bitstr_obj.W_upper = transcodingParam.W_upper;
    472     ISACencLB_obj->bitstr_obj.stream_index = transcodingParam.stream_index;
    473     ISACencLB_obj->bitstr_obj.streamval = transcodingParam.streamval;
    474     ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 2] =
    475         transcodingParam.stream[0];
    476     ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 1] =
    477         transcodingParam.stream[1];
    478     ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index] =
    479         transcodingParam.stream[2];
    480 
    481     /* Code gains. */
    482     WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef,
    483                                &ISACencLB_obj->bitstr_obj,
    484                                &ISACencLB_obj->SaveEnc_obj);
    485 
    486     /* Update the number of bytes left for encoding the spectrum. */
    487     bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index;
    488 
    489     /* Encode the spectrum. */
    490     err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand,
    491                                 &ISACencLB_obj->bitstr_obj);
    492 
    493     if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    494       /* There has been an error but it was not too large
    495          payload (we can cure too large payload). */
    496       if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) {
    497         /* If this is the second 30 ms of a 60 ms frame reset
    498            this such that in the next call encoder starts fresh. */
    499         ISACencLB_obj->frame_nb = 0;
    500       }
    501       return err;
    502     }
    503     iterCntr++;
    504   }
    505 
    506   /* If 60 ms frame-size and just processed the first 30 ms, */
    507   /* go back to main function to buffer the other 30 ms speech frame. */
    508   if (frame_mode == 1) {
    509     if (ISACencLB_obj->frame_nb == 0) {
    510       ISACencLB_obj->frame_nb = 1;
    511       return 0;
    512     } else if (ISACencLB_obj->frame_nb == 1) {
    513       ISACencLB_obj->frame_nb = 0;
    514       /* Also update the frame-length for next packet,
    515          in Adaptive mode only. */
    516       if (codingMode == 0 && (ISACencLB_obj->enforceFrameSize == 0)) {
    517         ISACencLB_obj->new_framelength =
    518             WebRtcIsac_GetNewFrameLength(ISACencLB_obj->bottleneck,
    519                                          ISACencLB_obj->current_framesamples);
    520       }
    521     }
    522   } else {
    523     ISACencLB_obj->frame_nb = 0;
    524   }
    525 
    526   /* Complete arithmetic coding. */
    527   stream_length = WebRtcIsac_EncTerminate(&ISACencLB_obj->bitstr_obj);
    528   return stream_length;
    529 }
    530 
    531 
    532 
    533 static int LimitPayloadUb(ISACUBEncStruct* ISACencUB_obj,
    534                           WebRtc_UWord16 payloadLimitBytes,
    535                           double bytesLeftSpecCoding,
    536                           transcode_obj* transcodingParam,
    537                           WebRtc_Word16* fre, WebRtc_Word16* fim,
    538                           double* lpcGains, enum ISACBand band, int status) {
    539 
    540   int iterCntr = 0;
    541   int k;
    542   double bytesSpecCoderUsed;
    543   double transcodeScale;
    544   const WebRtc_Word16 kAveragePitchGain = 0.0;
    545 
    546   do {
    547     if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) {
    548       /* We were not able to limit the payload size. */
    549       return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
    550     }
    551 
    552     if (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
    553       bytesSpecCoderUsed = STREAM_SIZE_MAX;
    554       /* Being conservative. */
    555       transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5;
    556     } else {
    557       bytesSpecCoderUsed = ISACencUB_obj->bitstr_obj.stream_index -
    558           transcodingParam->stream_index;
    559       transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed;
    560     }
    561 
    562     /* To be safe, we reduce the scale depending on the
    563        number of iterations. */
    564     transcodeScale *= (1.0 - (0.9 * (double)iterCntr /
    565         (double)MAX_PAYLOAD_LIMIT_ITERATION));
    566 
    567     /* Scale the LPC Gains. */
    568     if (band == kIsacUpperBand16) {
    569       /* Two sets of coefficients if 16 kHz. */
    570       for (k = 0; k < SUBFRAMES; k++) {
    571         transcodingParam->loFiltGain[k] *= transcodeScale;
    572         transcodingParam->hiFiltGain[k] *= transcodeScale;
    573       }
    574     } else {
    575       /* One sets of coefficients if 12 kHz. */
    576       for (k = 0; k < SUBFRAMES; k++) {
    577         transcodingParam->loFiltGain[k] *= transcodeScale;
    578       }
    579     }
    580 
    581     /* Scale DFT coefficients. */
    582     for (k = 0; k < FRAMESAMPLES_HALF; k++) {
    583       fre[k] = (WebRtc_Word16)(fre[k] * transcodeScale + 0.5);
    584       fim[k] = (WebRtc_Word16)(fim[k] * transcodeScale + 0.5);
    585     }
    586     /* Store FFT coefficients for multiple encoding. */
    587     memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre,
    588           sizeof(ISACencUB_obj->SaveEnc_obj.realFFT));
    589     memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim,
    590            sizeof(ISACencUB_obj->SaveEnc_obj.imagFFT));
    591 
    592     /* Store the state of arithmetic coder before coding LPC gains */
    593     ISACencUB_obj->bitstr_obj.W_upper = transcodingParam->W_upper;
    594     ISACencUB_obj->bitstr_obj.stream_index = transcodingParam->stream_index;
    595     ISACencUB_obj->bitstr_obj.streamval = transcodingParam->streamval;
    596     ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 2] =
    597         transcodingParam->stream[0];
    598     ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 1] =
    599         transcodingParam->stream[1];
    600     ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index] =
    601         transcodingParam->stream[2];
    602 
    603     /* Store the gains for multiple encoding. */
    604     memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains,
    605            SUBFRAMES * sizeof(double));
    606     /* Entropy Code lpc-gains, indices are stored for a later use.*/
    607     WebRtcIsac_EncodeLpcGainUb(transcodingParam->loFiltGain,
    608                                &ISACencUB_obj->bitstr_obj,
    609                                ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
    610 
    611     /* If 16kHz should do one more set. */
    612     if (band == kIsacUpperBand16) {
    613       /* Store the gains for multiple encoding. */
    614       memcpy(&ISACencUB_obj->SaveEnc_obj.lpcGain[SUBFRAMES],
    615              &lpcGains[SUBFRAMES], SUBFRAMES * sizeof(double));
    616       /* Entropy Code lpc-gains, indices are stored for a later use.*/
    617       WebRtcIsac_EncodeLpcGainUb(
    618           transcodingParam->hiFiltGain, &ISACencUB_obj->bitstr_obj,
    619           &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]);
    620     }
    621 
    622     /* Update the number of bytes left for encoding the spectrum. */
    623     bytesLeftSpecCoding = payloadLimitBytes -
    624         ISACencUB_obj->bitstr_obj.stream_index;
    625 
    626     /* Save the bit-stream object at this point for FEC. */
    627     memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj,
    628            &ISACencUB_obj->bitstr_obj, sizeof(Bitstr));
    629 
    630     /* Encode the spectrum. */
    631     status = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain,
    632                                    band, &ISACencUB_obj->bitstr_obj);
    633     if ((status < 0) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    634       /* There has been an error but it was not too large payload
    635          (we can cure too large payload). */
    636       return status;
    637     }
    638     iterCntr++;
    639   } while ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
    640       (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH));
    641   return 0;
    642 }
    643 
    644 int WebRtcIsac_EncodeUb16(float* in, ISACUBEncStruct* ISACencUB_obj,
    645                           WebRtc_Word32 jitterInfo) {
    646   int err;
    647   int k;
    648 
    649   double lpcVecs[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
    650   double percepFilterParams[(1 + UB_LPC_ORDER) * (SUBFRAMES << 1) +
    651                             (1 + UB_LPC_ORDER)];
    652 
    653   double LP_lookahead[FRAMESAMPLES];
    654   WebRtc_Word16 fre[FRAMESAMPLES_HALF];   /* Q7 */
    655   WebRtc_Word16 fim[FRAMESAMPLES_HALF];   /* Q7 */
    656 
    657   int status = 0;
    658 
    659   double varscale[2];
    660   double corr[SUBFRAMES << 1][UB_LPC_ORDER + 1];
    661   double lpcGains[SUBFRAMES << 1];
    662   transcode_obj transcodingParam;
    663   WebRtc_UWord16 payloadLimitBytes;
    664   double s2nr;
    665   const WebRtc_Word16 kAveragePitchGain = 0.0;
    666   int bytesLeftSpecCoding;
    667 
    668   /* Buffer speech samples (by 10ms packet) until the frame-length is   */
    669   /* reached (30 ms).                                                   */
    670   /*********************************************************************/
    671 
    672   /* fill the buffer with 10ms input data */
    673   memcpy(&ISACencUB_obj->data_buffer_float[ISACencUB_obj->buffer_index], in,
    674          FRAMESAMPLES_10ms * sizeof(float));
    675 
    676   /* If buffer size is not equal to current frame-size, and end of file is
    677    * not reached yet, we don't do encoding unless we have the whole frame. */
    678   if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) {
    679     ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms;
    680     return 0;
    681   }
    682 
    683   /* End of buffer function. */
    684   /**************************/
    685 
    686   /* Encoding */
    687   /************/
    688 
    689   /* Reset bit-stream */
    690   WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj));
    691 
    692   /* Encoding of bandwidth information. */
    693   WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj);
    694 
    695   status = WebRtcIsac_EncodeBandwidth(isac16kHz, &ISACencUB_obj->bitstr_obj);
    696   if (status < 0) {
    697     return status;
    698   }
    699 
    700   s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES);
    701 
    702   memcpy(lpcVecs, ISACencUB_obj->lastLPCVec, UB_LPC_ORDER * sizeof(double));
    703 
    704   for (k = 0; k < FRAMESAMPLES; k++) {
    705     LP_lookahead[k] = ISACencUB_obj->data_buffer_float[UB_LOOKAHEAD + k];
    706   }
    707 
    708   /* Find coefficients for perceptual pre-filters. */
    709   WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj,
    710                           &lpcVecs[UB_LPC_ORDER], corr, varscale, isac16kHz);
    711 
    712   memcpy(ISACencUB_obj->lastLPCVec,
    713          &lpcVecs[(UB16_LPC_VEC_PER_FRAME - 1) * (UB_LPC_ORDER)],
    714          sizeof(double) * UB_LPC_ORDER);
    715 
    716   /* Code LPC model and shape - gains not quantized yet. */
    717   WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj,
    718                          percepFilterParams, isac16kHz,
    719                          &ISACencUB_obj->SaveEnc_obj);
    720 
    721   /* the first set of lpc parameters are from the last sub-frame of
    722    * the previous frame. so we don't care about them. */
    723   WebRtcIsac_GetLpcGain(s2nr, &percepFilterParams[UB_LPC_ORDER + 1],
    724                         (SUBFRAMES << 1), lpcGains, corr, varscale);
    725 
    726   /* Store the state of arithmetic coder before coding LPC gains */
    727   transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index;
    728   transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper;
    729   transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval;
    730   transcodingParam.stream[0] =
    731       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
    732                                        2];
    733   transcodingParam.stream[1] =
    734       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
    735                                        1];
    736   transcodingParam.stream[2] =
    737       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index];
    738 
    739   /* Store LPC Gains before encoding them. */
    740   for (k = 0; k < SUBFRAMES; k++) {
    741     transcodingParam.loFiltGain[k] = lpcGains[k];
    742     transcodingParam.hiFiltGain[k] = lpcGains[SUBFRAMES + k];
    743   }
    744 
    745   /* Store the gains for multiple encoding. */
    746   memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains,
    747          (SUBFRAMES << 1) * sizeof(double));
    748 
    749   WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj,
    750                              ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
    751   WebRtcIsac_EncodeLpcGainUb(
    752       &lpcGains[SUBFRAMES], &ISACencUB_obj->bitstr_obj,
    753       &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]);
    754 
    755   /* Get the correct value for the payload limit and calculate the number of
    756      bytes left for coding the spectrum. It is a 30ms frame
    757      Subract 3 because termination process may add 3 bytes */
    758   payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes -
    759       ISACencUB_obj->numBytesUsed - 3;
    760   bytesLeftSpecCoding = payloadLimitBytes -
    761         ISACencUB_obj->bitstr_obj.stream_index;
    762 
    763   for (k = 0; k < (SUBFRAMES << 1); k++) {
    764     percepFilterParams[k * (UB_LPC_ORDER + 1) + (UB_LPC_ORDER + 1)] =
    765         lpcGains[k];
    766   }
    767 
    768   /* LPC filtering (using normalized lattice filter), */
    769   /* first half-frame. */
    770   WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER,
    771                                  ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
    772                                  ISACencUB_obj->maskfiltstr_obj.PreStateLoG,
    773                                  &ISACencUB_obj->data_buffer_float[0],
    774                                  &percepFilterParams[UB_LPC_ORDER + 1],
    775                                  &LP_lookahead[0]);
    776 
    777   /* Second half-frame filtering. */
    778   WebRtcIsac_NormLatticeFilterMa(
    779       UB_LPC_ORDER, ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
    780       ISACencUB_obj->maskfiltstr_obj.PreStateLoG,
    781       &ISACencUB_obj->data_buffer_float[FRAMESAMPLES_HALF],
    782       &percepFilterParams[(UB_LPC_ORDER + 1) + SUBFRAMES * (UB_LPC_ORDER + 1)],
    783       &LP_lookahead[FRAMESAMPLES_HALF]);
    784 
    785   WebRtcIsac_Time2Spec(&LP_lookahead[0], &LP_lookahead[FRAMESAMPLES_HALF],
    786                        fre, fim, &ISACencUB_obj->fftstr_obj);
    787 
    788   /* Store FFT coefficients for multiple encoding. */
    789   memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre, sizeof(fre));
    790   memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim, sizeof(fim));
    791 
    792   /* Prepare the audio buffer for the next packet
    793    * move the last 3 ms to the beginning of the buffer. */
    794   memcpy(ISACencUB_obj->data_buffer_float,
    795          &ISACencUB_obj->data_buffer_float[FRAMESAMPLES],
    796          LB_TOTAL_DELAY_SAMPLES * sizeof(float));
    797   /* start writing with 3 ms delay to compensate for the delay
    798    * of the lower-band. */
    799   ISACencUB_obj->buffer_index = LB_TOTAL_DELAY_SAMPLES;
    800 
    801   /* Save the bit-stream object at this point for FEC. */
    802   memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, &ISACencUB_obj->bitstr_obj,
    803          sizeof(Bitstr));
    804 
    805   /* Qantization and lossless coding */
    806   /* Note that there is no pitch-gain for this band so kAveragePitchGain = 0
    807    * is passed to the function. In fact, the function ignores the 3rd parameter
    808    * for this band. */
    809   err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand16,
    810                               &ISACencUB_obj->bitstr_obj);
    811   if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    812     return err;
    813   }
    814 
    815   if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
    816       (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    817     err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding,
    818                          &transcodingParam, fre, fim, lpcGains,
    819                          kIsacUpperBand16, err);
    820   }
    821   if (err < 0) {
    822     return err;
    823   }
    824   /* Complete arithmetic coding. */
    825   return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj);
    826 }
    827 
    828 
    829 int WebRtcIsac_EncodeUb12(float* in, ISACUBEncStruct* ISACencUB_obj,
    830                           WebRtc_Word32 jitterInfo) {
    831   int err;
    832   int k;
    833 
    834   double lpcVecs[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME];
    835 
    836   double percepFilterParams[(1 + UB_LPC_ORDER) * SUBFRAMES];
    837   float LP[FRAMESAMPLES_HALF];
    838   float HP[FRAMESAMPLES_HALF];
    839 
    840   double LP_lookahead[FRAMESAMPLES_HALF];
    841   double HP_lookahead[FRAMESAMPLES_HALF];
    842   double LPw[FRAMESAMPLES_HALF];
    843 
    844   double HPw[FRAMESAMPLES_HALF];
    845   WebRtc_Word16 fre[FRAMESAMPLES_HALF];   /* Q7 */
    846   WebRtc_Word16 fim[FRAMESAMPLES_HALF];   /* Q7 */
    847 
    848   int status = 0;
    849 
    850   double varscale[1];
    851 
    852   double corr[UB_LPC_GAIN_DIM][UB_LPC_ORDER + 1];
    853   double lpcGains[SUBFRAMES];
    854   transcode_obj transcodingParam;
    855   WebRtc_UWord16 payloadLimitBytes;
    856   double s2nr;
    857   const WebRtc_Word16 kAveragePitchGain = 0.0;
    858   double bytesLeftSpecCoding;
    859 
    860   /* Buffer speech samples (by 10ms packet) until the framelength is  */
    861   /* reached (30 ms).                                                 */
    862   /********************************************************************/
    863 
    864   /* Fill the buffer with 10ms input data. */
    865   memcpy(&ISACencUB_obj->data_buffer_float[ISACencUB_obj->buffer_index], in,
    866          FRAMESAMPLES_10ms * sizeof(float));
    867 
    868   /* if buffer-size is not equal to current frame-size then increase the
    869      index and return. We do the encoding when we have enough audio.     */
    870   if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) {
    871     ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms;
    872     return 0;
    873   }
    874   /* If buffer reached the right size, reset index and continue
    875      with encoding the frame */
    876   ISACencUB_obj->buffer_index = 0;
    877 
    878   /* End of buffer function */
    879   /**************************/
    880 
    881   /* Encoding */
    882   /************/
    883 
    884   /* Reset bit-stream. */
    885   WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj));
    886 
    887   /* Encoding bandwidth information. */
    888   WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj);
    889   status = WebRtcIsac_EncodeBandwidth(isac12kHz, &ISACencUB_obj->bitstr_obj);
    890   if (status < 0) {
    891     return status;
    892   }
    893 
    894   s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES);
    895 
    896   /* Split signal in two bands. */
    897   WebRtcIsac_SplitAndFilterFloat(ISACencUB_obj->data_buffer_float, HP, LP,
    898                                  HP_lookahead, LP_lookahead,
    899                                  &ISACencUB_obj->prefiltbankstr_obj);
    900 
    901   /* Find coefficients for perceptual pre-filters. */
    902   WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj,
    903                           lpcVecs, corr, varscale, isac12kHz);
    904 
    905   /* Code LPC model and shape - gains not quantized yet. */
    906   WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj,
    907                          percepFilterParams, isac12kHz,
    908                          &ISACencUB_obj->SaveEnc_obj);
    909 
    910   WebRtcIsac_GetLpcGain(s2nr, percepFilterParams, SUBFRAMES, lpcGains, corr,
    911                         varscale);
    912 
    913   /* Store the state of arithmetic coder before coding LPC gains. */
    914   transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper;
    915   transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index;
    916   transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval;
    917   transcodingParam.stream[0] =
    918       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
    919                                        2];
    920   transcodingParam.stream[1] =
    921       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
    922                                        1];
    923   transcodingParam.stream[2] =
    924       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index];
    925 
    926   /* Store LPC Gains before encoding them. */
    927   for (k = 0; k < SUBFRAMES; k++) {
    928     transcodingParam.loFiltGain[k] = lpcGains[k];
    929   }
    930 
    931   /* Store the gains for multiple encoding. */
    932   memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, SUBFRAMES *
    933          sizeof(double));
    934 
    935   WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj,
    936                              ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
    937 
    938   for (k = 0; k < SUBFRAMES; k++) {
    939     percepFilterParams[k * (UB_LPC_ORDER + 1)] = lpcGains[k];
    940   }
    941 
    942   /* perceptual pre-filtering (using normalized lattice filter) */
    943   /* low-band filtering */
    944   WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER,
    945                                  ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
    946                                  ISACencUB_obj->maskfiltstr_obj.PreStateLoG, LP,
    947                                  percepFilterParams, LPw);
    948 
    949   /* Get the correct value for the payload limit and calculate the number
    950      of bytes left for coding the spectrum. It is a 30ms frame Subract 3
    951      because termination process may add 3 bytes */
    952   payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes -
    953       ISACencUB_obj->numBytesUsed - 3;
    954   bytesLeftSpecCoding = payloadLimitBytes -
    955       ISACencUB_obj->bitstr_obj.stream_index;
    956 
    957   memset(HPw, 0, sizeof(HPw));
    958 
    959   /* Transform */
    960   WebRtcIsac_Time2Spec(LPw, HPw, fre, fim, &ISACencUB_obj->fftstr_obj);
    961 
    962   /* Store FFT coefficients for multiple encoding. */
    963   memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre,
    964          sizeof(ISACencUB_obj->SaveEnc_obj.realFFT));
    965   memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim,
    966          sizeof(ISACencUB_obj->SaveEnc_obj.imagFFT));
    967 
    968   /* Save the bit-stream object at this point for FEC. */
    969   memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj,
    970          &ISACencUB_obj->bitstr_obj, sizeof(Bitstr));
    971 
    972   /* Quantization and loss-less coding */
    973   /* The 4th parameter to this function is pitch-gain, which is only used
    974    * when encoding 0-8 kHz band, and irrelevant in this function, therefore,
    975    * we insert zero here. */
    976   err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand12,
    977                               &ISACencUB_obj->bitstr_obj);
    978   if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    979     /* There has been an error but it was not too large
    980        payload (we can cure too large payload) */
    981     return err;
    982   }
    983 
    984   if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
    985       (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
    986     err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding,
    987                          &transcodingParam, fre, fim, lpcGains,
    988                          kIsacUpperBand12, err);
    989   }
    990   if (err < 0) {
    991     return err;
    992   }
    993   /* Complete arithmetic coding. */
    994   return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj);
    995 }
    996 
    997 
    998 
    999 
   1000 
   1001 
   1002 /* This function is used to create a new bit-stream with new BWE.
   1003    The same data as previously encoded with the function WebRtcIsac_Encoder().
   1004    The data needed is taken from the structure, where it was stored
   1005    when calling the encoder. */
   1006 
   1007 int WebRtcIsac_EncodeStoredDataLb(const ISAC_SaveEncData_t* ISACSavedEnc_obj,
   1008                                   Bitstr* ISACBitStr_obj, int BWnumber,
   1009                                   float scale) {
   1010   int ii;
   1011   int status;
   1012   int BWno = BWnumber;
   1013 
   1014   const WebRtc_UWord16* WebRtcIsac_kQPitchGainCdf_ptr[1];
   1015   const WebRtc_UWord16** cdf;
   1016 
   1017   double tmpLPCcoeffs_lo[(ORDERLO + 1)*SUBFRAMES * 2];
   1018   double tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * 2];
   1019   int tmpLPCindex_g[12 * 2];
   1020   WebRtc_Word16 tmp_fre[FRAMESAMPLES], tmp_fim[FRAMESAMPLES];
   1021   const int kModel = 0;
   1022 
   1023   /* Sanity Check - possible values for BWnumber is 0 - 23. */
   1024   if ((BWnumber < 0) || (BWnumber > 23)) {
   1025     return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
   1026   }
   1027 
   1028   /* Reset bit-stream. */
   1029   WebRtcIsac_ResetBitstream(ISACBitStr_obj);
   1030 
   1031   /* Encode frame length */
   1032   status = WebRtcIsac_EncodeFrameLen(ISACSavedEnc_obj->framelength,
   1033                                      ISACBitStr_obj);
   1034   if (status < 0) {
   1035     /* Wrong frame size. */
   1036     return status;
   1037   }
   1038 
   1039   /* Transcoding */
   1040   if ((scale > 0.0) && (scale < 1.0)) {
   1041     /* Compensate LPC gain. */
   1042     for (ii = 0;
   1043         ii < ((ORDERLO + 1)* SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx));
   1044         ii++) {
   1045       tmpLPCcoeffs_lo[ii] = scale *  ISACSavedEnc_obj->LPCcoeffs_lo[ii];
   1046     }
   1047     for (ii = 0;
   1048         ii < ((ORDERHI + 1) * SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx));
   1049         ii++) {
   1050       tmpLPCcoeffs_hi[ii] = scale *  ISACSavedEnc_obj->LPCcoeffs_hi[ii];
   1051     }
   1052     /* Scale DFT. */
   1053     for (ii = 0;
   1054         ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx));
   1055         ii++) {
   1056       tmp_fre[ii] = (WebRtc_Word16)((scale) * (float)ISACSavedEnc_obj->fre[ii]);
   1057       tmp_fim[ii] = (WebRtc_Word16)((scale) * (float)ISACSavedEnc_obj->fim[ii]);
   1058     }
   1059   } else {
   1060     for (ii = 0;
   1061         ii < (KLT_ORDER_GAIN * (1 + ISACSavedEnc_obj->startIdx));
   1062         ii++) {
   1063       tmpLPCindex_g[ii] =  ISACSavedEnc_obj->LPCindex_g[ii];
   1064     }
   1065     for (ii = 0;
   1066         ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx));
   1067         ii++) {
   1068       tmp_fre[ii] = ISACSavedEnc_obj->fre[ii];
   1069       tmp_fim[ii] = ISACSavedEnc_obj->fim[ii];
   1070     }
   1071   }
   1072 
   1073   /* Encode bandwidth estimate. */
   1074   WebRtcIsac_EncodeReceiveBw(&BWno, ISACBitStr_obj);
   1075 
   1076   /* Loop over number of 30 msec */
   1077   for (ii = 0; ii <= ISACSavedEnc_obj->startIdx; ii++) {
   1078     /* Encode pitch gains. */
   1079     *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf;
   1080     WebRtcIsac_EncHistMulti(ISACBitStr_obj,
   1081                             &ISACSavedEnc_obj->pitchGain_index[ii],
   1082                             WebRtcIsac_kQPitchGainCdf_ptr, 1);
   1083 
   1084     /* Entropy coding of quantization pitch lags */
   1085     /* Voicing classification. */
   1086     if (ISACSavedEnc_obj->meanGain[ii] < 0.2) {
   1087       cdf = WebRtcIsac_kQPitchLagCdfPtrLo;
   1088     } else if (ISACSavedEnc_obj->meanGain[ii] < 0.4) {
   1089       cdf = WebRtcIsac_kQPitchLagCdfPtrMid;
   1090     } else {
   1091       cdf = WebRtcIsac_kQPitchLagCdfPtrHi;
   1092     }
   1093     WebRtcIsac_EncHistMulti(ISACBitStr_obj,
   1094                             &ISACSavedEnc_obj->pitchIndex[PITCH_SUBFRAMES * ii],
   1095                             cdf, PITCH_SUBFRAMES);
   1096 
   1097     /* LPC */
   1098     /* Only one model exists. The entropy coding is done only for backward
   1099      * compatibility. */
   1100     WebRtcIsac_EncHistMulti(ISACBitStr_obj, &kModel,
   1101                             WebRtcIsac_kQKltModelCdfPtr, 1);
   1102     /* Entropy coding of quantization indices - LPC shape only. */
   1103     WebRtcIsac_EncHistMulti(ISACBitStr_obj,
   1104                             &ISACSavedEnc_obj->LPCindex_s[KLT_ORDER_SHAPE * ii],
   1105                             WebRtcIsac_kQKltCdfPtrShape,
   1106                             KLT_ORDER_SHAPE);
   1107 
   1108     /* If transcoding, get new LPC gain indices */
   1109     if (scale < 1.0) {
   1110       WebRtcIsac_TranscodeLPCCoef(
   1111           &tmpLPCcoeffs_lo[(ORDERLO + 1) * SUBFRAMES * ii],
   1112           &tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * ii],
   1113           &tmpLPCindex_g[KLT_ORDER_GAIN * ii]);
   1114     }
   1115 
   1116     /* Entropy coding of quantization indices - LPC gain. */
   1117     WebRtcIsac_EncHistMulti(ISACBitStr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN * ii],
   1118                             WebRtcIsac_kQKltCdfPtrGain, KLT_ORDER_GAIN);
   1119 
   1120     /* Quantization and loss-less coding. */
   1121     status = WebRtcIsac_EncodeSpec(&tmp_fre[ii * FRAMESAMPLES_HALF],
   1122                                    &tmp_fim[ii * FRAMESAMPLES_HALF],
   1123                                    ISACSavedEnc_obj->AvgPitchGain[ii],
   1124                                    kIsacLowerBand, ISACBitStr_obj);
   1125     if (status < 0) {
   1126       return status;
   1127     }
   1128   }
   1129   /* Complete arithmetic coding. */
   1130   return WebRtcIsac_EncTerminate(ISACBitStr_obj);
   1131 }
   1132 
   1133 
   1134 int WebRtcIsac_EncodeStoredDataUb(
   1135     const ISACUBSaveEncDataStruct* ISACSavedEnc_obj,
   1136     Bitstr* bitStream,
   1137     WebRtc_Word32 jitterInfo,
   1138     float scale,
   1139     enum ISACBandwidth bandwidth) {
   1140   int n;
   1141   int err;
   1142   double lpcGain[SUBFRAMES];
   1143   WebRtc_Word16 realFFT[FRAMESAMPLES_HALF];
   1144   WebRtc_Word16 imagFFT[FRAMESAMPLES_HALF];
   1145   const WebRtc_UWord16** shape_cdf;
   1146   int shape_len;
   1147   const WebRtc_Word16 kAveragePitchGain = 0.0;
   1148   enum ISACBand band;
   1149   /* Reset bitstream. */
   1150   WebRtcIsac_ResetBitstream(bitStream);
   1151 
   1152   /* Encode jitter index. */
   1153   WebRtcIsac_EncodeJitterInfo(jitterInfo, bitStream);
   1154 
   1155   err = WebRtcIsac_EncodeBandwidth(bandwidth, bitStream);
   1156   if (err < 0) {
   1157     return err;
   1158   }
   1159 
   1160   /* Encode LPC-shape. */
   1161   if (bandwidth == isac12kHz) {
   1162     shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb12;
   1163     shape_len = UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME;
   1164     band = kIsacUpperBand12;
   1165   } else {
   1166     shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb16;
   1167     shape_len = UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME;
   1168     band = kIsacUpperBand16;
   1169   }
   1170   WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->indexLPCShape,
   1171                           shape_cdf, shape_len);
   1172 
   1173   if ((scale <= 0.0) || (scale >= 1.0)) {
   1174     /* We only consider scales between zero and one. */
   1175     WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->lpcGainIndex,
   1176                             WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM);
   1177     if (bandwidth == isac16kHz) {
   1178       /* Store gain indices of the second half. */
   1179       WebRtcIsac_EncHistMulti(bitStream,
   1180                               &ISACSavedEnc_obj->lpcGainIndex[SUBFRAMES],
   1181                               WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM);
   1182     }
   1183     /* Store FFT coefficients. */
   1184     err = WebRtcIsac_EncodeSpec(ISACSavedEnc_obj->realFFT,
   1185                                 ISACSavedEnc_obj->imagFFT, kAveragePitchGain,
   1186                                 band, bitStream);
   1187   } else {
   1188     /* Scale LPC gain and FFT coefficients. */
   1189     for (n = 0; n < SUBFRAMES; n++) {
   1190       lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n];
   1191     }
   1192     /* Store LPC gains. */
   1193     WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream);
   1194 
   1195     if (bandwidth == isac16kHz) {
   1196       /* Scale and code the gains of the second half of the frame, if 16kHz. */
   1197       for (n = 0; n < SUBFRAMES; n++) {
   1198         lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n + SUBFRAMES];
   1199       }
   1200       WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream);
   1201     }
   1202 
   1203     for (n = 0; n < FRAMESAMPLES_HALF; n++) {
   1204       realFFT[n] = (WebRtc_Word16)(scale * (float)ISACSavedEnc_obj->realFFT[n] +
   1205           0.5f);
   1206       imagFFT[n] = (WebRtc_Word16)(scale * (float)ISACSavedEnc_obj->imagFFT[n] +
   1207           0.5f);
   1208     }
   1209     /* Store FFT coefficients. */
   1210     err = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain,
   1211                                 band, bitStream);
   1212   }
   1213   if (err < 0) {
   1214     /* Error happened while encoding FFT coefficients. */
   1215     return err;
   1216   }
   1217 
   1218   /* Complete arithmetic coding. */
   1219   return WebRtcIsac_EncTerminate(bitStream);
   1220 }
   1221 
   1222 WebRtc_Word16 WebRtcIsac_GetRedPayloadUb(
   1223     const ISACUBSaveEncDataStruct* ISACSavedEncObj,
   1224     Bitstr*                        bitStreamObj,
   1225     enum ISACBandwidth             bandwidth) {
   1226   int n;
   1227   WebRtc_Word16 status;
   1228   WebRtc_Word16 realFFT[FRAMESAMPLES_HALF];
   1229   WebRtc_Word16 imagFFT[FRAMESAMPLES_HALF];
   1230   enum ISACBand band;
   1231   const WebRtc_Word16 kAveragePitchGain = 0.0;
   1232   /* Store bit-stream object. */
   1233   memcpy(bitStreamObj, &ISACSavedEncObj->bitStreamObj, sizeof(Bitstr));
   1234 
   1235   /* Scale FFT coefficients. */
   1236   for (n = 0; n < FRAMESAMPLES_HALF; n++) {
   1237     realFFT[n] = (WebRtc_Word16)((float)ISACSavedEncObj->realFFT[n] *
   1238         RCU_TRANSCODING_SCALE_UB + 0.5);
   1239     imagFFT[n] = (WebRtc_Word16)((float)ISACSavedEncObj->imagFFT[n] *
   1240         RCU_TRANSCODING_SCALE_UB + 0.5);
   1241   }
   1242 
   1243   band = (bandwidth == isac12kHz) ? kIsacUpperBand12 : kIsacUpperBand16;
   1244   status = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain, band,
   1245                                  bitStreamObj);
   1246   if (status < 0) {
   1247     return status;
   1248   } else {
   1249     /* Terminate entropy coding */
   1250     return WebRtcIsac_EncTerminate(bitStreamObj);
   1251   }
   1252 }
   1253