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
34int 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. */
492int 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