• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "rtc_base/checks.h"
19 #include "modules/audio_coding/codecs/isac/fix/source/codec.h"
20 
21 #include <stdio.h>
22 
23 #include "modules/audio_coding/codecs/isac/fix/source/arith_routins.h"
24 #include "modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.h"
25 #include "modules/audio_coding/codecs/isac/fix/source/entropy_coding.h"
26 #include "modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
27 #include "modules/audio_coding/codecs/isac/fix/source/lpc_tables.h"
28 #include "modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h"
29 #include "modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.h"
30 #include "modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.h"
31 #include "modules/audio_coding/codecs/isac/fix/source/structs.h"
32 
33 
WebRtcIsacfix_EncodeImpl(int16_t * in,IsacFixEncoderInstance * ISACenc_obj,BwEstimatorstr * bw_estimatordata,int16_t CodingMode)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       RTC_DCHECK_GE(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. */
WebRtcIsacfix_EncodeStoredData(IsacFixEncoderInstance * ISACenc_obj,int BWnumber,float scale)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