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