1 /*
2  *  Copyright (c) 2012 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  * This file contains definition of funtions for encoding.
15  * Decoding of upper-band, including 8-12 kHz, when the bandwidth is
16  * 0-12 kHz, and 8-16 kHz, when the bandwidth is 0-16 kHz.
17  *
18  */
19 
20 #include <stdlib.h>
21 #include <string.h>
22 #include <stdio.h>
23 
24 #include "structs.h"
25 #include "codec.h"
26 #include "pitch_estimator.h"
27 #include "entropy_coding.h"
28 #include "arith_routines.h"
29 #include "pitch_gain_tables.h"
30 #include "pitch_lag_tables.h"
31 #include "spectrum_ar_model_tables.h"
32 #include "lpc_tables.h"
33 #include "lpc_analysis.h"
34 #include "bandwidth_estimator.h"
35 #include "lpc_shape_swb12_tables.h"
36 #include "lpc_shape_swb16_tables.h"
37 #include "lpc_gain_swb_tables.h"
38 
39 
40 #define UB_LOOKAHEAD 24
41 
42 
43 /*
44   Rate allocation tables of lower and upper-band bottleneck for
45   12kHz & 16kHz bandwidth.
46 
47   12 kHz bandwidth
48   -----------------
49   The overall bottleneck of the coder is between 38 kbps and 45 kbps. We have
50   considered 7 enteries, uniformly distributed in this interval, i.e. 38,
51   39.17, 40.33, 41.5, 42.67, 43.83 and 45. For every entery, the lower-band
52   and the upper-band bottlenecks are specified in
53   'kLowerBandBitRate12' and 'kUpperBandBitRate12'
54   tables, respectively. E.g. the overall rate of 41.5 kbps corresponts to a
55   bottleneck of 31 kbps for lower-band and 27 kbps for upper-band. Given an
56   overall bottleneck of the codec, we use linear interpolation to get
57   lower-band and upper-band bottlenecks.
58 
59   16 kHz bandwidth
60   -----------------
61   The overall bottleneck of the coder is between 50 kbps and 56 kbps. We have
62   considered 7 enteries, uniformly distributed in this interval, i.e. 50, 51.2,
63   52.4, 53.6, 54.8 and 56. For every entery, the lower-band and the upper-band
64   bottlenecks are specified in 'kLowerBandBitRate16' and
65   'kUpperBandBitRate16' tables, respectively. E.g. the overall rate
66   of 53.6 kbps corresponts to a bottleneck of 32 kbps for lower-band and 30
67   kbps for upper-band. Given an overall bottleneck of the codec, we use linear
68   interpolation to get lower-band and upper-band bottlenecks.
69 
70  */
71 
72 /*     38  39.17  40.33   41.5  42.67  43.83     45 */
73 static const WebRtc_Word16 kLowerBandBitRate12[7] = {
74     29000, 30000, 30000, 31000, 31000, 32000, 32000 };
75 static const WebRtc_Word16 kUpperBandBitRate12[7] = {
76     25000, 25000, 27000, 27000, 29000, 29000, 32000 };
77 
78 /*    50     51.2  52.4   53.6   54.8    56 */
79 static const WebRtc_Word16 kLowerBandBitRate16[6] = {
80     31000, 31000, 32000, 32000, 32000, 32000 };
81 static const WebRtc_Word16 kUpperBandBitRate16[6] = {
82     28000, 29000, 29000, 30000, 31000, 32000 };
83 
84 /******************************************************************************
85  * WebRtcIsac_RateAllocation()
86  * Internal function to perform a rate-allocation for upper and lower-band,
87  * given a total rate.
88  *
89  * Input:
90  *   - inRateBitPerSec           : a total bottleneck in bits/sec.
91  *
92  * Output:
93  *   - rateLBBitPerSec           : a bottleneck allocated to the lower-band
94  *                                 in bits/sec.
95  *   - rateUBBitPerSec           : a bottleneck allocated to the upper-band
96  *                                 in bits/sec.
97  *
98  * Return value                  : 0 if rate allocation has been successful.
99  *                                -1 if failed to allocate rates.
100  */
101 
WebRtcIsac_RateAllocation(WebRtc_Word32 inRateBitPerSec,double * rateLBBitPerSec,double * rateUBBitPerSec,enum ISACBandwidth * bandwidthKHz)102 WebRtc_Word16 WebRtcIsac_RateAllocation(WebRtc_Word32 inRateBitPerSec,
103                                         double* rateLBBitPerSec,
104                                         double* rateUBBitPerSec,
105                                         enum ISACBandwidth* bandwidthKHz) {
106   WebRtc_Word16 idx;
107   double idxD;
108   double idxErr;
109   if (inRateBitPerSec < 38000) {
110     /* If the given overall bottleneck is less than 38000 then
111      * then codec has to operate in wideband mode, i.e. 8 kHz
112      * bandwidth. */
113     *rateLBBitPerSec = (WebRtc_Word16)((inRateBitPerSec > 32000) ?
114         32000 : inRateBitPerSec);
115     *rateUBBitPerSec = 0;
116     *bandwidthKHz = isac8kHz;
117   } else if ((inRateBitPerSec >= 38000) && (inRateBitPerSec < 50000)) {
118     /* At a bottleneck between 38 and 50 kbps the codec is operating
119      * at 12 kHz bandwidth. Using xxxBandBitRate12[] to calculates
120      * upper/lower bottleneck */
121 
122     /* Find the bottlenecks by linear interpolation,
123      * step is (45000 - 38000)/6.0 we use the inverse of it. */
124     const double stepSizeInv = 8.5714286e-4;
125     idxD = (inRateBitPerSec - 38000) * stepSizeInv;
126     idx = (idxD >= 6) ? 6 : ((WebRtc_Word16)idxD);
127     idxErr = idxD - idx;
128     *rateLBBitPerSec = kLowerBandBitRate12[idx];
129     *rateUBBitPerSec = kUpperBandBitRate12[idx];
130 
131     if (idx < 6) {
132       *rateLBBitPerSec += (WebRtc_Word16)(
133           idxErr * (kLowerBandBitRate12[idx + 1] - kLowerBandBitRate12[idx]));
134       *rateUBBitPerSec += (WebRtc_Word16)(
135           idxErr * (kUpperBandBitRate12[idx + 1] - kUpperBandBitRate12[idx]));
136     }
137     *bandwidthKHz = isac12kHz;
138   } else if ((inRateBitPerSec >= 50000) && (inRateBitPerSec <= 56000)) {
139     /* A bottleneck between 50 and 56 kbps corresponds to bandwidth
140      * of 16 kHz. Using xxxBandBitRate16[] to calculates
141      * upper/lower bottleneck. */
142 
143     /* Find the bottlenecks by linear interpolation
144      * step is (56000 - 50000)/5 we use the inverse of it. */
145     const double stepSizeInv = 8.3333333e-4;
146     idxD = (inRateBitPerSec - 50000) * stepSizeInv;
147     idx = (idxD >= 5) ? 5 : ((WebRtc_Word16)idxD);
148     idxErr = idxD - idx;
149     *rateLBBitPerSec = kLowerBandBitRate16[idx];
150     *rateUBBitPerSec  = kUpperBandBitRate16[idx];
151 
152     if (idx < 5) {
153       *rateLBBitPerSec += (WebRtc_Word16)(idxErr *
154           (kLowerBandBitRate16[idx + 1] -
155               kLowerBandBitRate16[idx]));
156 
157       *rateUBBitPerSec += (WebRtc_Word16)(idxErr *
158           (kUpperBandBitRate16[idx + 1] -
159               kUpperBandBitRate16[idx]));
160     }
161     *bandwidthKHz = isac16kHz;
162   } else {
163     /* Out-of-range botlteneck value. */
164     return -1;
165   }
166 
167   /* limit the values. */
168   *rateLBBitPerSec = (*rateLBBitPerSec > 32000) ? 32000 : *rateLBBitPerSec;
169   *rateUBBitPerSec = (*rateUBBitPerSec > 32000) ? 32000 : *rateUBBitPerSec;
170   return 0;
171 }
172 
173 
WebRtcIsac_ResetBitstream(Bitstr * bit_stream)174 void WebRtcIsac_ResetBitstream(Bitstr* bit_stream) {
175   bit_stream->W_upper = 0xFFFFFFFF;
176   bit_stream->stream_index = 0;
177   bit_stream->streamval = 0;
178 }
179 
WebRtcIsac_EncodeLb(float * in,ISACLBEncStruct * ISACencLB_obj,WebRtc_Word16 codingMode,WebRtc_Word16 bottleneckIndex)180 int WebRtcIsac_EncodeLb(float* in, ISACLBEncStruct* ISACencLB_obj,
181                         WebRtc_Word16 codingMode,
182                         WebRtc_Word16 bottleneckIndex) {
183   int stream_length = 0;
184   int err;
185   int k;
186   int iterCntr;
187 
188   double lofilt_coef[(ORDERLO + 1)*SUBFRAMES];
189   double hifilt_coef[(ORDERHI + 1)*SUBFRAMES];
190   float LP[FRAMESAMPLES_HALF];
191   float HP[FRAMESAMPLES_HALF];
192 
193   double LP_lookahead[FRAMESAMPLES_HALF];
194   double HP_lookahead[FRAMESAMPLES_HALF];
195   double LP_lookahead_pf[FRAMESAMPLES_HALF + QLOOKAHEAD];
196   double LPw[FRAMESAMPLES_HALF];
197 
198   double HPw[FRAMESAMPLES_HALF];
199   double LPw_pf[FRAMESAMPLES_HALF];
200   WebRtc_Word16 fre[FRAMESAMPLES_HALF];   /* Q7 */
201   WebRtc_Word16 fim[FRAMESAMPLES_HALF];   /* Q7 */
202 
203   double PitchLags[4];
204   double PitchGains[4];
205   WebRtc_Word16 PitchGains_Q12[4];
206   WebRtc_Word16 AvgPitchGain_Q12;
207 
208   int frame_mode; /* 0 for 30ms, 1 for 60ms */
209   int status = 0;
210   int my_index;
211   transcode_obj transcodingParam;
212   double bytesLeftSpecCoding;
213   WebRtc_UWord16 payloadLimitBytes;
214 
215   /* Copy new frame-length and bottleneck rate only for the first 10 ms data */
216   if (ISACencLB_obj->buffer_index == 0) {
217     /* Set the framelength for the next packet. */
218     ISACencLB_obj->current_framesamples = ISACencLB_obj->new_framelength;
219   }
220   /* 'frame_mode' is 0 (30 ms) or 1 (60 ms). */
221   frame_mode = ISACencLB_obj->current_framesamples / MAX_FRAMESAMPLES;
222 
223   /* buffer speech samples (by 10ms packet) until the frame-length */
224   /* is reached (30 or 60 ms).                                     */
225   /*****************************************************************/
226 
227   /* fill the buffer with 10ms input data */
228   for (k = 0; k < FRAMESAMPLES_10ms; k++) {
229     ISACencLB_obj->data_buffer_float[k + ISACencLB_obj->buffer_index] = in[k];
230   }
231 
232   /* If buffersize is not equal to current framesize then increase index
233    * and return. We do no encoding untill we have enough audio.  */
234   if (ISACencLB_obj->buffer_index + FRAMESAMPLES_10ms != FRAMESAMPLES) {
235     ISACencLB_obj->buffer_index += FRAMESAMPLES_10ms;
236     return 0;
237   }
238   /* If buffer reached the right size, reset index and continue with
239    * encoding the frame. */
240   ISACencLB_obj->buffer_index = 0;
241 
242   /* End of buffer function. */
243   /**************************/
244 
245   /* Encoding */
246   /************/
247 
248   if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) {
249     /* This is to avoid Linux warnings until we change 'int' to 'Word32'
250      * at all places. */
251     int intVar;
252     /* reset bitstream */
253     WebRtcIsac_ResetBitstream(&(ISACencLB_obj->bitstr_obj));
254 
255     if ((codingMode == 0) && (frame_mode == 0) &&
256         (ISACencLB_obj->enforceFrameSize == 0)) {
257       ISACencLB_obj->new_framelength = WebRtcIsac_GetNewFrameLength(
258           ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples);
259     }
260 
261     ISACencLB_obj->s2nr = WebRtcIsac_GetSnr(
262         ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples);
263 
264     /* Encode frame length. */
265     status = WebRtcIsac_EncodeFrameLen(
266         ISACencLB_obj->current_framesamples, &ISACencLB_obj->bitstr_obj);
267     if (status < 0) {
268       /* Wrong frame size. */
269       return status;
270     }
271     /* Save framelength for multiple packets memory. */
272     ISACencLB_obj->SaveEnc_obj.framelength =
273         ISACencLB_obj->current_framesamples;
274 
275     /* To be used for Redundant Coding. */
276     ISACencLB_obj->lastBWIdx = bottleneckIndex;
277     intVar = (int)bottleneckIndex;
278     WebRtcIsac_EncodeReceiveBw(&intVar, &ISACencLB_obj->bitstr_obj);
279   }
280 
281   /* Split signal in two bands. */
282   WebRtcIsac_SplitAndFilterFloat(ISACencLB_obj->data_buffer_float, LP, HP,
283                                  LP_lookahead, HP_lookahead,
284                                  &ISACencLB_obj->prefiltbankstr_obj);
285 
286   /* estimate pitch parameters and pitch-filter lookahead signal */
287   WebRtcIsac_PitchAnalysis(LP_lookahead, LP_lookahead_pf,
288                            &ISACencLB_obj->pitchanalysisstr_obj, PitchLags,
289                            PitchGains);
290 
291   /* Encode in FIX Q12. */
292 
293   /* Convert PitchGain to Fixed point. */
294   for (k = 0; k < PITCH_SUBFRAMES; k++) {
295     PitchGains_Q12[k] = (WebRtc_Word16)(PitchGains[k] * 4096.0);
296   }
297 
298   /* Set where to store data in multiple packets memory. */
299   if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) {
300     ISACencLB_obj->SaveEnc_obj.startIdx = 0;
301   } else {
302     ISACencLB_obj->SaveEnc_obj.startIdx = 1;
303   }
304 
305   /* Quantize & encode pitch parameters. */
306   WebRtcIsac_EncodePitchGain(PitchGains_Q12, &ISACencLB_obj->bitstr_obj,
307                              &ISACencLB_obj->SaveEnc_obj);
308   WebRtcIsac_EncodePitchLag(PitchLags, PitchGains_Q12,
309                             &ISACencLB_obj->bitstr_obj,
310                             &ISACencLB_obj->SaveEnc_obj);
311 
312   AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] +
313       PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2;
314 
315   /* Find coefficients for perceptual pre-filters. */
316   WebRtcIsac_GetLpcCoefLb(LP_lookahead_pf, HP_lookahead,
317                           &ISACencLB_obj->maskfiltstr_obj, ISACencLB_obj->s2nr,
318                           PitchGains_Q12, lofilt_coef, hifilt_coef);
319 
320   /* Code LPC model and shape - gains not quantized yet. */
321   WebRtcIsac_EncodeLpcLb(lofilt_coef, hifilt_coef, &ISACencLB_obj->bitstr_obj,
322                          &ISACencLB_obj->SaveEnc_obj);
323 
324   /* Convert PitchGains back to FLOAT for pitchfilter_pre. */
325   for (k = 0; k < 4; k++) {
326     PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096;
327   }
328 
329   /* Store the state of arithmetic coder before coding LPC gains. */
330   transcodingParam.W_upper = ISACencLB_obj->bitstr_obj.W_upper;
331   transcodingParam.stream_index = ISACencLB_obj->bitstr_obj.stream_index;
332   transcodingParam.streamval = ISACencLB_obj->bitstr_obj.streamval;
333   transcodingParam.stream[0] =
334       ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index -
335                                        2];
336   transcodingParam.stream[1] =
337       ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index -
338                                        1];
339   transcodingParam.stream[2] =
340       ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index];
341 
342   /* Store LPC Gains before encoding them. */
343   for (k = 0; k < SUBFRAMES; k++) {
344     transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k];
345     transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k];
346   }
347 
348   /* Code gains */
349   WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef,
350                              &ISACencLB_obj->bitstr_obj,
351                              &ISACencLB_obj->SaveEnc_obj);
352 
353   /* Get the correct value for the payload limit and calculate the
354    * number of bytes left for coding the spectrum. */
355   if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) {
356     /* It is a 60ms and we are in the first 30ms then the limit at
357      * this point should be half of the assigned value. */
358     payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 >> 1;
359   } else if (frame_mode == 0) {
360     /* It is a 30ms frame */
361     /* Subract 3 because termination process may add 3 bytes. */
362     payloadLimitBytes = ISACencLB_obj->payloadLimitBytes30 - 3;
363   } else {
364     /* This is the second half of a 60ms frame. */
365     /* Subract 3 because termination process may add 3 bytes. */
366     payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 - 3;
367   }
368   bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index;
369 
370   /* Perceptual pre-filtering (using normalized lattice filter). */
371   /* Low-band filtering. */
372   WebRtcIsac_NormLatticeFilterMa(ORDERLO,
373                                  ISACencLB_obj->maskfiltstr_obj.PreStateLoF,
374                                  ISACencLB_obj->maskfiltstr_obj.PreStateLoG,
375                                  LP, lofilt_coef, LPw);
376   /* High-band filtering. */
377   WebRtcIsac_NormLatticeFilterMa(ORDERHI,
378                                  ISACencLB_obj->maskfiltstr_obj.PreStateHiF,
379                                  ISACencLB_obj->maskfiltstr_obj.PreStateHiG,
380                                  HP, hifilt_coef, HPw);
381   /* Pitch filter. */
382   WebRtcIsac_PitchfilterPre(LPw, LPw_pf, &ISACencLB_obj->pitchfiltstr_obj,
383                             PitchLags, PitchGains);
384   /* Transform */
385   WebRtcIsac_Time2Spec(LPw_pf, HPw, fre, fim, &ISACencLB_obj->fftstr_obj);
386 
387   /* Save data for multiple packets memory. */
388   my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF;
389   memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre));
390   memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim));
391 
392   ISACencLB_obj->SaveEnc_obj.AvgPitchGain[ISACencLB_obj->SaveEnc_obj.startIdx] =
393       AvgPitchGain_Q12;
394 
395   /* Quantization and loss-less coding. */
396   err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand,
397                               &ISACencLB_obj->bitstr_obj);
398   if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
399     /* There has been an error but it was not too large payload
400        (we can cure too large payload). */
401     if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) {
402       /* If this is the second 30ms of a 60ms frame reset
403          this such that in the next call encoder starts fresh. */
404       ISACencLB_obj->frame_nb = 0;
405     }
406     return err;
407   }
408   iterCntr = 0;
409   while ((ISACencLB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
410       (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
411     double bytesSpecCoderUsed;
412     double transcodeScale;
413 
414     if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) {
415       /* We were not able to limit the payload size */
416       if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) {
417         /* This was the first 30ms of a 60ms frame. Although
418            the payload is larger than it should be but we let
419            the second 30ms be encoded. Maybe together we
420            won't exceed the limit. */
421         ISACencLB_obj->frame_nb = 1;
422         return 0;
423       } else if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 1)) {
424         ISACencLB_obj->frame_nb = 0;
425       }
426 
427       if (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
428         return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
429       } else {
430         return status;
431       }
432     }
433 
434     if (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
435       bytesSpecCoderUsed = STREAM_SIZE_MAX;
436       /* Being conservative */
437       transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5;
438     } else {
439       bytesSpecCoderUsed = ISACencLB_obj->bitstr_obj.stream_index -
440           transcodingParam.stream_index;
441       transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed;
442     }
443 
444     /* To be safe, we reduce the scale depending on
445        the number of iterations. */
446     transcodeScale *= (1.0 - (0.9 * (double)iterCntr /
447         (double)MAX_PAYLOAD_LIMIT_ITERATION));
448 
449     /* Scale the LPC Gains. */
450     for (k = 0; k < SUBFRAMES; k++) {
451       lofilt_coef[(LPC_LOBAND_ORDER + 1) * k] =
452           transcodingParam.loFiltGain[k] * transcodeScale;
453       hifilt_coef[(LPC_HIBAND_ORDER + 1) * k] =
454           transcodingParam.hiFiltGain[k] * transcodeScale;
455       transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k];
456       transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k];
457     }
458 
459     /* Scale DFT coefficients. */
460     for (k = 0; k < FRAMESAMPLES_HALF; k++) {
461       fre[k] = (WebRtc_Word16)(fre[k] * transcodeScale);
462       fim[k] = (WebRtc_Word16)(fim[k] * transcodeScale);
463     }
464 
465     /* Save data for multiple packets memory. */
466     my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF;
467     memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre));
468     memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim));
469 
470     /* Re-store the state of arithmetic coder before coding LPC gains. */
471     ISACencLB_obj->bitstr_obj.W_upper = transcodingParam.W_upper;
472     ISACencLB_obj->bitstr_obj.stream_index = transcodingParam.stream_index;
473     ISACencLB_obj->bitstr_obj.streamval = transcodingParam.streamval;
474     ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 2] =
475         transcodingParam.stream[0];
476     ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 1] =
477         transcodingParam.stream[1];
478     ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index] =
479         transcodingParam.stream[2];
480 
481     /* Code gains. */
482     WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef,
483                                &ISACencLB_obj->bitstr_obj,
484                                &ISACencLB_obj->SaveEnc_obj);
485 
486     /* Update the number of bytes left for encoding the spectrum. */
487     bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index;
488 
489     /* Encode the spectrum. */
490     err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand,
491                                 &ISACencLB_obj->bitstr_obj);
492 
493     if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
494       /* There has been an error but it was not too large
495          payload (we can cure too large payload). */
496       if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) {
497         /* If this is the second 30 ms of a 60 ms frame reset
498            this such that in the next call encoder starts fresh. */
499         ISACencLB_obj->frame_nb = 0;
500       }
501       return err;
502     }
503     iterCntr++;
504   }
505 
506   /* If 60 ms frame-size and just processed the first 30 ms, */
507   /* go back to main function to buffer the other 30 ms speech frame. */
508   if (frame_mode == 1) {
509     if (ISACencLB_obj->frame_nb == 0) {
510       ISACencLB_obj->frame_nb = 1;
511       return 0;
512     } else if (ISACencLB_obj->frame_nb == 1) {
513       ISACencLB_obj->frame_nb = 0;
514       /* Also update the frame-length for next packet,
515          in Adaptive mode only. */
516       if (codingMode == 0 && (ISACencLB_obj->enforceFrameSize == 0)) {
517         ISACencLB_obj->new_framelength =
518             WebRtcIsac_GetNewFrameLength(ISACencLB_obj->bottleneck,
519                                          ISACencLB_obj->current_framesamples);
520       }
521     }
522   } else {
523     ISACencLB_obj->frame_nb = 0;
524   }
525 
526   /* Complete arithmetic coding. */
527   stream_length = WebRtcIsac_EncTerminate(&ISACencLB_obj->bitstr_obj);
528   return stream_length;
529 }
530 
531 
532 
LimitPayloadUb(ISACUBEncStruct * ISACencUB_obj,WebRtc_UWord16 payloadLimitBytes,double bytesLeftSpecCoding,transcode_obj * transcodingParam,WebRtc_Word16 * fre,WebRtc_Word16 * fim,double * lpcGains,enum ISACBand band,int status)533 static int LimitPayloadUb(ISACUBEncStruct* ISACencUB_obj,
534                           WebRtc_UWord16 payloadLimitBytes,
535                           double bytesLeftSpecCoding,
536                           transcode_obj* transcodingParam,
537                           WebRtc_Word16* fre, WebRtc_Word16* fim,
538                           double* lpcGains, enum ISACBand band, int status) {
539 
540   int iterCntr = 0;
541   int k;
542   double bytesSpecCoderUsed;
543   double transcodeScale;
544   const WebRtc_Word16 kAveragePitchGain = 0.0;
545 
546   do {
547     if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) {
548       /* We were not able to limit the payload size. */
549       return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
550     }
551 
552     if (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
553       bytesSpecCoderUsed = STREAM_SIZE_MAX;
554       /* Being conservative. */
555       transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5;
556     } else {
557       bytesSpecCoderUsed = ISACencUB_obj->bitstr_obj.stream_index -
558           transcodingParam->stream_index;
559       transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed;
560     }
561 
562     /* To be safe, we reduce the scale depending on the
563        number of iterations. */
564     transcodeScale *= (1.0 - (0.9 * (double)iterCntr /
565         (double)MAX_PAYLOAD_LIMIT_ITERATION));
566 
567     /* Scale the LPC Gains. */
568     if (band == kIsacUpperBand16) {
569       /* Two sets of coefficients if 16 kHz. */
570       for (k = 0; k < SUBFRAMES; k++) {
571         transcodingParam->loFiltGain[k] *= transcodeScale;
572         transcodingParam->hiFiltGain[k] *= transcodeScale;
573       }
574     } else {
575       /* One sets of coefficients if 12 kHz. */
576       for (k = 0; k < SUBFRAMES; k++) {
577         transcodingParam->loFiltGain[k] *= transcodeScale;
578       }
579     }
580 
581     /* Scale DFT coefficients. */
582     for (k = 0; k < FRAMESAMPLES_HALF; k++) {
583       fre[k] = (WebRtc_Word16)(fre[k] * transcodeScale + 0.5);
584       fim[k] = (WebRtc_Word16)(fim[k] * transcodeScale + 0.5);
585     }
586     /* Store FFT coefficients for multiple encoding. */
587     memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre,
588           sizeof(ISACencUB_obj->SaveEnc_obj.realFFT));
589     memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim,
590            sizeof(ISACencUB_obj->SaveEnc_obj.imagFFT));
591 
592     /* Store the state of arithmetic coder before coding LPC gains */
593     ISACencUB_obj->bitstr_obj.W_upper = transcodingParam->W_upper;
594     ISACencUB_obj->bitstr_obj.stream_index = transcodingParam->stream_index;
595     ISACencUB_obj->bitstr_obj.streamval = transcodingParam->streamval;
596     ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 2] =
597         transcodingParam->stream[0];
598     ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 1] =
599         transcodingParam->stream[1];
600     ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index] =
601         transcodingParam->stream[2];
602 
603     /* Store the gains for multiple encoding. */
604     memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains,
605            SUBFRAMES * sizeof(double));
606     /* Entropy Code lpc-gains, indices are stored for a later use.*/
607     WebRtcIsac_EncodeLpcGainUb(transcodingParam->loFiltGain,
608                                &ISACencUB_obj->bitstr_obj,
609                                ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
610 
611     /* If 16kHz should do one more set. */
612     if (band == kIsacUpperBand16) {
613       /* Store the gains for multiple encoding. */
614       memcpy(&ISACencUB_obj->SaveEnc_obj.lpcGain[SUBFRAMES],
615              &lpcGains[SUBFRAMES], SUBFRAMES * sizeof(double));
616       /* Entropy Code lpc-gains, indices are stored for a later use.*/
617       WebRtcIsac_EncodeLpcGainUb(
618           transcodingParam->hiFiltGain, &ISACencUB_obj->bitstr_obj,
619           &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]);
620     }
621 
622     /* Update the number of bytes left for encoding the spectrum. */
623     bytesLeftSpecCoding = payloadLimitBytes -
624         ISACencUB_obj->bitstr_obj.stream_index;
625 
626     /* Save the bit-stream object at this point for FEC. */
627     memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj,
628            &ISACencUB_obj->bitstr_obj, sizeof(Bitstr));
629 
630     /* Encode the spectrum. */
631     status = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain,
632                                    band, &ISACencUB_obj->bitstr_obj);
633     if ((status < 0) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
634       /* There has been an error but it was not too large payload
635          (we can cure too large payload). */
636       return status;
637     }
638     iterCntr++;
639   } while ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
640       (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH));
641   return 0;
642 }
643 
WebRtcIsac_EncodeUb16(float * in,ISACUBEncStruct * ISACencUB_obj,WebRtc_Word32 jitterInfo)644 int WebRtcIsac_EncodeUb16(float* in, ISACUBEncStruct* ISACencUB_obj,
645                           WebRtc_Word32 jitterInfo) {
646   int err;
647   int k;
648 
649   double lpcVecs[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
650   double percepFilterParams[(1 + UB_LPC_ORDER) * (SUBFRAMES << 1) +
651                             (1 + UB_LPC_ORDER)];
652 
653   double LP_lookahead[FRAMESAMPLES];
654   WebRtc_Word16 fre[FRAMESAMPLES_HALF];   /* Q7 */
655   WebRtc_Word16 fim[FRAMESAMPLES_HALF];   /* Q7 */
656 
657   int status = 0;
658 
659   double varscale[2];
660   double corr[SUBFRAMES << 1][UB_LPC_ORDER + 1];
661   double lpcGains[SUBFRAMES << 1];
662   transcode_obj transcodingParam;
663   WebRtc_UWord16 payloadLimitBytes;
664   double s2nr;
665   const WebRtc_Word16 kAveragePitchGain = 0.0;
666   int bytesLeftSpecCoding;
667 
668   /* Buffer speech samples (by 10ms packet) until the frame-length is   */
669   /* reached (30 ms).                                                   */
670   /*********************************************************************/
671 
672   /* fill the buffer with 10ms input data */
673   memcpy(&ISACencUB_obj->data_buffer_float[ISACencUB_obj->buffer_index], in,
674          FRAMESAMPLES_10ms * sizeof(float));
675 
676   /* If buffer size is not equal to current frame-size, and end of file is
677    * not reached yet, we don't do encoding unless we have the whole frame. */
678   if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) {
679     ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms;
680     return 0;
681   }
682 
683   /* End of buffer function. */
684   /**************************/
685 
686   /* Encoding */
687   /************/
688 
689   /* Reset bit-stream */
690   WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj));
691 
692   /* Encoding of bandwidth information. */
693   WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj);
694 
695   status = WebRtcIsac_EncodeBandwidth(isac16kHz, &ISACencUB_obj->bitstr_obj);
696   if (status < 0) {
697     return status;
698   }
699 
700   s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES);
701 
702   memcpy(lpcVecs, ISACencUB_obj->lastLPCVec, UB_LPC_ORDER * sizeof(double));
703 
704   for (k = 0; k < FRAMESAMPLES; k++) {
705     LP_lookahead[k] = ISACencUB_obj->data_buffer_float[UB_LOOKAHEAD + k];
706   }
707 
708   /* Find coefficients for perceptual pre-filters. */
709   WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj,
710                           &lpcVecs[UB_LPC_ORDER], corr, varscale, isac16kHz);
711 
712   memcpy(ISACencUB_obj->lastLPCVec,
713          &lpcVecs[(UB16_LPC_VEC_PER_FRAME - 1) * (UB_LPC_ORDER)],
714          sizeof(double) * UB_LPC_ORDER);
715 
716   /* Code LPC model and shape - gains not quantized yet. */
717   WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj,
718                          percepFilterParams, isac16kHz,
719                          &ISACencUB_obj->SaveEnc_obj);
720 
721   /* the first set of lpc parameters are from the last sub-frame of
722    * the previous frame. so we don't care about them. */
723   WebRtcIsac_GetLpcGain(s2nr, &percepFilterParams[UB_LPC_ORDER + 1],
724                         (SUBFRAMES << 1), lpcGains, corr, varscale);
725 
726   /* Store the state of arithmetic coder before coding LPC gains */
727   transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index;
728   transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper;
729   transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval;
730   transcodingParam.stream[0] =
731       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
732                                        2];
733   transcodingParam.stream[1] =
734       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
735                                        1];
736   transcodingParam.stream[2] =
737       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index];
738 
739   /* Store LPC Gains before encoding them. */
740   for (k = 0; k < SUBFRAMES; k++) {
741     transcodingParam.loFiltGain[k] = lpcGains[k];
742     transcodingParam.hiFiltGain[k] = lpcGains[SUBFRAMES + k];
743   }
744 
745   /* Store the gains for multiple encoding. */
746   memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains,
747          (SUBFRAMES << 1) * sizeof(double));
748 
749   WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj,
750                              ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
751   WebRtcIsac_EncodeLpcGainUb(
752       &lpcGains[SUBFRAMES], &ISACencUB_obj->bitstr_obj,
753       &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]);
754 
755   /* Get the correct value for the payload limit and calculate the number of
756      bytes left for coding the spectrum. It is a 30ms frame
757      Subract 3 because termination process may add 3 bytes */
758   payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes -
759       ISACencUB_obj->numBytesUsed - 3;
760   bytesLeftSpecCoding = payloadLimitBytes -
761         ISACencUB_obj->bitstr_obj.stream_index;
762 
763   for (k = 0; k < (SUBFRAMES << 1); k++) {
764     percepFilterParams[k * (UB_LPC_ORDER + 1) + (UB_LPC_ORDER + 1)] =
765         lpcGains[k];
766   }
767 
768   /* LPC filtering (using normalized lattice filter), */
769   /* first half-frame. */
770   WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER,
771                                  ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
772                                  ISACencUB_obj->maskfiltstr_obj.PreStateLoG,
773                                  &ISACencUB_obj->data_buffer_float[0],
774                                  &percepFilterParams[UB_LPC_ORDER + 1],
775                                  &LP_lookahead[0]);
776 
777   /* Second half-frame filtering. */
778   WebRtcIsac_NormLatticeFilterMa(
779       UB_LPC_ORDER, ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
780       ISACencUB_obj->maskfiltstr_obj.PreStateLoG,
781       &ISACencUB_obj->data_buffer_float[FRAMESAMPLES_HALF],
782       &percepFilterParams[(UB_LPC_ORDER + 1) + SUBFRAMES * (UB_LPC_ORDER + 1)],
783       &LP_lookahead[FRAMESAMPLES_HALF]);
784 
785   WebRtcIsac_Time2Spec(&LP_lookahead[0], &LP_lookahead[FRAMESAMPLES_HALF],
786                        fre, fim, &ISACencUB_obj->fftstr_obj);
787 
788   /* Store FFT coefficients for multiple encoding. */
789   memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre, sizeof(fre));
790   memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim, sizeof(fim));
791 
792   /* Prepare the audio buffer for the next packet
793    * move the last 3 ms to the beginning of the buffer. */
794   memcpy(ISACencUB_obj->data_buffer_float,
795          &ISACencUB_obj->data_buffer_float[FRAMESAMPLES],
796          LB_TOTAL_DELAY_SAMPLES * sizeof(float));
797   /* start writing with 3 ms delay to compensate for the delay
798    * of the lower-band. */
799   ISACencUB_obj->buffer_index = LB_TOTAL_DELAY_SAMPLES;
800 
801   /* Save the bit-stream object at this point for FEC. */
802   memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, &ISACencUB_obj->bitstr_obj,
803          sizeof(Bitstr));
804 
805   /* Qantization and lossless coding */
806   /* Note that there is no pitch-gain for this band so kAveragePitchGain = 0
807    * is passed to the function. In fact, the function ignores the 3rd parameter
808    * for this band. */
809   err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand16,
810                               &ISACencUB_obj->bitstr_obj);
811   if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
812     return err;
813   }
814 
815   if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
816       (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
817     err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding,
818                          &transcodingParam, fre, fim, lpcGains,
819                          kIsacUpperBand16, err);
820   }
821   if (err < 0) {
822     return err;
823   }
824   /* Complete arithmetic coding. */
825   return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj);
826 }
827 
828 
WebRtcIsac_EncodeUb12(float * in,ISACUBEncStruct * ISACencUB_obj,WebRtc_Word32 jitterInfo)829 int WebRtcIsac_EncodeUb12(float* in, ISACUBEncStruct* ISACencUB_obj,
830                           WebRtc_Word32 jitterInfo) {
831   int err;
832   int k;
833 
834   double lpcVecs[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME];
835 
836   double percepFilterParams[(1 + UB_LPC_ORDER) * SUBFRAMES];
837   float LP[FRAMESAMPLES_HALF];
838   float HP[FRAMESAMPLES_HALF];
839 
840   double LP_lookahead[FRAMESAMPLES_HALF];
841   double HP_lookahead[FRAMESAMPLES_HALF];
842   double LPw[FRAMESAMPLES_HALF];
843 
844   double HPw[FRAMESAMPLES_HALF];
845   WebRtc_Word16 fre[FRAMESAMPLES_HALF];   /* Q7 */
846   WebRtc_Word16 fim[FRAMESAMPLES_HALF];   /* Q7 */
847 
848   int status = 0;
849 
850   double varscale[1];
851 
852   double corr[UB_LPC_GAIN_DIM][UB_LPC_ORDER + 1];
853   double lpcGains[SUBFRAMES];
854   transcode_obj transcodingParam;
855   WebRtc_UWord16 payloadLimitBytes;
856   double s2nr;
857   const WebRtc_Word16 kAveragePitchGain = 0.0;
858   double bytesLeftSpecCoding;
859 
860   /* Buffer speech samples (by 10ms packet) until the framelength is  */
861   /* reached (30 ms).                                                 */
862   /********************************************************************/
863 
864   /* Fill the buffer with 10ms input data. */
865   memcpy(&ISACencUB_obj->data_buffer_float[ISACencUB_obj->buffer_index], in,
866          FRAMESAMPLES_10ms * sizeof(float));
867 
868   /* if buffer-size is not equal to current frame-size then increase the
869      index and return. We do the encoding when we have enough audio.     */
870   if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) {
871     ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms;
872     return 0;
873   }
874   /* If buffer reached the right size, reset index and continue
875      with encoding the frame */
876   ISACencUB_obj->buffer_index = 0;
877 
878   /* End of buffer function */
879   /**************************/
880 
881   /* Encoding */
882   /************/
883 
884   /* Reset bit-stream. */
885   WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj));
886 
887   /* Encoding bandwidth information. */
888   WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj);
889   status = WebRtcIsac_EncodeBandwidth(isac12kHz, &ISACencUB_obj->bitstr_obj);
890   if (status < 0) {
891     return status;
892   }
893 
894   s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES);
895 
896   /* Split signal in two bands. */
897   WebRtcIsac_SplitAndFilterFloat(ISACencUB_obj->data_buffer_float, HP, LP,
898                                  HP_lookahead, LP_lookahead,
899                                  &ISACencUB_obj->prefiltbankstr_obj);
900 
901   /* Find coefficients for perceptual pre-filters. */
902   WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj,
903                           lpcVecs, corr, varscale, isac12kHz);
904 
905   /* Code LPC model and shape - gains not quantized yet. */
906   WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj,
907                          percepFilterParams, isac12kHz,
908                          &ISACencUB_obj->SaveEnc_obj);
909 
910   WebRtcIsac_GetLpcGain(s2nr, percepFilterParams, SUBFRAMES, lpcGains, corr,
911                         varscale);
912 
913   /* Store the state of arithmetic coder before coding LPC gains. */
914   transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper;
915   transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index;
916   transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval;
917   transcodingParam.stream[0] =
918       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
919                                        2];
920   transcodingParam.stream[1] =
921       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
922                                        1];
923   transcodingParam.stream[2] =
924       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index];
925 
926   /* Store LPC Gains before encoding them. */
927   for (k = 0; k < SUBFRAMES; k++) {
928     transcodingParam.loFiltGain[k] = lpcGains[k];
929   }
930 
931   /* Store the gains for multiple encoding. */
932   memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, SUBFRAMES *
933          sizeof(double));
934 
935   WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj,
936                              ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
937 
938   for (k = 0; k < SUBFRAMES; k++) {
939     percepFilterParams[k * (UB_LPC_ORDER + 1)] = lpcGains[k];
940   }
941 
942   /* perceptual pre-filtering (using normalized lattice filter) */
943   /* low-band filtering */
944   WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER,
945                                  ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
946                                  ISACencUB_obj->maskfiltstr_obj.PreStateLoG, LP,
947                                  percepFilterParams, LPw);
948 
949   /* Get the correct value for the payload limit and calculate the number
950      of bytes left for coding the spectrum. It is a 30ms frame Subract 3
951      because termination process may add 3 bytes */
952   payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes -
953       ISACencUB_obj->numBytesUsed - 3;
954   bytesLeftSpecCoding = payloadLimitBytes -
955       ISACencUB_obj->bitstr_obj.stream_index;
956 
957   memset(HPw, 0, sizeof(HPw));
958 
959   /* Transform */
960   WebRtcIsac_Time2Spec(LPw, HPw, fre, fim, &ISACencUB_obj->fftstr_obj);
961 
962   /* Store FFT coefficients for multiple encoding. */
963   memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre,
964          sizeof(ISACencUB_obj->SaveEnc_obj.realFFT));
965   memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim,
966          sizeof(ISACencUB_obj->SaveEnc_obj.imagFFT));
967 
968   /* Save the bit-stream object at this point for FEC. */
969   memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj,
970          &ISACencUB_obj->bitstr_obj, sizeof(Bitstr));
971 
972   /* Quantization and loss-less coding */
973   /* The 4th parameter to this function is pitch-gain, which is only used
974    * when encoding 0-8 kHz band, and irrelevant in this function, therefore,
975    * we insert zero here. */
976   err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand12,
977                               &ISACencUB_obj->bitstr_obj);
978   if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
979     /* There has been an error but it was not too large
980        payload (we can cure too large payload) */
981     return err;
982   }
983 
984   if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
985       (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
986     err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding,
987                          &transcodingParam, fre, fim, lpcGains,
988                          kIsacUpperBand12, err);
989   }
990   if (err < 0) {
991     return err;
992   }
993   /* Complete arithmetic coding. */
994   return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj);
995 }
996 
997 
998 
999 
1000 
1001 
1002 /* This function is used to create a new bit-stream with new BWE.
1003    The same data as previously encoded with the function WebRtcIsac_Encoder().
1004    The data needed is taken from the structure, where it was stored
1005    when calling the encoder. */
1006 
WebRtcIsac_EncodeStoredDataLb(const ISAC_SaveEncData_t * ISACSavedEnc_obj,Bitstr * ISACBitStr_obj,int BWnumber,float scale)1007 int WebRtcIsac_EncodeStoredDataLb(const ISAC_SaveEncData_t* ISACSavedEnc_obj,
1008                                   Bitstr* ISACBitStr_obj, int BWnumber,
1009                                   float scale) {
1010   int ii;
1011   int status;
1012   int BWno = BWnumber;
1013 
1014   const WebRtc_UWord16* WebRtcIsac_kQPitchGainCdf_ptr[1];
1015   const WebRtc_UWord16** cdf;
1016 
1017   double tmpLPCcoeffs_lo[(ORDERLO + 1)*SUBFRAMES * 2];
1018   double tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * 2];
1019   int tmpLPCindex_g[12 * 2];
1020   WebRtc_Word16 tmp_fre[FRAMESAMPLES], tmp_fim[FRAMESAMPLES];
1021   const int kModel = 0;
1022 
1023   /* Sanity Check - possible values for BWnumber is 0 - 23. */
1024   if ((BWnumber < 0) || (BWnumber > 23)) {
1025     return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
1026   }
1027 
1028   /* Reset bit-stream. */
1029   WebRtcIsac_ResetBitstream(ISACBitStr_obj);
1030 
1031   /* Encode frame length */
1032   status = WebRtcIsac_EncodeFrameLen(ISACSavedEnc_obj->framelength,
1033                                      ISACBitStr_obj);
1034   if (status < 0) {
1035     /* Wrong frame size. */
1036     return status;
1037   }
1038 
1039   /* Transcoding */
1040   if ((scale > 0.0) && (scale < 1.0)) {
1041     /* Compensate LPC gain. */
1042     for (ii = 0;
1043         ii < ((ORDERLO + 1)* SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx));
1044         ii++) {
1045       tmpLPCcoeffs_lo[ii] = scale *  ISACSavedEnc_obj->LPCcoeffs_lo[ii];
1046     }
1047     for (ii = 0;
1048         ii < ((ORDERHI + 1) * SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx));
1049         ii++) {
1050       tmpLPCcoeffs_hi[ii] = scale *  ISACSavedEnc_obj->LPCcoeffs_hi[ii];
1051     }
1052     /* Scale DFT. */
1053     for (ii = 0;
1054         ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx));
1055         ii++) {
1056       tmp_fre[ii] = (WebRtc_Word16)((scale) * (float)ISACSavedEnc_obj->fre[ii]);
1057       tmp_fim[ii] = (WebRtc_Word16)((scale) * (float)ISACSavedEnc_obj->fim[ii]);
1058     }
1059   } else {
1060     for (ii = 0;
1061         ii < (KLT_ORDER_GAIN * (1 + ISACSavedEnc_obj->startIdx));
1062         ii++) {
1063       tmpLPCindex_g[ii] =  ISACSavedEnc_obj->LPCindex_g[ii];
1064     }
1065     for (ii = 0;
1066         ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx));
1067         ii++) {
1068       tmp_fre[ii] = ISACSavedEnc_obj->fre[ii];
1069       tmp_fim[ii] = ISACSavedEnc_obj->fim[ii];
1070     }
1071   }
1072 
1073   /* Encode bandwidth estimate. */
1074   WebRtcIsac_EncodeReceiveBw(&BWno, ISACBitStr_obj);
1075 
1076   /* Loop over number of 30 msec */
1077   for (ii = 0; ii <= ISACSavedEnc_obj->startIdx; ii++) {
1078     /* Encode pitch gains. */
1079     *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf;
1080     WebRtcIsac_EncHistMulti(ISACBitStr_obj,
1081                             &ISACSavedEnc_obj->pitchGain_index[ii],
1082                             WebRtcIsac_kQPitchGainCdf_ptr, 1);
1083 
1084     /* Entropy coding of quantization pitch lags */
1085     /* Voicing classification. */
1086     if (ISACSavedEnc_obj->meanGain[ii] < 0.2) {
1087       cdf = WebRtcIsac_kQPitchLagCdfPtrLo;
1088     } else if (ISACSavedEnc_obj->meanGain[ii] < 0.4) {
1089       cdf = WebRtcIsac_kQPitchLagCdfPtrMid;
1090     } else {
1091       cdf = WebRtcIsac_kQPitchLagCdfPtrHi;
1092     }
1093     WebRtcIsac_EncHistMulti(ISACBitStr_obj,
1094                             &ISACSavedEnc_obj->pitchIndex[PITCH_SUBFRAMES * ii],
1095                             cdf, PITCH_SUBFRAMES);
1096 
1097     /* LPC */
1098     /* Only one model exists. The entropy coding is done only for backward
1099      * compatibility. */
1100     WebRtcIsac_EncHistMulti(ISACBitStr_obj, &kModel,
1101                             WebRtcIsac_kQKltModelCdfPtr, 1);
1102     /* Entropy coding of quantization indices - LPC shape only. */
1103     WebRtcIsac_EncHistMulti(ISACBitStr_obj,
1104                             &ISACSavedEnc_obj->LPCindex_s[KLT_ORDER_SHAPE * ii],
1105                             WebRtcIsac_kQKltCdfPtrShape,
1106                             KLT_ORDER_SHAPE);
1107 
1108     /* If transcoding, get new LPC gain indices */
1109     if (scale < 1.0) {
1110       WebRtcIsac_TranscodeLPCCoef(
1111           &tmpLPCcoeffs_lo[(ORDERLO + 1) * SUBFRAMES * ii],
1112           &tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * ii],
1113           &tmpLPCindex_g[KLT_ORDER_GAIN * ii]);
1114     }
1115 
1116     /* Entropy coding of quantization indices - LPC gain. */
1117     WebRtcIsac_EncHistMulti(ISACBitStr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN * ii],
1118                             WebRtcIsac_kQKltCdfPtrGain, KLT_ORDER_GAIN);
1119 
1120     /* Quantization and loss-less coding. */
1121     status = WebRtcIsac_EncodeSpec(&tmp_fre[ii * FRAMESAMPLES_HALF],
1122                                    &tmp_fim[ii * FRAMESAMPLES_HALF],
1123                                    ISACSavedEnc_obj->AvgPitchGain[ii],
1124                                    kIsacLowerBand, ISACBitStr_obj);
1125     if (status < 0) {
1126       return status;
1127     }
1128   }
1129   /* Complete arithmetic coding. */
1130   return WebRtcIsac_EncTerminate(ISACBitStr_obj);
1131 }
1132 
1133 
WebRtcIsac_EncodeStoredDataUb(const ISACUBSaveEncDataStruct * ISACSavedEnc_obj,Bitstr * bitStream,WebRtc_Word32 jitterInfo,float scale,enum ISACBandwidth bandwidth)1134 int WebRtcIsac_EncodeStoredDataUb(
1135     const ISACUBSaveEncDataStruct* ISACSavedEnc_obj,
1136     Bitstr* bitStream,
1137     WebRtc_Word32 jitterInfo,
1138     float scale,
1139     enum ISACBandwidth bandwidth) {
1140   int n;
1141   int err;
1142   double lpcGain[SUBFRAMES];
1143   WebRtc_Word16 realFFT[FRAMESAMPLES_HALF];
1144   WebRtc_Word16 imagFFT[FRAMESAMPLES_HALF];
1145   const WebRtc_UWord16** shape_cdf;
1146   int shape_len;
1147   const WebRtc_Word16 kAveragePitchGain = 0.0;
1148   enum ISACBand band;
1149   /* Reset bitstream. */
1150   WebRtcIsac_ResetBitstream(bitStream);
1151 
1152   /* Encode jitter index. */
1153   WebRtcIsac_EncodeJitterInfo(jitterInfo, bitStream);
1154 
1155   err = WebRtcIsac_EncodeBandwidth(bandwidth, bitStream);
1156   if (err < 0) {
1157     return err;
1158   }
1159 
1160   /* Encode LPC-shape. */
1161   if (bandwidth == isac12kHz) {
1162     shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb12;
1163     shape_len = UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME;
1164     band = kIsacUpperBand12;
1165   } else {
1166     shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb16;
1167     shape_len = UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME;
1168     band = kIsacUpperBand16;
1169   }
1170   WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->indexLPCShape,
1171                           shape_cdf, shape_len);
1172 
1173   if ((scale <= 0.0) || (scale >= 1.0)) {
1174     /* We only consider scales between zero and one. */
1175     WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->lpcGainIndex,
1176                             WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM);
1177     if (bandwidth == isac16kHz) {
1178       /* Store gain indices of the second half. */
1179       WebRtcIsac_EncHistMulti(bitStream,
1180                               &ISACSavedEnc_obj->lpcGainIndex[SUBFRAMES],
1181                               WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM);
1182     }
1183     /* Store FFT coefficients. */
1184     err = WebRtcIsac_EncodeSpec(ISACSavedEnc_obj->realFFT,
1185                                 ISACSavedEnc_obj->imagFFT, kAveragePitchGain,
1186                                 band, bitStream);
1187   } else {
1188     /* Scale LPC gain and FFT coefficients. */
1189     for (n = 0; n < SUBFRAMES; n++) {
1190       lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n];
1191     }
1192     /* Store LPC gains. */
1193     WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream);
1194 
1195     if (bandwidth == isac16kHz) {
1196       /* Scale and code the gains of the second half of the frame, if 16kHz. */
1197       for (n = 0; n < SUBFRAMES; n++) {
1198         lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n + SUBFRAMES];
1199       }
1200       WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream);
1201     }
1202 
1203     for (n = 0; n < FRAMESAMPLES_HALF; n++) {
1204       realFFT[n] = (WebRtc_Word16)(scale * (float)ISACSavedEnc_obj->realFFT[n] +
1205           0.5f);
1206       imagFFT[n] = (WebRtc_Word16)(scale * (float)ISACSavedEnc_obj->imagFFT[n] +
1207           0.5f);
1208     }
1209     /* Store FFT coefficients. */
1210     err = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain,
1211                                 band, bitStream);
1212   }
1213   if (err < 0) {
1214     /* Error happened while encoding FFT coefficients. */
1215     return err;
1216   }
1217 
1218   /* Complete arithmetic coding. */
1219   return WebRtcIsac_EncTerminate(bitStream);
1220 }
1221 
WebRtcIsac_GetRedPayloadUb(const ISACUBSaveEncDataStruct * ISACSavedEncObj,Bitstr * bitStreamObj,enum ISACBandwidth bandwidth)1222 WebRtc_Word16 WebRtcIsac_GetRedPayloadUb(
1223     const ISACUBSaveEncDataStruct* ISACSavedEncObj,
1224     Bitstr*                        bitStreamObj,
1225     enum ISACBandwidth             bandwidth) {
1226   int n;
1227   WebRtc_Word16 status;
1228   WebRtc_Word16 realFFT[FRAMESAMPLES_HALF];
1229   WebRtc_Word16 imagFFT[FRAMESAMPLES_HALF];
1230   enum ISACBand band;
1231   const WebRtc_Word16 kAveragePitchGain = 0.0;
1232   /* Store bit-stream object. */
1233   memcpy(bitStreamObj, &ISACSavedEncObj->bitStreamObj, sizeof(Bitstr));
1234 
1235   /* Scale FFT coefficients. */
1236   for (n = 0; n < FRAMESAMPLES_HALF; n++) {
1237     realFFT[n] = (WebRtc_Word16)((float)ISACSavedEncObj->realFFT[n] *
1238         RCU_TRANSCODING_SCALE_UB + 0.5);
1239     imagFFT[n] = (WebRtc_Word16)((float)ISACSavedEncObj->imagFFT[n] *
1240         RCU_TRANSCODING_SCALE_UB + 0.5);
1241   }
1242 
1243   band = (bandwidth == isac12kHz) ? kIsacUpperBand12 : kIsacUpperBand16;
1244   status = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain, band,
1245                                  bitStreamObj);
1246   if (status < 0) {
1247     return status;
1248   } else {
1249     /* Terminate entropy coding */
1250     return WebRtcIsac_EncTerminate(bitStreamObj);
1251   }
1252 }
1253