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