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