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  * encode.c
     13  *
     14  * Encoding function for the iSAC coder.
     15  *
     16  */
     17 
     18 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/codec.h"
     19 
     20 #include <assert.h>
     21 #include <stdio.h>
     22 
     23 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/arith_routins.h"
     24 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.h"
     25 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/entropy_coding.h"
     26 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
     27 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/lpc_tables.h"
     28 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h"
     29 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.h"
     30 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.h"
     31 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/structs.h"
     32 
     33 
     34 int WebRtcIsacfix_EncodeImpl(int16_t      *in,
     35                              IsacFixEncoderInstance  *ISACenc_obj,
     36                              BwEstimatorstr      *bw_estimatordata,
     37                              int16_t         CodingMode)
     38 {
     39   int16_t stream_length = 0;
     40   int16_t usefulstr_len = 0;
     41   int k;
     42   int16_t BWno;
     43 
     44   int16_t lofilt_coefQ15[(ORDERLO)*SUBFRAMES];
     45   int16_t hifilt_coefQ15[(ORDERHI)*SUBFRAMES];
     46   int32_t gain_lo_hiQ17[2*SUBFRAMES];
     47 
     48   int16_t LPandHP[FRAMESAMPLES/2 + QLOOKAHEAD];
     49   int16_t LP16a[FRAMESAMPLES/2 + QLOOKAHEAD];
     50   int16_t HP16a[FRAMESAMPLES/2 + QLOOKAHEAD];
     51 
     52   int16_t PitchLags_Q7[PITCH_SUBFRAMES];
     53   int16_t PitchGains_Q12[PITCH_SUBFRAMES];
     54   int16_t AvgPitchGain_Q12;
     55 
     56   int16_t frame_mode; /* 0 for 30ms, 1 for 60ms */
     57   int16_t processed_samples;
     58   int status;
     59 
     60   int32_t bits_gainsQ11;
     61   int16_t MinBytes;
     62   int16_t bmodel;
     63 
     64   transcode_obj transcodingParam;
     65   int16_t payloadLimitBytes;
     66   int16_t arithLenBeforeEncodingDFT;
     67   int16_t iterCntr;
     68 
     69   /* copy new frame length and bottle neck rate only for the first 10 ms data */
     70   if (ISACenc_obj->buffer_index == 0) {
     71     /* set the framelength for the next packet */
     72     ISACenc_obj->current_framesamples = ISACenc_obj->new_framelength;
     73   }
     74 
     75   frame_mode = ISACenc_obj->current_framesamples/MAX_FRAMESAMPLES; /* 0 (30 ms) or 1 (60 ms)  */
     76   processed_samples = ISACenc_obj->current_framesamples/(frame_mode+1); /* 480 (30, 60 ms) */
     77 
     78   /* buffer speech samples (by 10ms packet) until the framelength is reached (30 or 60 ms) */
     79   /**************************************************************************************/
     80   /* fill the buffer with 10ms input data */
     81   for(k=0; k<FRAMESAMPLES_10ms; k++) {
     82     ISACenc_obj->data_buffer_fix[k + ISACenc_obj->buffer_index] = in[k];
     83   }
     84   /* if buffersize is not equal to current framesize, and end of file is not reached yet, */
     85   /* increase index and go back to main to get more speech samples */
     86   if (ISACenc_obj->buffer_index + FRAMESAMPLES_10ms != processed_samples) {
     87     ISACenc_obj->buffer_index = ISACenc_obj->buffer_index + FRAMESAMPLES_10ms;
     88     return 0;
     89   }
     90   /* if buffer reached the right size, reset index and continue with encoding the frame */
     91   ISACenc_obj->buffer_index = 0;
     92 
     93   /* end of buffer function */
     94   /**************************/
     95 
     96   /* encoding */
     97   /************/
     98 
     99   if (frame_mode == 0 || ISACenc_obj->frame_nb == 0 )
    100   {
    101     /* reset bitstream */
    102     ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF;
    103     ISACenc_obj->bitstr_obj.streamval = 0;
    104     ISACenc_obj->bitstr_obj.stream_index = 0;
    105     ISACenc_obj->bitstr_obj.full = 1;
    106 
    107     if (CodingMode == 0) {
    108       ISACenc_obj->BottleNeck =  WebRtcIsacfix_GetUplinkBandwidth(bw_estimatordata);
    109       ISACenc_obj->MaxDelay =  WebRtcIsacfix_GetUplinkMaxDelay(bw_estimatordata);
    110     }
    111     if (CodingMode == 0 && frame_mode == 0 && (ISACenc_obj->enforceFrameSize == 0)) {
    112       ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck,
    113                                                                      ISACenc_obj->current_framesamples);
    114     }
    115 
    116     // multiply the bottleneck by 0.88 before computing SNR, 0.88 is tuned by experimenting on TIMIT
    117     // 901/1024 is 0.87988281250000
    118     ISACenc_obj->s2nr = WebRtcIsacfix_GetSnr(
    119         (int16_t)(ISACenc_obj->BottleNeck * 901 >> 10),
    120         ISACenc_obj->current_framesamples);
    121 
    122     /* encode frame length */
    123     status = WebRtcIsacfix_EncodeFrameLen(ISACenc_obj->current_framesamples, &ISACenc_obj->bitstr_obj);
    124     if (status < 0)
    125     {
    126       /* Wrong frame size */
    127       if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
    128       {
    129         // If this is the second 30ms of a 60ms frame reset this such that in the next call
    130         // encoder starts fresh.
    131         ISACenc_obj->frame_nb = 0;
    132       }
    133       return status;
    134     }
    135 
    136     /* Save framelength for multiple packets memory */
    137     if (ISACenc_obj->SaveEnc_ptr != NULL) {
    138       (ISACenc_obj->SaveEnc_ptr)->framelength=ISACenc_obj->current_framesamples;
    139     }
    140 
    141     /* bandwidth estimation and coding */
    142     BWno = WebRtcIsacfix_GetDownlinkBwIndexImpl(bw_estimatordata);
    143     status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj);
    144     if (status < 0)
    145     {
    146       if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
    147       {
    148         // If this is the second 30ms of a 60ms frame reset this such that in the next call
    149         // encoder starts fresh.
    150         ISACenc_obj->frame_nb = 0;
    151       }
    152       return status;
    153     }
    154   }
    155 
    156   /* split signal in two bands */
    157   WebRtcIsacfix_SplitAndFilter1(ISACenc_obj->data_buffer_fix, LP16a, HP16a, &ISACenc_obj->prefiltbankstr_obj );
    158 
    159   /* estimate pitch parameters and pitch-filter lookahead signal */
    160   WebRtcIsacfix_PitchAnalysis(LP16a+QLOOKAHEAD, LPandHP,
    161                               &ISACenc_obj->pitchanalysisstr_obj,  PitchLags_Q7, PitchGains_Q12); /* LPandHP = LP_lookahead_pfQ0, */
    162 
    163   /* Set where to store data in multiple packets memory */
    164   if (ISACenc_obj->SaveEnc_ptr != NULL) {
    165     if (frame_mode == 0 || ISACenc_obj->frame_nb == 0)
    166     {
    167       (ISACenc_obj->SaveEnc_ptr)->startIdx = 0;
    168     }
    169     else
    170     {
    171       (ISACenc_obj->SaveEnc_ptr)->startIdx = 1;
    172     }
    173   }
    174 
    175   /* quantize & encode pitch parameters */
    176   status = WebRtcIsacfix_EncodePitchGain(PitchGains_Q12, &ISACenc_obj->bitstr_obj,  ISACenc_obj->SaveEnc_ptr);
    177   if (status < 0)
    178   {
    179     if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
    180     {
    181       // If this is the second 30ms of a 60ms frame reset this such that in the next call
    182       // encoder starts fresh.
    183       ISACenc_obj->frame_nb = 0;
    184     }
    185     return status;
    186   }
    187   status = WebRtcIsacfix_EncodePitchLag(PitchLags_Q7 , PitchGains_Q12, &ISACenc_obj->bitstr_obj,  ISACenc_obj->SaveEnc_ptr);
    188   if (status < 0)
    189   {
    190     if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
    191     {
    192       // If this is the second 30ms of a 60ms frame reset this such that in the next call
    193       // encoder starts fresh.
    194       ISACenc_obj->frame_nb = 0;
    195     }
    196     return status;
    197   }
    198   AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] +
    199       PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2;
    200 
    201   /* find coefficients for perceptual pre-filters */
    202   WebRtcIsacfix_GetLpcCoef(LPandHP, HP16a+QLOOKAHEAD, &ISACenc_obj->maskfiltstr_obj,
    203                            ISACenc_obj->s2nr, PitchGains_Q12,
    204                            gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15); /*LPandHP = LP_lookahead_pfQ0*/
    205 
    206   // record LPC Gains for possible bit-rate reduction
    207   for(k = 0; k < KLT_ORDER_GAIN; k++)
    208   {
    209     transcodingParam.lpcGains[k] = gain_lo_hiQ17[k];
    210   }
    211 
    212   /* code LPC model and shape - gains not quantized yet */
    213   status = WebRtcIsacfix_EncodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15,
    214                                    &bmodel, &bits_gainsQ11, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr, &transcodingParam);
    215   if (status < 0)
    216   {
    217     if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
    218     {
    219       // If this is the second 30ms of a 60ms frame reset this such that in the next call
    220       // encoder starts fresh.
    221       ISACenc_obj->frame_nb = 0;
    222     }
    223     return status;
    224   }
    225   arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full);
    226 
    227   /* low-band filtering */
    228   WebRtcIsacfix_NormLatticeFilterMa(ORDERLO, ISACenc_obj->maskfiltstr_obj.PreStateLoGQ15,
    229                                     LP16a, lofilt_coefQ15, gain_lo_hiQ17, 0, LPandHP);/* LPandHP = LP16b */
    230 
    231   /* pitch filter */
    232   WebRtcIsacfix_PitchFilter(LPandHP, LP16a, &ISACenc_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 1);/* LPandHP = LP16b */
    233 
    234   /* high-band filtering */
    235   WebRtcIsacfix_NormLatticeFilterMa(ORDERHI, ISACenc_obj->maskfiltstr_obj.PreStateHiGQ15,
    236                                     HP16a, hifilt_coefQ15, gain_lo_hiQ17, 1, LPandHP);/*LPandHP = HP16b*/
    237 
    238   /* transform */
    239   WebRtcIsacfix_Time2Spec(LP16a, LPandHP, LP16a, LPandHP); /*LPandHP = HP16b*/
    240 
    241   /* Save data for multiple packets memory */
    242   if (ISACenc_obj->SaveEnc_ptr != NULL) {
    243     for (k = 0; k < FRAMESAMPLES_HALF; k++) {
    244       (ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k];
    245       (ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k];
    246     }
    247     (ISACenc_obj->SaveEnc_ptr)->AvgPitchGain[(ISACenc_obj->SaveEnc_ptr)->startIdx] = AvgPitchGain_Q12;
    248   }
    249 
    250   /* quantization and lossless coding */
    251   status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12);
    252   if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/
    253   {
    254     if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
    255     {
    256       // If this is the second 30ms of a 60ms frame reset this such that in the next call
    257       // encoder starts fresh.
    258       ISACenc_obj->frame_nb = 0;
    259     }
    260     return status;
    261   }
    262 
    263   if((frame_mode == 1) && (ISACenc_obj->frame_nb == 0))
    264   {
    265     // it is a 60ms and we are in the first 30ms
    266     // then the limit at this point should be half of the assigned value
    267     payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 >> 1;
    268   }
    269   else if (frame_mode == 0)
    270   {
    271     // it is a 30ms frame
    272     payloadLimitBytes = (ISACenc_obj->payloadLimitBytes30) - 3;
    273   }
    274   else
    275   {
    276     // this is the second half of a 60ms frame.
    277     payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 - 3; // subract 3 because termination process may add 3 bytes
    278   }
    279 
    280   iterCntr = 0;
    281   while((((ISACenc_obj->bitstr_obj.stream_index) << 1) > payloadLimitBytes) ||
    282         (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH))
    283   {
    284     int16_t arithLenDFTByte;
    285     int16_t bytesLeftQ5;
    286     int16_t ratioQ5[8] = {0, 6, 9, 12, 16, 19, 22, 25};
    287 
    288     // According to experiments on TIMIT the following is proper for audio, but it is not agressive enough for tonal inputs
    289     // such as DTMF, sweep-sine, ...
    290     //
    291     // (0.55 - (0.8 - ratio[i]/32) * 5 / 6) * 2^14
    292     // int16_t scaleQ14[8] = {0, 648, 1928, 3208, 4915, 6195, 7475, 8755};
    293 
    294 
    295     // This is a supper-agressive scaling passed the tests (tonal inputs) tone with one iteration for payload limit
    296     // of 120 (32kbps bottleneck), number of frames needed a rate-reduction was 58403
    297     //
    298     int16_t scaleQ14[8] = {0, 348, 828, 1408, 2015, 3195, 3500, 3500};
    299     int16_t idx;
    300 
    301     if(iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION)
    302     {
    303       // We were not able to limit the payload size
    304 
    305       if((frame_mode == 1) && (ISACenc_obj->frame_nb == 0))
    306       {
    307         // This was the first 30ms of a 60ms frame. Although the payload is larger than it
    308         // should be but we let the second 30ms be encoded. Maybe togetehr we won't exceed
    309         // the limit.
    310         ISACenc_obj->frame_nb = 1;
    311         return 0;
    312       }
    313       else if((frame_mode == 1) && (ISACenc_obj->frame_nb == 1))
    314       {
    315         ISACenc_obj->frame_nb = 0;
    316       }
    317 
    318       if(status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)
    319       {
    320         return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
    321       }
    322       else
    323       {
    324         return status;
    325       }
    326     }
    327     if(status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)
    328     {
    329       arithLenDFTByte = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full) - arithLenBeforeEncodingDFT;
    330       bytesLeftQ5 = (payloadLimitBytes - arithLenBeforeEncodingDFT) << 5;
    331 
    332       // bytesLeft / arithLenDFTBytes indicates how much scaling is required a rough estimate (agressive)
    333       // scale = 0.55 - (0.8 - bytesLeft / arithLenDFTBytes) * 5 / 6
    334       // bytesLeft / arithLenDFTBytes below 0.2 will have a scale of zero and above 0.8 are treated as 0.8
    335       // to avoid division we do more simplification.
    336       //
    337       // values of (bytesLeft / arithLenDFTBytes)*32 between ratioQ5[i] and ratioQ5[i+1] are rounded to ratioQ5[i]
    338       // and the corresponding scale is chosen
    339 
    340       // we compare bytesLeftQ5 with ratioQ5[]*arithLenDFTByte;
    341       idx = 4;
    342       idx += (bytesLeftQ5 >= ratioQ5[idx] * arithLenDFTByte) ? 2 : -2;
    343       idx += (bytesLeftQ5 >= ratioQ5[idx] * arithLenDFTByte) ? 1 : -1;
    344       idx += (bytesLeftQ5 >= ratioQ5[idx] * arithLenDFTByte) ? 0 : -1;
    345     }
    346     else
    347     {
    348       // we are here because the bit-stream did not fit into the buffer, in this case, the stream_index is not
    349       // trustable, especially if the is the first 30ms of a packet. Thereforem, we will go for the most agressive
    350       // case.
    351       idx = 0;
    352     }
    353     // scale FFT coefficients to reduce the bit-rate
    354     for(k = 0; k < FRAMESAMPLES_HALF; k++)
    355     {
    356       LP16a[k] = (int16_t)(LP16a[k] * scaleQ14[idx] >> 14);
    357       LPandHP[k] = (int16_t)(LPandHP[k] * scaleQ14[idx] >> 14);
    358     }
    359 
    360     // Save data for multiple packets memory
    361     if (ISACenc_obj->SaveEnc_ptr != NULL)
    362     {
    363       for(k = 0; k < FRAMESAMPLES_HALF; k++)
    364       {
    365         (ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k];
    366         (ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k];
    367       }
    368     }
    369 
    370     // scale the unquantized LPC gains and save the scaled version for the future use
    371     for(k = 0; k < KLT_ORDER_GAIN; k++)
    372     {
    373       gain_lo_hiQ17[k] = WEBRTC_SPL_MUL_16_32_RSFT14(scaleQ14[idx], transcodingParam.lpcGains[k]);//transcodingParam.lpcGains[k]; //
    374       transcodingParam.lpcGains[k] = gain_lo_hiQ17[k];
    375     }
    376 
    377     // reset the bit-stream object to the state which it had before encoding LPC Gains
    378     ISACenc_obj->bitstr_obj.full = transcodingParam.full;
    379     ISACenc_obj->bitstr_obj.stream_index = transcodingParam.stream_index;
    380     ISACenc_obj->bitstr_obj.streamval = transcodingParam.streamval;
    381     ISACenc_obj->bitstr_obj.W_upper = transcodingParam.W_upper;
    382     ISACenc_obj->bitstr_obj.stream[transcodingParam.stream_index-1] = transcodingParam.beforeLastWord;
    383     ISACenc_obj->bitstr_obj.stream[transcodingParam.stream_index] = transcodingParam.lastWord;
    384 
    385 
    386     // quantize and encode LPC gain
    387     WebRtcIsacfix_EstCodeLpcGain(gain_lo_hiQ17, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr);
    388     arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full);
    389     status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12);
    390     if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/
    391     {
    392       if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
    393       {
    394         // If this is the second 30ms of a 60ms frame reset this such that in the next call
    395         // encoder starts fresh.
    396         ISACenc_obj->frame_nb = 0;
    397       }
    398       return status;
    399     }
    400     iterCntr++;
    401   }
    402 
    403   if (frame_mode == 1 && ISACenc_obj->frame_nb == 0)
    404     /* i.e. 60 ms framesize and just processed the first 30ms, */
    405     /* go back to main function to buffer the other 30ms speech frame */
    406   {
    407     ISACenc_obj->frame_nb = 1;
    408     return 0;
    409   }
    410   else if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
    411   {
    412     ISACenc_obj->frame_nb = 0;
    413     /* also update the framelength for next packet, in Adaptive mode only */
    414     if (CodingMode == 0 && (ISACenc_obj->enforceFrameSize == 0)) {
    415       ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck,
    416                                                                      ISACenc_obj->current_framesamples);
    417     }
    418   }
    419 
    420 
    421   /* complete arithmetic coding */
    422   stream_length = WebRtcIsacfix_EncTerminate(&ISACenc_obj->bitstr_obj);
    423   /* can this be negative? */
    424 
    425   if(CodingMode == 0)
    426   {
    427 
    428     /* update rate model and get minimum number of bytes in this packet */
    429     MinBytes = WebRtcIsacfix_GetMinBytes(&ISACenc_obj->rate_data_obj, (int16_t) stream_length,
    430                                          ISACenc_obj->current_framesamples, ISACenc_obj->BottleNeck, ISACenc_obj->MaxDelay);
    431 
    432     /* if bitstream is too short, add garbage at the end */
    433 
    434     /* Store length of coded data */
    435     usefulstr_len = stream_length;
    436 
    437     /* Make sure MinBytes does not exceed packet size limit */
    438     if ((ISACenc_obj->frame_nb == 0) && (MinBytes > ISACenc_obj->payloadLimitBytes30)) {
    439       MinBytes = ISACenc_obj->payloadLimitBytes30;
    440     } else if ((ISACenc_obj->frame_nb == 1) && (MinBytes > ISACenc_obj->payloadLimitBytes60)) {
    441       MinBytes = ISACenc_obj->payloadLimitBytes60;
    442     }
    443 
    444     /* Make sure we don't allow more than 255 bytes of garbage data.
    445        We store the length of the garbage data in 8 bits in the bitstream,
    446        255 is the max garbage lenght we can signal using 8 bits. */
    447     if( MinBytes > usefulstr_len + 255 ) {
    448       MinBytes = usefulstr_len + 255;
    449     }
    450 
    451     /* Save data for creation of multiple bitstreams */
    452     if (ISACenc_obj->SaveEnc_ptr != NULL) {
    453       (ISACenc_obj->SaveEnc_ptr)->minBytes = MinBytes;
    454     }
    455 
    456     while (stream_length < MinBytes)
    457     {
    458       assert(stream_length >= 0);
    459       if (stream_length & 0x0001){
    460         ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed );
    461         ISACenc_obj->bitstr_obj.stream[stream_length / 2] |=
    462             (uint16_t)(ISACenc_obj->bitstr_seed & 0xFF);
    463       } else {
    464         ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed );
    465         ISACenc_obj->bitstr_obj.stream[stream_length / 2] =
    466             ((uint16_t)ISACenc_obj->bitstr_seed << 8);
    467       }
    468       stream_length++;
    469     }
    470 
    471     /* to get the real stream_length, without garbage */
    472     if (usefulstr_len & 0x0001) {
    473       ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] &= 0xFF00;
    474       ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] += (MinBytes - usefulstr_len) & 0x00FF;
    475     }
    476     else {
    477       ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] &= 0x00FF;
    478       ISACenc_obj->bitstr_obj.stream[usefulstr_len >> 1] +=
    479           ((uint16_t)((MinBytes - usefulstr_len) & 0x00FF) << 8);
    480     }
    481   }
    482   else
    483   {
    484     /* update rate model */
    485     WebRtcIsacfix_UpdateRateModel(&ISACenc_obj->rate_data_obj, (int16_t) stream_length,
    486                                   ISACenc_obj->current_framesamples, ISACenc_obj->BottleNeck);
    487   }
    488   return stream_length;
    489 }
    490 
    491 /* This function is used to create a new bitstream with new BWE.
    492    The same data as previously encoded with the fucntion WebRtcIsacfix_EncodeImpl()
    493    is used. The data needed is taken from the struct, where it was stored
    494    when calling the encoder. */
    495 int WebRtcIsacfix_EncodeStoredData(IsacFixEncoderInstance  *ISACenc_obj,
    496                                    int     BWnumber,
    497                                    float              scale)
    498 {
    499   int ii;
    500   int status;
    501   int16_t BWno = (int16_t)BWnumber;
    502   int stream_length = 0;
    503 
    504   int16_t model;
    505   const uint16_t *Q_PitchGain_cdf_ptr[1];
    506   const uint16_t **cdf;
    507   const IsacSaveEncoderData *SaveEnc_str;
    508   int32_t tmpLPCcoeffs_g[KLT_ORDER_GAIN<<1];
    509   int16_t tmpLPCindex_g[KLT_ORDER_GAIN<<1];
    510   int16_t tmp_fre[FRAMESAMPLES];
    511   int16_t tmp_fim[FRAMESAMPLES];
    512 
    513   SaveEnc_str = ISACenc_obj->SaveEnc_ptr;
    514 
    515   /* Check if SaveEnc memory exists */
    516   if (SaveEnc_str == NULL) {
    517     return (-1);
    518   }
    519 
    520   /* Sanity Check - possible values for BWnumber is 0 - 23 */
    521   if ((BWnumber < 0) || (BWnumber > 23)) {
    522     return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
    523   }
    524 
    525   /* reset bitstream */
    526   ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF;
    527   ISACenc_obj->bitstr_obj.streamval = 0;
    528   ISACenc_obj->bitstr_obj.stream_index = 0;
    529   ISACenc_obj->bitstr_obj.full = 1;
    530 
    531   /* encode frame length */
    532   status = WebRtcIsacfix_EncodeFrameLen(SaveEnc_str->framelength, &ISACenc_obj->bitstr_obj);
    533   if (status < 0) {
    534     /* Wrong frame size */
    535     return status;
    536   }
    537 
    538   /* encode bandwidth estimate */
    539   status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj);
    540   if (status < 0) {
    541     return status;
    542   }
    543 
    544   /* Transcoding                                                 */
    545   /* If scale < 1, rescale data to produce lower bitrate signal  */
    546   if ((0.0 < scale) && (scale < 1.0)) {
    547     /* Compensate LPC gain */
    548     for (ii = 0; ii < (KLT_ORDER_GAIN*(1+SaveEnc_str->startIdx)); ii++) {
    549       tmpLPCcoeffs_g[ii] = (int32_t) ((scale) * (float) SaveEnc_str->LPCcoeffs_g[ii]);
    550     }
    551 
    552     /* Scale DFT */
    553     for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) {
    554       tmp_fre[ii] = (int16_t) ((scale) * (float) SaveEnc_str->fre[ii]) ;
    555       tmp_fim[ii] = (int16_t) ((scale) * (float) SaveEnc_str->fim[ii]) ;
    556     }
    557   } else {
    558     for (ii = 0; ii < (KLT_ORDER_GAIN*(1+SaveEnc_str->startIdx)); ii++) {
    559       tmpLPCindex_g[ii] =  SaveEnc_str->LPCindex_g[ii];
    560     }
    561 
    562     for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) {
    563       tmp_fre[ii] = SaveEnc_str->fre[ii];
    564       tmp_fim[ii] = SaveEnc_str->fim[ii];
    565     }
    566   }
    567 
    568   /* Loop over number of 30 msec */
    569   for (ii = 0; ii <= SaveEnc_str->startIdx; ii++)
    570   {
    571 
    572     /* encode pitch gains */
    573     *Q_PitchGain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf;
    574     status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &SaveEnc_str->pitchGain_index[ii],
    575                                        Q_PitchGain_cdf_ptr, 1);
    576     if (status < 0) {
    577       return status;
    578     }
    579 
    580     /* entropy coding of quantization pitch lags */
    581     /* voicing classificiation */
    582     if (SaveEnc_str->meanGain[ii] <= 819) {
    583       cdf = WebRtcIsacfix_kPitchLagPtrLo;
    584     } else if (SaveEnc_str->meanGain[ii] <= 1638) {
    585       cdf = WebRtcIsacfix_kPitchLagPtrMid;
    586     } else {
    587       cdf = WebRtcIsacfix_kPitchLagPtrHi;
    588     }
    589     status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj,
    590                                        &SaveEnc_str->pitchIndex[PITCH_SUBFRAMES*ii], cdf, PITCH_SUBFRAMES);
    591     if (status < 0) {
    592       return status;
    593     }
    594 
    595     /* LPC */
    596     /* entropy coding of model number */
    597     model = 0;
    598     status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj,  &model,
    599                                        WebRtcIsacfix_kModelCdfPtr, 1);
    600     if (status < 0) {
    601       return status;
    602     }
    603 
    604     /* entropy coding of quantization indices - LPC shape only */
    605     status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &SaveEnc_str->LPCindex_s[KLT_ORDER_SHAPE*ii],
    606                                        WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE);
    607     if (status < 0) {
    608       return status;
    609     }
    610 
    611     /* If transcoding, get new LPC gain indices */
    612     if (scale < 1.0) {
    613       WebRtcIsacfix_TranscodeLpcCoef(&tmpLPCcoeffs_g[KLT_ORDER_GAIN*ii], &tmpLPCindex_g[KLT_ORDER_GAIN*ii]);
    614     }
    615 
    616     /* entropy coding of quantization indices - LPC gain */
    617     status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN*ii],
    618                                        WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN);
    619     if (status < 0) {
    620       return status;
    621     }
    622 
    623     /* quantization and lossless coding */
    624     status = WebRtcIsacfix_EncodeSpec(&tmp_fre[ii*FRAMESAMPLES_HALF], &tmp_fim[ii*FRAMESAMPLES_HALF],
    625                                       &ISACenc_obj->bitstr_obj, SaveEnc_str->AvgPitchGain[ii]);
    626     if (status < 0) {
    627       return status;
    628     }
    629   }
    630 
    631   /* complete arithmetic coding */
    632   stream_length = WebRtcIsacfix_EncTerminate(&ISACenc_obj->bitstr_obj);
    633 
    634   return stream_length;
    635 }
    636