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