LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/main/source - encode.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 459 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
     102           0 : 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           0 :   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           0 :     *rateLBBitPerSec = (int16_t)((inRateBitPerSec > 32000) ?
     114             :         32000 : inRateBitPerSec);
     115           0 :     *rateUBBitPerSec = 0;
     116           0 :     *bandwidthKHz = isac8kHz;
     117           0 :   } 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           0 :     const double stepSizeInv = 8.5714286e-4;
     125           0 :     idxD = (inRateBitPerSec - 38000) * stepSizeInv;
     126           0 :     idx = (idxD >= 6) ? 6 : ((int16_t)idxD);
     127           0 :     idxErr = idxD - idx;
     128           0 :     *rateLBBitPerSec = kLowerBandBitRate12[idx];
     129           0 :     *rateUBBitPerSec = kUpperBandBitRate12[idx];
     130             : 
     131           0 :     if (idx < 6) {
     132           0 :       *rateLBBitPerSec += (int16_t)(
     133           0 :           idxErr * (kLowerBandBitRate12[idx + 1] - kLowerBandBitRate12[idx]));
     134           0 :       *rateUBBitPerSec += (int16_t)(
     135           0 :           idxErr * (kUpperBandBitRate12[idx + 1] - kUpperBandBitRate12[idx]));
     136             :     }
     137           0 :     *bandwidthKHz = isac12kHz;
     138           0 :   } 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           0 :     const double stepSizeInv = 8.3333333e-4;
     146           0 :     idxD = (inRateBitPerSec - 50000) * stepSizeInv;
     147           0 :     idx = (idxD >= 5) ? 5 : ((int16_t)idxD);
     148           0 :     idxErr = idxD - idx;
     149           0 :     *rateLBBitPerSec = kLowerBandBitRate16[idx];
     150           0 :     *rateUBBitPerSec  = kUpperBandBitRate16[idx];
     151             : 
     152           0 :     if (idx < 5) {
     153           0 :       *rateLBBitPerSec += (int16_t)(idxErr *
     154           0 :           (kLowerBandBitRate16[idx + 1] -
     155           0 :               kLowerBandBitRate16[idx]));
     156             : 
     157           0 :       *rateUBBitPerSec += (int16_t)(idxErr *
     158           0 :           (kUpperBandBitRate16[idx + 1] -
     159           0 :               kUpperBandBitRate16[idx]));
     160             :     }
     161           0 :     *bandwidthKHz = isac16kHz;
     162             :   } else {
     163             :     /* Out-of-range botlteneck value. */
     164           0 :     return -1;
     165             :   }
     166             : 
     167             :   /* limit the values. */
     168           0 :   *rateLBBitPerSec = (*rateLBBitPerSec > 32000) ? 32000 : *rateLBBitPerSec;
     169           0 :   *rateUBBitPerSec = (*rateUBBitPerSec > 32000) ? 32000 : *rateUBBitPerSec;
     170           0 :   return 0;
     171             : }
     172             : 
     173             : 
     174           0 : void WebRtcIsac_ResetBitstream(Bitstr* bit_stream) {
     175           0 :   bit_stream->W_upper = 0xFFFFFFFF;
     176           0 :   bit_stream->stream_index = 0;
     177           0 :   bit_stream->streamval = 0;
     178           0 : }
     179             : 
     180           0 : int WebRtcIsac_EncodeLb(const TransformTables* transform_tables,
     181             :                         float* in, ISACLBEncStruct* ISACencLB_obj,
     182             :                         int16_t codingMode,
     183             :                         int16_t bottleneckIndex) {
     184           0 :   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           0 :   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           0 :   if (ISACencLB_obj->buffer_index == 0) {
     218             :     /* Set the framelength for the next packet. */
     219           0 :     ISACencLB_obj->current_framesamples = ISACencLB_obj->new_framelength;
     220             :   }
     221             :   /* 'frame_mode' is 0 (30 ms) or 1 (60 ms). */
     222           0 :   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           0 :   for (k = 0; k < FRAMESAMPLES_10ms; k++) {
     230           0 :     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           0 :   if (ISACencLB_obj->buffer_index + FRAMESAMPLES_10ms != FRAMESAMPLES) {
     236           0 :     ISACencLB_obj->buffer_index += FRAMESAMPLES_10ms;
     237           0 :     return 0;
     238             :   }
     239             :   /* If buffer reached the right size, reset index and continue with
     240             :    * encoding the frame. */
     241           0 :   ISACencLB_obj->buffer_index = 0;
     242             : 
     243             :   /* End of buffer function. */
     244             :   /**************************/
     245             : 
     246             :   /* Encoding */
     247             :   /************/
     248             : 
     249           0 :   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           0 :     WebRtcIsac_ResetBitstream(&(ISACencLB_obj->bitstr_obj));
     255             : 
     256           0 :     if ((codingMode == 0) && (frame_mode == 0) &&
     257           0 :         (ISACencLB_obj->enforceFrameSize == 0)) {
     258           0 :       ISACencLB_obj->new_framelength = WebRtcIsac_GetNewFrameLength(
     259           0 :           ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples);
     260             :     }
     261             : 
     262           0 :     ISACencLB_obj->s2nr = WebRtcIsac_GetSnr(
     263           0 :         ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples);
     264             : 
     265             :     /* Encode frame length. */
     266           0 :     status = WebRtcIsac_EncodeFrameLen(
     267           0 :         ISACencLB_obj->current_framesamples, &ISACencLB_obj->bitstr_obj);
     268           0 :     if (status < 0) {
     269             :       /* Wrong frame size. */
     270           0 :       return status;
     271             :     }
     272             :     /* Save framelength for multiple packets memory. */
     273           0 :     ISACencLB_obj->SaveEnc_obj.framelength =
     274           0 :         ISACencLB_obj->current_framesamples;
     275             : 
     276             :     /* To be used for Redundant Coding. */
     277           0 :     ISACencLB_obj->lastBWIdx = bottleneckIndex;
     278           0 :     intVar = (int)bottleneckIndex;
     279           0 :     WebRtcIsac_EncodeReceiveBw(&intVar, &ISACencLB_obj->bitstr_obj);
     280             :   }
     281             : 
     282             :   /* Split signal in two bands. */
     283           0 :   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           0 :   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           0 :   for (k = 0; k < PITCH_SUBFRAMES; k++) {
     296           0 :     PitchGains_Q12[k] = (int16_t)(PitchGains[k] * 4096.0);
     297             :   }
     298             : 
     299             :   /* Set where to store data in multiple packets memory. */
     300           0 :   if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) {
     301           0 :     ISACencLB_obj->SaveEnc_obj.startIdx = 0;
     302             :   } else {
     303           0 :     ISACencLB_obj->SaveEnc_obj.startIdx = 1;
     304             :   }
     305             : 
     306             :   /* Quantize & encode pitch parameters. */
     307           0 :   WebRtcIsac_EncodePitchGain(PitchGains_Q12, &ISACencLB_obj->bitstr_obj,
     308             :                              &ISACencLB_obj->SaveEnc_obj);
     309           0 :   WebRtcIsac_EncodePitchLag(PitchLags, PitchGains_Q12,
     310             :                             &ISACencLB_obj->bitstr_obj,
     311             :                             &ISACencLB_obj->SaveEnc_obj);
     312             : 
     313           0 :   AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] +
     314           0 :       PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2;
     315             : 
     316             :   /* Find coefficients for perceptual pre-filters. */
     317           0 :   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           0 :   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           0 :   for (k = 0; k < 4; k++) {
     327           0 :     PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096;
     328             :   }
     329             : 
     330             :   /* Store the state of arithmetic coder before coding LPC gains. */
     331           0 :   transcodingParam.W_upper = ISACencLB_obj->bitstr_obj.W_upper;
     332           0 :   transcodingParam.stream_index = ISACencLB_obj->bitstr_obj.stream_index;
     333           0 :   transcodingParam.streamval = ISACencLB_obj->bitstr_obj.streamval;
     334           0 :   transcodingParam.stream[0] =
     335           0 :       ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index -
     336             :                                        2];
     337           0 :   transcodingParam.stream[1] =
     338           0 :       ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index -
     339             :                                        1];
     340           0 :   transcodingParam.stream[2] =
     341           0 :       ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index];
     342             : 
     343             :   /* Store LPC Gains before encoding them. */
     344           0 :   for (k = 0; k < SUBFRAMES; k++) {
     345           0 :     transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k];
     346           0 :     transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k];
     347             :   }
     348             : 
     349             :   /* Code gains */
     350           0 :   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           0 :   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           0 :     payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 >> 1;
     360           0 :   } else if (frame_mode == 0) {
     361             :     /* It is a 30ms frame */
     362             :     /* Subract 3 because termination process may add 3 bytes. */
     363           0 :     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           0 :     payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 - 3;
     368             :   }
     369           0 :   bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index;
     370             : 
     371             :   /* Perceptual pre-filtering (using normalized lattice filter). */
     372             :   /* Low-band filtering. */
     373           0 :   WebRtcIsac_NormLatticeFilterMa(ORDERLO,
     374           0 :                                  ISACencLB_obj->maskfiltstr_obj.PreStateLoF,
     375           0 :                                  ISACencLB_obj->maskfiltstr_obj.PreStateLoG,
     376             :                                  LP, lofilt_coef, LPw);
     377             :   /* High-band filtering. */
     378           0 :   WebRtcIsac_NormLatticeFilterMa(ORDERHI,
     379           0 :                                  ISACencLB_obj->maskfiltstr_obj.PreStateHiF,
     380           0 :                                  ISACencLB_obj->maskfiltstr_obj.PreStateHiG,
     381             :                                  HP, hifilt_coef, HPw);
     382             :   /* Pitch filter. */
     383           0 :   WebRtcIsac_PitchfilterPre(LPw, LPw_pf, &ISACencLB_obj->pitchfiltstr_obj,
     384             :                             PitchLags, PitchGains);
     385             :   /* Transform */
     386           0 :   WebRtcIsac_Time2Spec(transform_tables,
     387             :                        LPw_pf, HPw, fre, fim, &ISACencLB_obj->fftstr_obj);
     388             : 
     389             :   /* Save data for multiple packets memory. */
     390           0 :   my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF;
     391           0 :   memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre));
     392           0 :   memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim));
     393             : 
     394           0 :   ISACencLB_obj->SaveEnc_obj.AvgPitchGain[ISACencLB_obj->SaveEnc_obj.startIdx] =
     395             :       AvgPitchGain_Q12;
     396             : 
     397             :   /* Quantization and loss-less coding. */
     398           0 :   err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand,
     399             :                               &ISACencLB_obj->bitstr_obj);
     400           0 :   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           0 :     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           0 :       ISACencLB_obj->frame_nb = 0;
     407             :     }
     408           0 :     return err;
     409             :   }
     410           0 :   iterCntr = 0;
     411           0 :   while ((ISACencLB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
     412             :       (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
     413             :     double bytesSpecCoderUsed;
     414             :     double transcodeScale;
     415             : 
     416           0 :     if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) {
     417             :       /* We were not able to limit the payload size */
     418           0 :       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           0 :         ISACencLB_obj->frame_nb = 1;
     424           0 :         return 0;
     425           0 :       } else if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 1)) {
     426           0 :         ISACencLB_obj->frame_nb = 0;
     427             :       }
     428             : 
     429           0 :       if (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
     430           0 :         return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
     431             :       } else {
     432           0 :         return status;
     433             :       }
     434             :     }
     435             : 
     436           0 :     if (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
     437           0 :       bytesSpecCoderUsed = STREAM_SIZE_MAX;
     438             :       /* Being conservative */
     439           0 :       transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5;
     440             :     } else {
     441           0 :       bytesSpecCoderUsed = ISACencLB_obj->bitstr_obj.stream_index -
     442           0 :           transcodingParam.stream_index;
     443           0 :       transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed;
     444             :     }
     445             : 
     446             :     /* To be safe, we reduce the scale depending on
     447             :        the number of iterations. */
     448           0 :     transcodeScale *= (1.0 - (0.9 * (double)iterCntr /
     449             :         (double)MAX_PAYLOAD_LIMIT_ITERATION));
     450             : 
     451             :     /* Scale the LPC Gains. */
     452           0 :     for (k = 0; k < SUBFRAMES; k++) {
     453           0 :       lofilt_coef[(LPC_LOBAND_ORDER + 1) * k] =
     454           0 :           transcodingParam.loFiltGain[k] * transcodeScale;
     455           0 :       hifilt_coef[(LPC_HIBAND_ORDER + 1) * k] =
     456           0 :           transcodingParam.hiFiltGain[k] * transcodeScale;
     457           0 :       transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k];
     458           0 :       transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k];
     459             :     }
     460             : 
     461             :     /* Scale DFT coefficients. */
     462           0 :     for (k = 0; k < FRAMESAMPLES_HALF; k++) {
     463           0 :       fre[k] = (int16_t)(fre[k] * transcodeScale);
     464           0 :       fim[k] = (int16_t)(fim[k] * transcodeScale);
     465             :     }
     466             : 
     467             :     /* Save data for multiple packets memory. */
     468           0 :     my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF;
     469           0 :     memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre));
     470           0 :     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           0 :     ISACencLB_obj->bitstr_obj.W_upper = transcodingParam.W_upper;
     474           0 :     ISACencLB_obj->bitstr_obj.stream_index = transcodingParam.stream_index;
     475           0 :     ISACencLB_obj->bitstr_obj.streamval = transcodingParam.streamval;
     476           0 :     ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 2] =
     477           0 :         transcodingParam.stream[0];
     478           0 :     ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 1] =
     479           0 :         transcodingParam.stream[1];
     480           0 :     ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index] =
     481           0 :         transcodingParam.stream[2];
     482             : 
     483             :     /* Code gains. */
     484           0 :     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           0 :     bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index;
     490             : 
     491             :     /* Encode the spectrum. */
     492           0 :     err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand,
     493             :                                 &ISACencLB_obj->bitstr_obj);
     494             : 
     495           0 :     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           0 :       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           0 :         ISACencLB_obj->frame_nb = 0;
     502             :       }
     503           0 :       return err;
     504             :     }
     505           0 :     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           0 :   if (frame_mode == 1) {
     511           0 :     if (ISACencLB_obj->frame_nb == 0) {
     512           0 :       ISACencLB_obj->frame_nb = 1;
     513           0 :       return 0;
     514           0 :     } else if (ISACencLB_obj->frame_nb == 1) {
     515           0 :       ISACencLB_obj->frame_nb = 0;
     516             :       /* Also update the frame-length for next packet,
     517             :          in Adaptive mode only. */
     518           0 :       if (codingMode == 0 && (ISACencLB_obj->enforceFrameSize == 0)) {
     519           0 :         ISACencLB_obj->new_framelength =
     520           0 :             WebRtcIsac_GetNewFrameLength(ISACencLB_obj->bottleneck,
     521           0 :                                          ISACencLB_obj->current_framesamples);
     522             :       }
     523             :     }
     524             :   } else {
     525           0 :     ISACencLB_obj->frame_nb = 0;
     526             :   }
     527             : 
     528             :   /* Complete arithmetic coding. */
     529           0 :   stream_length = WebRtcIsac_EncTerminate(&ISACencLB_obj->bitstr_obj);
     530           0 :   return stream_length;
     531             : }
     532             : 
     533             : 
     534             : 
     535           0 : 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           0 :   int iterCntr = 0;
     543             :   int k;
     544             :   double bytesSpecCoderUsed;
     545             :   double transcodeScale;
     546           0 :   const int16_t kAveragePitchGain = 0.0;
     547             : 
     548             :   do {
     549           0 :     if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) {
     550             :       /* We were not able to limit the payload size. */
     551           0 :       return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
     552             :     }
     553             : 
     554           0 :     if (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
     555           0 :       bytesSpecCoderUsed = STREAM_SIZE_MAX;
     556             :       /* Being conservative. */
     557           0 :       transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5;
     558             :     } else {
     559           0 :       bytesSpecCoderUsed = ISACencUB_obj->bitstr_obj.stream_index -
     560           0 :           transcodingParam->stream_index;
     561           0 :       transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed;
     562             :     }
     563             : 
     564             :     /* To be safe, we reduce the scale depending on the
     565             :        number of iterations. */
     566           0 :     transcodeScale *= (1.0 - (0.9 * (double)iterCntr /
     567             :         (double)MAX_PAYLOAD_LIMIT_ITERATION));
     568             : 
     569             :     /* Scale the LPC Gains. */
     570           0 :     if (band == kIsacUpperBand16) {
     571             :       /* Two sets of coefficients if 16 kHz. */
     572           0 :       for (k = 0; k < SUBFRAMES; k++) {
     573           0 :         transcodingParam->loFiltGain[k] *= transcodeScale;
     574           0 :         transcodingParam->hiFiltGain[k] *= transcodeScale;
     575             :       }
     576             :     } else {
     577             :       /* One sets of coefficients if 12 kHz. */
     578           0 :       for (k = 0; k < SUBFRAMES; k++) {
     579           0 :         transcodingParam->loFiltGain[k] *= transcodeScale;
     580             :       }
     581             :     }
     582             : 
     583             :     /* Scale DFT coefficients. */
     584           0 :     for (k = 0; k < FRAMESAMPLES_HALF; k++) {
     585           0 :       fre[k] = (int16_t)(fre[k] * transcodeScale + 0.5);
     586           0 :       fim[k] = (int16_t)(fim[k] * transcodeScale + 0.5);
     587             :     }
     588             :     /* Store FFT coefficients for multiple encoding. */
     589           0 :     memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre,
     590             :           sizeof(ISACencUB_obj->SaveEnc_obj.realFFT));
     591           0 :     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           0 :     ISACencUB_obj->bitstr_obj.W_upper = transcodingParam->W_upper;
     596           0 :     ISACencUB_obj->bitstr_obj.stream_index = transcodingParam->stream_index;
     597           0 :     ISACencUB_obj->bitstr_obj.streamval = transcodingParam->streamval;
     598           0 :     ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 2] =
     599           0 :         transcodingParam->stream[0];
     600           0 :     ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 1] =
     601           0 :         transcodingParam->stream[1];
     602           0 :     ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index] =
     603           0 :         transcodingParam->stream[2];
     604             : 
     605             :     /* Store the gains for multiple encoding. */
     606           0 :     memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains,
     607             :            SUBFRAMES * sizeof(double));
     608             :     /* Entropy Code lpc-gains, indices are stored for a later use.*/
     609           0 :     WebRtcIsac_EncodeLpcGainUb(transcodingParam->loFiltGain,
     610             :                                &ISACencUB_obj->bitstr_obj,
     611           0 :                                ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
     612             : 
     613             :     /* If 16kHz should do one more set. */
     614           0 :     if (band == kIsacUpperBand16) {
     615             :       /* Store the gains for multiple encoding. */
     616           0 :       memcpy(&ISACencUB_obj->SaveEnc_obj.lpcGain[SUBFRAMES],
     617           0 :              &lpcGains[SUBFRAMES], SUBFRAMES * sizeof(double));
     618             :       /* Entropy Code lpc-gains, indices are stored for a later use.*/
     619           0 :       WebRtcIsac_EncodeLpcGainUb(
     620           0 :           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           0 :     bytesLeftSpecCoding = payloadLimitBytes -
     626           0 :         ISACencUB_obj->bitstr_obj.stream_index;
     627             : 
     628             :     /* Save the bit-stream object at this point for FEC. */
     629           0 :     memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj,
     630           0 :            &ISACencUB_obj->bitstr_obj, sizeof(Bitstr));
     631             : 
     632             :     /* Encode the spectrum. */
     633           0 :     status = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain,
     634             :                                    band, &ISACencUB_obj->bitstr_obj);
     635           0 :     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           0 :       return status;
     639             :     }
     640           0 :     iterCntr++;
     641           0 :   } while ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
     642           0 :       (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH));
     643           0 :   return 0;
     644             : }
     645             : 
     646           0 : 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           0 :   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           0 :   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           0 :   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           0 :   if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) {
     682           0 :     ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms;
     683           0 :     return 0;
     684             :   }
     685             : 
     686             :   /* End of buffer function. */
     687             :   /**************************/
     688             : 
     689             :   /* Encoding */
     690             :   /************/
     691             : 
     692             :   /* Reset bit-stream */
     693           0 :   WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj));
     694             : 
     695             :   /* Encoding of bandwidth information. */
     696           0 :   WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj);
     697             : 
     698           0 :   status = WebRtcIsac_EncodeBandwidth(isac16kHz, &ISACencUB_obj->bitstr_obj);
     699           0 :   if (status < 0) {
     700           0 :     return status;
     701             :   }
     702             : 
     703           0 :   s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES);
     704             : 
     705           0 :   memcpy(lpcVecs, ISACencUB_obj->lastLPCVec, UB_LPC_ORDER * sizeof(double));
     706             : 
     707           0 :   for (k = 0; k < FRAMESAMPLES; k++) {
     708           0 :     LP_lookahead[k] = ISACencUB_obj->data_buffer_float[UB_LOOKAHEAD + k];
     709             :   }
     710             : 
     711             :   /* Find coefficients for perceptual pre-filters. */
     712           0 :   WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj,
     713             :                           &lpcVecs[UB_LPC_ORDER], corr, varscale, isac16kHz);
     714             : 
     715           0 :   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           0 :   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           0 :   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           0 :   transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index;
     731           0 :   transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper;
     732           0 :   transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval;
     733           0 :   transcodingParam.stream[0] =
     734           0 :       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
     735             :                                        2];
     736           0 :   transcodingParam.stream[1] =
     737           0 :       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
     738             :                                        1];
     739           0 :   transcodingParam.stream[2] =
     740           0 :       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index];
     741             : 
     742             :   /* Store LPC Gains before encoding them. */
     743           0 :   for (k = 0; k < SUBFRAMES; k++) {
     744           0 :     transcodingParam.loFiltGain[k] = lpcGains[k];
     745           0 :     transcodingParam.hiFiltGain[k] = lpcGains[SUBFRAMES + k];
     746             :   }
     747             : 
     748             :   /* Store the gains for multiple encoding. */
     749           0 :   memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains,
     750             :          (SUBFRAMES << 1) * sizeof(double));
     751             : 
     752           0 :   WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj,
     753           0 :                              ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
     754           0 :   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           0 :   payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes -
     762           0 :       ISACencUB_obj->numBytesUsed - 3;
     763           0 :   bytesLeftSpecCoding = payloadLimitBytes -
     764           0 :         ISACencUB_obj->bitstr_obj.stream_index;
     765             : 
     766           0 :   for (k = 0; k < (SUBFRAMES << 1); k++) {
     767           0 :     percepFilterParams[k * (UB_LPC_ORDER + 1) + (UB_LPC_ORDER + 1)] =
     768           0 :         lpcGains[k];
     769             :   }
     770             : 
     771             :   /* LPC filtering (using normalized lattice filter), */
     772             :   /* first half-frame. */
     773           0 :   WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER,
     774           0 :                                  ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
     775           0 :                                  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           0 :   WebRtcIsac_NormLatticeFilterMa(
     782           0 :       UB_LPC_ORDER, ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
     783           0 :       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           0 :   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           0 :   memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre, sizeof(fre));
     794           0 :   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           0 :   memcpy(ISACencUB_obj->data_buffer_float,
     799           0 :          &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           0 :   ISACencUB_obj->buffer_index = LB_TOTAL_DELAY_SAMPLES;
     804             : 
     805             :   /* Save the bit-stream object at this point for FEC. */
     806           0 :   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           0 :   err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand16,
     814             :                               &ISACencUB_obj->bitstr_obj);
     815           0 :   if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
     816           0 :     return err;
     817             :   }
     818             : 
     819           0 :   if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
     820             :       (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
     821           0 :     err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding,
     822             :                          &transcodingParam, fre, fim, lpcGains,
     823             :                          kIsacUpperBand16, err);
     824             :   }
     825           0 :   if (err < 0) {
     826           0 :     return err;
     827             :   }
     828             :   /* Complete arithmetic coding. */
     829           0 :   return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj);
     830             : }
     831             : 
     832             : 
     833           0 : 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           0 :   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           0 :   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           0 :   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           0 :   if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) {
     876           0 :     ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms;
     877           0 :     return 0;
     878             :   }
     879             :   /* If buffer reached the right size, reset index and continue
     880             :      with encoding the frame */
     881           0 :   ISACencUB_obj->buffer_index = 0;
     882             : 
     883             :   /* End of buffer function */
     884             :   /**************************/
     885             : 
     886             :   /* Encoding */
     887             :   /************/
     888             : 
     889             :   /* Reset bit-stream. */
     890           0 :   WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj));
     891             : 
     892             :   /* Encoding bandwidth information. */
     893           0 :   WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj);
     894           0 :   status = WebRtcIsac_EncodeBandwidth(isac12kHz, &ISACencUB_obj->bitstr_obj);
     895           0 :   if (status < 0) {
     896           0 :     return status;
     897             :   }
     898             : 
     899           0 :   s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES);
     900             : 
     901             :   /* Split signal in two bands. */
     902           0 :   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           0 :   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           0 :   WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj,
     912             :                          percepFilterParams, isac12kHz,
     913             :                          &ISACencUB_obj->SaveEnc_obj);
     914             : 
     915           0 :   WebRtcIsac_GetLpcGain(s2nr, percepFilterParams, SUBFRAMES, lpcGains, corr,
     916             :                         varscale);
     917             : 
     918             :   /* Store the state of arithmetic coder before coding LPC gains. */
     919           0 :   transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper;
     920           0 :   transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index;
     921           0 :   transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval;
     922           0 :   transcodingParam.stream[0] =
     923           0 :       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
     924             :                                        2];
     925           0 :   transcodingParam.stream[1] =
     926           0 :       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
     927             :                                        1];
     928           0 :   transcodingParam.stream[2] =
     929           0 :       ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index];
     930             : 
     931             :   /* Store LPC Gains before encoding them. */
     932           0 :   for (k = 0; k < SUBFRAMES; k++) {
     933           0 :     transcodingParam.loFiltGain[k] = lpcGains[k];
     934             :   }
     935             : 
     936             :   /* Store the gains for multiple encoding. */
     937           0 :   memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, SUBFRAMES *
     938             :          sizeof(double));
     939             : 
     940           0 :   WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj,
     941           0 :                              ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
     942             : 
     943           0 :   for (k = 0; k < SUBFRAMES; k++) {
     944           0 :     percepFilterParams[k * (UB_LPC_ORDER + 1)] = lpcGains[k];
     945             :   }
     946             : 
     947             :   /* perceptual pre-filtering (using normalized lattice filter) */
     948             :   /* low-band filtering */
     949           0 :   WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER,
     950           0 :                                  ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
     951           0 :                                  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           0 :   payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes -
     958           0 :       ISACencUB_obj->numBytesUsed - 3;
     959           0 :   bytesLeftSpecCoding = payloadLimitBytes -
     960           0 :       ISACencUB_obj->bitstr_obj.stream_index;
     961             : 
     962           0 :   memset(HPw, 0, sizeof(HPw));
     963             : 
     964             :   /* Transform */
     965           0 :   WebRtcIsac_Time2Spec(transform_tables,
     966             :                        LPw, HPw, fre, fim, &ISACencUB_obj->fftstr_obj);
     967             : 
     968             :   /* Store FFT coefficients for multiple encoding. */
     969           0 :   memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre,
     970             :          sizeof(ISACencUB_obj->SaveEnc_obj.realFFT));
     971           0 :   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           0 :   memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj,
     976           0 :          &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           0 :   err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand12,
     983             :                               &ISACencUB_obj->bitstr_obj);
     984           0 :   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           0 :     return err;
     988             :   }
     989             : 
     990           0 :   if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
     991             :       (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
     992           0 :     err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding,
     993             :                          &transcodingParam, fre, fim, lpcGains,
     994             :                          kIsacUpperBand12, err);
     995             :   }
     996           0 :   if (err < 0) {
     997           0 :     return err;
     998             :   }
     999             :   /* Complete arithmetic coding. */
    1000           0 :   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             : 
    1013           0 : int WebRtcIsac_EncodeStoredDataLb(const IsacSaveEncoderData* ISACSavedEnc_obj,
    1014             :                                   Bitstr* ISACBitStr_obj, int BWnumber,
    1015             :                                   float scale) {
    1016             :   int ii;
    1017             :   int status;
    1018           0 :   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           0 :   const int kModel = 0;
    1028             : 
    1029             :   /* Sanity Check - possible values for BWnumber is 0 - 23. */
    1030           0 :   if ((BWnumber < 0) || (BWnumber > 23)) {
    1031           0 :     return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
    1032             :   }
    1033             : 
    1034             :   /* Reset bit-stream. */
    1035           0 :   WebRtcIsac_ResetBitstream(ISACBitStr_obj);
    1036             : 
    1037             :   /* Encode frame length */
    1038           0 :   status = WebRtcIsac_EncodeFrameLen(ISACSavedEnc_obj->framelength,
    1039             :                                      ISACBitStr_obj);
    1040           0 :   if (status < 0) {
    1041             :     /* Wrong frame size. */
    1042           0 :     return status;
    1043             :   }
    1044             : 
    1045             :   /* Transcoding */
    1046           0 :   if ((scale > 0.0) && (scale < 1.0)) {
    1047             :     /* Compensate LPC gain. */
    1048           0 :     for (ii = 0;
    1049           0 :         ii < ((ORDERLO + 1)* SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx));
    1050           0 :         ii++) {
    1051           0 :       tmpLPCcoeffs_lo[ii] = scale *  ISACSavedEnc_obj->LPCcoeffs_lo[ii];
    1052             :     }
    1053           0 :     for (ii = 0;
    1054           0 :         ii < ((ORDERHI + 1) * SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx));
    1055           0 :         ii++) {
    1056           0 :       tmpLPCcoeffs_hi[ii] = scale *  ISACSavedEnc_obj->LPCcoeffs_hi[ii];
    1057             :     }
    1058             :     /* Scale DFT. */
    1059           0 :     for (ii = 0;
    1060           0 :         ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx));
    1061           0 :         ii++) {
    1062           0 :       tmp_fre[ii] = (int16_t)((scale) * (float)ISACSavedEnc_obj->fre[ii]);
    1063           0 :       tmp_fim[ii] = (int16_t)((scale) * (float)ISACSavedEnc_obj->fim[ii]);
    1064             :     }
    1065             :   } else {
    1066           0 :     for (ii = 0;
    1067           0 :         ii < (KLT_ORDER_GAIN * (1 + ISACSavedEnc_obj->startIdx));
    1068           0 :         ii++) {
    1069           0 :       tmpLPCindex_g[ii] =  ISACSavedEnc_obj->LPCindex_g[ii];
    1070             :     }
    1071           0 :     for (ii = 0;
    1072           0 :         ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx));
    1073           0 :         ii++) {
    1074           0 :       tmp_fre[ii] = ISACSavedEnc_obj->fre[ii];
    1075           0 :       tmp_fim[ii] = ISACSavedEnc_obj->fim[ii];
    1076             :     }
    1077             :   }
    1078             : 
    1079             :   /* Encode bandwidth estimate. */
    1080           0 :   WebRtcIsac_EncodeReceiveBw(&BWno, ISACBitStr_obj);
    1081             : 
    1082             :   /* Loop over number of 30 msec */
    1083           0 :   for (ii = 0; ii <= ISACSavedEnc_obj->startIdx; ii++) {
    1084             :     /* Encode pitch gains. */
    1085           0 :     *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf;
    1086           0 :     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           0 :     if (ISACSavedEnc_obj->meanGain[ii] < 0.2) {
    1093           0 :       cdf = WebRtcIsac_kQPitchLagCdfPtrLo;
    1094           0 :     } else if (ISACSavedEnc_obj->meanGain[ii] < 0.4) {
    1095           0 :       cdf = WebRtcIsac_kQPitchLagCdfPtrMid;
    1096             :     } else {
    1097           0 :       cdf = WebRtcIsac_kQPitchLagCdfPtrHi;
    1098             :     }
    1099           0 :     WebRtcIsac_EncHistMulti(ISACBitStr_obj,
    1100           0 :                             &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           0 :     WebRtcIsac_EncHistMulti(ISACBitStr_obj, &kModel,
    1107             :                             WebRtcIsac_kQKltModelCdfPtr, 1);
    1108             :     /* Entropy coding of quantization indices - LPC shape only. */
    1109           0 :     WebRtcIsac_EncHistMulti(ISACBitStr_obj,
    1110           0 :                             &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           0 :     if (scale < 1.0) {
    1116           0 :       WebRtcIsac_TranscodeLPCCoef(
    1117           0 :           &tmpLPCcoeffs_lo[(ORDERLO + 1) * SUBFRAMES * ii],
    1118           0 :           &tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * ii],
    1119           0 :           &tmpLPCindex_g[KLT_ORDER_GAIN * ii]);
    1120             :     }
    1121             : 
    1122             :     /* Entropy coding of quantization indices - LPC gain. */
    1123           0 :     WebRtcIsac_EncHistMulti(ISACBitStr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN * ii],
    1124             :                             WebRtcIsac_kQKltCdfPtrGain, KLT_ORDER_GAIN);
    1125             : 
    1126             :     /* Quantization and loss-less coding. */
    1127           0 :     status = WebRtcIsac_EncodeSpec(&tmp_fre[ii * FRAMESAMPLES_HALF],
    1128           0 :                                    &tmp_fim[ii * FRAMESAMPLES_HALF],
    1129           0 :                                    ISACSavedEnc_obj->AvgPitchGain[ii],
    1130             :                                    kIsacLowerBand, ISACBitStr_obj);
    1131           0 :     if (status < 0) {
    1132           0 :       return status;
    1133             :     }
    1134             :   }
    1135             :   /* Complete arithmetic coding. */
    1136           0 :   return WebRtcIsac_EncTerminate(ISACBitStr_obj);
    1137             : }
    1138             : 
    1139             : 
    1140           0 : 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           0 :   const int16_t kAveragePitchGain = 0.0;
    1154             :   enum ISACBand band;
    1155             :   /* Reset bitstream. */
    1156           0 :   WebRtcIsac_ResetBitstream(bitStream);
    1157             : 
    1158             :   /* Encode jitter index. */
    1159           0 :   WebRtcIsac_EncodeJitterInfo(jitterInfo, bitStream);
    1160             : 
    1161           0 :   err = WebRtcIsac_EncodeBandwidth(bandwidth, bitStream);
    1162           0 :   if (err < 0) {
    1163           0 :     return err;
    1164             :   }
    1165             : 
    1166             :   /* Encode LPC-shape. */
    1167           0 :   if (bandwidth == isac12kHz) {
    1168           0 :     shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb12;
    1169           0 :     shape_len = UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME;
    1170           0 :     band = kIsacUpperBand12;
    1171             :   } else {
    1172           0 :     shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb16;
    1173           0 :     shape_len = UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME;
    1174           0 :     band = kIsacUpperBand16;
    1175             :   }
    1176           0 :   WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->indexLPCShape,
    1177             :                           shape_cdf, shape_len);
    1178             : 
    1179           0 :   if ((scale <= 0.0) || (scale >= 1.0)) {
    1180             :     /* We only consider scales between zero and one. */
    1181           0 :     WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->lpcGainIndex,
    1182             :                             WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM);
    1183           0 :     if (bandwidth == isac16kHz) {
    1184             :       /* Store gain indices of the second half. */
    1185           0 :       WebRtcIsac_EncHistMulti(bitStream,
    1186             :                               &ISACSavedEnc_obj->lpcGainIndex[SUBFRAMES],
    1187             :                               WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM);
    1188             :     }
    1189             :     /* Store FFT coefficients. */
    1190           0 :     err = WebRtcIsac_EncodeSpec(ISACSavedEnc_obj->realFFT,
    1191           0 :                                 ISACSavedEnc_obj->imagFFT, kAveragePitchGain,
    1192             :                                 band, bitStream);
    1193             :   } else {
    1194             :     /* Scale LPC gain and FFT coefficients. */
    1195           0 :     for (n = 0; n < SUBFRAMES; n++) {
    1196           0 :       lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n];
    1197             :     }
    1198             :     /* Store LPC gains. */
    1199           0 :     WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream);
    1200             : 
    1201           0 :     if (bandwidth == isac16kHz) {
    1202             :       /* Scale and code the gains of the second half of the frame, if 16kHz. */
    1203           0 :       for (n = 0; n < SUBFRAMES; n++) {
    1204           0 :         lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n + SUBFRAMES];
    1205             :       }
    1206           0 :       WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream);
    1207             :     }
    1208             : 
    1209           0 :     for (n = 0; n < FRAMESAMPLES_HALF; n++) {
    1210           0 :       realFFT[n] = (int16_t)(scale * (float)ISACSavedEnc_obj->realFFT[n] +
    1211             :           0.5f);
    1212           0 :       imagFFT[n] = (int16_t)(scale * (float)ISACSavedEnc_obj->imagFFT[n] +
    1213             :           0.5f);
    1214             :     }
    1215             :     /* Store FFT coefficients. */
    1216           0 :     err = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain,
    1217             :                                 band, bitStream);
    1218             :   }
    1219           0 :   if (err < 0) {
    1220             :     /* Error happened while encoding FFT coefficients. */
    1221           0 :     return err;
    1222             :   }
    1223             : 
    1224             :   /* Complete arithmetic coding. */
    1225           0 :   return WebRtcIsac_EncTerminate(bitStream);
    1226             : }
    1227             : 
    1228           0 : 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           0 :   const int16_t kAveragePitchGain = 0.0;
    1238             :   /* Store bit-stream object. */
    1239           0 :   memcpy(bitStreamObj, &ISACSavedEncObj->bitStreamObj, sizeof(Bitstr));
    1240             : 
    1241             :   /* Scale FFT coefficients. */
    1242           0 :   for (n = 0; n < FRAMESAMPLES_HALF; n++) {
    1243           0 :     realFFT[n] = (int16_t)((float)ISACSavedEncObj->realFFT[n] *
    1244           0 :         RCU_TRANSCODING_SCALE_UB + 0.5);
    1245           0 :     imagFFT[n] = (int16_t)((float)ISACSavedEncObj->imagFFT[n] *
    1246           0 :         RCU_TRANSCODING_SCALE_UB + 0.5);
    1247             :   }
    1248             : 
    1249           0 :   band = (bandwidth == isac12kHz) ? kIsacUpperBand12 : kIsacUpperBand16;
    1250           0 :   status = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain, band,
    1251             :                                  bitStreamObj);
    1252           0 :   if (status < 0) {
    1253           0 :     return status;
    1254             :   } else {
    1255             :     /* Terminate entropy coding */
    1256           0 :     return WebRtcIsac_EncTerminate(bitStreamObj);
    1257             :   }
    1258             : }

Generated by: LCOV version 1.13