• 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 "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 
WebRtcIsacfix_EncodeImpl(WebRtc_Word16 * in,ISACFIX_EncInst_t * ISACenc_obj,BwEstimatorstr * bw_estimatordata,WebRtc_Word16 CodingMode)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. */
WebRtcIsacfix_EncodeStoredData(ISACFIX_EncInst_t * ISACenc_obj,int BWnumber,float scale)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