LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/main/source - isac.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 795 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 43 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             :  * isac.c
      13             :  *
      14             :  * This C file contains the functions for the ISAC API
      15             :  *
      16             :  */
      17             : 
      18             : #include "webrtc/modules/audio_coding/codecs/isac/main/include/isac.h"
      19             : 
      20             : #include <math.h>
      21             : #include <stdio.h>
      22             : #include <stdlib.h>
      23             : #include <string.h>
      24             : 
      25             : #include "webrtc/base/checks.h"
      26             : #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
      27             : #include "webrtc/modules/audio_coding/codecs/isac/main/source/bandwidth_estimator.h"
      28             : #include "webrtc/modules/audio_coding/codecs/isac/main/source/codec.h"
      29             : #include "webrtc/modules/audio_coding/codecs/isac/main/source/crc.h"
      30             : #include "webrtc/modules/audio_coding/codecs/isac/main/source/entropy_coding.h"
      31             : #include "webrtc/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.h"
      32             : #include "webrtc/modules/audio_coding/codecs/isac/main/source/os_specific_inline.h"
      33             : #include "webrtc/modules/audio_coding/codecs/isac/main/source/structs.h"
      34             : 
      35             : #define BIT_MASK_DEC_INIT 0x0001
      36             : #define BIT_MASK_ENC_INIT 0x0002
      37             : 
      38             : #define LEN_CHECK_SUM_WORD8     4
      39             : #define MAX_NUM_LAYERS         10
      40             : 
      41             : 
      42             : /****************************************************************************
      43             :  * UpdatePayloadSizeLimit(...)
      44             :  *
      45             :  * Call this function to update the limit on the payload size. The limit on
      46             :  * payload size might change i) if a user ''directly changes the limit by
      47             :  * calling xxx_setMaxPayloadSize() or xxx_setMaxRate(), or ii) indirectly
      48             :  * when bandwidth is changing. The latter might be the result of bandwidth
      49             :  * adaptation, or direct change of the bottleneck in instantaneous mode.
      50             :  *
      51             :  * This function takes the current overall limit on payload, and translates it
      52             :  * to the limits on lower and upper-band. If the codec is in wideband mode,
      53             :  * then the overall limit and the limit on the lower-band is the same.
      54             :  * Otherwise, a fraction of the limit should be allocated to lower-band
      55             :  * leaving some room for the upper-band bit-stream. That is why an update
      56             :  * of limit is required every time that the bandwidth is changing.
      57             :  *
      58             :  */
      59           0 : static void UpdatePayloadSizeLimit(ISACMainStruct* instISAC) {
      60           0 :   int16_t lim30MsPayloadBytes = WEBRTC_SPL_MIN(
      61             :                           (instISAC->maxPayloadSizeBytes),
      62             :                           (instISAC->maxRateBytesPer30Ms));
      63           0 :   int16_t lim60MsPayloadBytes = WEBRTC_SPL_MIN(
      64             :                           (instISAC->maxPayloadSizeBytes),
      65             :                           (instISAC->maxRateBytesPer30Ms << 1));
      66             : 
      67             :   /* The only time that iSAC will have 60 ms
      68             :    * frame-size is when operating in wideband, so
      69             :    * there is no upper-band bit-stream. */
      70             : 
      71           0 :   if (instISAC->bandwidthKHz == isac8kHz) {
      72             :     /* At 8 kHz there is no upper-band bit-stream,
      73             :      * therefore, the lower-band limit is the overall limit. */
      74           0 :     instISAC->instLB.ISACencLB_obj.payloadLimitBytes60 =
      75             :       lim60MsPayloadBytes;
      76           0 :     instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 =
      77             :       lim30MsPayloadBytes;
      78             :   } else {
      79             :     /* When in super-wideband, we only have 30 ms frames.
      80             :      * Do a rate allocation for the given limit. */
      81           0 :     if (lim30MsPayloadBytes > 250) {
      82             :       /* 4/5 to lower-band the rest for upper-band. */
      83           0 :       instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 =
      84           0 :         (lim30MsPayloadBytes << 2) / 5;
      85           0 :     } else if (lim30MsPayloadBytes > 200) {
      86             :       /* For the interval of 200 to 250 the share of
      87             :        * upper-band linearly grows from 20 to 50. */
      88           0 :       instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 =
      89           0 :         (lim30MsPayloadBytes << 1) / 5 + 100;
      90             :     } else {
      91             :       /* Allocate only 20 for upper-band. */
      92           0 :       instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 =
      93           0 :         lim30MsPayloadBytes - 20;
      94             :     }
      95           0 :     instISAC->instUB.ISACencUB_obj.maxPayloadSizeBytes =
      96             :       lim30MsPayloadBytes;
      97             :   }
      98           0 : }
      99             : 
     100             : 
     101             : /****************************************************************************
     102             :  * UpdateBottleneck(...)
     103             :  *
     104             :  * This function updates the bottleneck only if the codec is operating in
     105             :  * channel-adaptive mode. Furthermore, as the update of bottleneck might
     106             :  * result in an update of bandwidth, therefore, the bottlenech should be
     107             :  * updated just right before the first 10ms of a frame is pushed into encoder.
     108             :  *
     109             :  */
     110           0 : static void UpdateBottleneck(ISACMainStruct* instISAC) {
     111             :   /* Read the bottleneck from bandwidth estimator for the
     112             :    * first 10 ms audio. This way, if there is a change
     113             :    * in bandwidth, upper and lower-band will be in sync. */
     114           0 :   if ((instISAC->codingMode == 0) &&
     115           0 :       (instISAC->instLB.ISACencLB_obj.buffer_index == 0) &&
     116           0 :       (instISAC->instLB.ISACencLB_obj.frame_nb == 0)) {
     117           0 :     int32_t bottleneck =
     118           0 :         WebRtcIsac_GetUplinkBandwidth(&instISAC->bwestimator_obj);
     119             : 
     120             :     /* Adding hysteresis when increasing signal bandwidth. */
     121           0 :     if ((instISAC->bandwidthKHz == isac8kHz)
     122           0 :         && (bottleneck > 37000)
     123           0 :         && (bottleneck < 41000)) {
     124           0 :       bottleneck = 37000;
     125             :     }
     126             : 
     127             :     /* Switching from 12 kHz to 16 kHz is not allowed at this revision.
     128             :      * If we let this happen, we have to take care of buffer_index and
     129             :      * the last LPC vector. */
     130           0 :     if ((instISAC->bandwidthKHz != isac16kHz) &&
     131             :         (bottleneck > 46000)) {
     132           0 :       bottleneck = 46000;
     133             :     }
     134             : 
     135             :     /* We might need a rate allocation. */
     136           0 :     if (instISAC->encoderSamplingRateKHz == kIsacWideband) {
     137             :       /* Wideband is the only choice we have here. */
     138           0 :       instISAC->instLB.ISACencLB_obj.bottleneck =
     139           0 :         (bottleneck > 32000) ? 32000 : bottleneck;
     140           0 :       instISAC->bandwidthKHz = isac8kHz;
     141             :     } else {
     142             :       /* Do the rate-allocation and get the new bandwidth. */
     143             :       enum ISACBandwidth bandwidth;
     144           0 :       WebRtcIsac_RateAllocation(bottleneck,
     145             :                                 &(instISAC->instLB.ISACencLB_obj.bottleneck),
     146             :                                 &(instISAC->instUB.ISACencUB_obj.bottleneck),
     147             :                                 &bandwidth);
     148           0 :       if (bandwidth != isac8kHz) {
     149           0 :         instISAC->instLB.ISACencLB_obj.new_framelength = 480;
     150             :       }
     151           0 :       if (bandwidth != instISAC->bandwidthKHz) {
     152             :         /* Bandwidth is changing. */
     153           0 :         instISAC->bandwidthKHz = bandwidth;
     154           0 :         UpdatePayloadSizeLimit(instISAC);
     155           0 :         if (bandwidth == isac12kHz) {
     156           0 :           instISAC->instLB.ISACencLB_obj.buffer_index = 0;
     157             :         }
     158             :         /* Currently we don't let the bandwidth to switch to 16 kHz
     159             :          * if in adaptive mode. If we let this happen, we have to take
     160             :          * care of buffer_index and the last LPC vector. */
     161             :       }
     162             :     }
     163             :   }
     164           0 : }
     165             : 
     166             : 
     167             : /****************************************************************************
     168             :  * GetSendBandwidthInfo(...)
     169             :  *
     170             :  * This is called to get the bandwidth info. This info is the bandwidth and
     171             :  * the jitter of 'there-to-here' channel, estimated 'here.' These info
     172             :  * is signaled in an in-band fashion to the other side.
     173             :  *
     174             :  * The call to the bandwidth estimator triggers a recursive averaging which
     175             :  * has to be synchronized between encoder & decoder, therefore, the call to
     176             :  * BWE should be once per packet. As the BWE info is inserted into bit-stream
     177             :  * We need a valid info right before the encodeLB function is going to
     178             :  * generate a bit-stream. That is when lower-band buffer has already 20ms
     179             :  * of audio, and the 3rd block of 10ms is going to be injected into encoder.
     180             :  *
     181             :  * Inputs:
     182             :  *         - instISAC          : iSAC instance.
     183             :  *
     184             :  * Outputs:
     185             :  *         - bandwidthIndex    : an index which has to be encoded in
     186             :  *                               lower-band bit-stream, indicating the
     187             :  *                               bandwidth of there-to-here channel.
     188             :  *         - jitterInfo        : this indicates if the jitter is high
     189             :  *                               or low and it is encoded in upper-band
     190             :  *                               bit-stream.
     191             :  *
     192             :  */
     193           0 : static void GetSendBandwidthInfo(ISACMainStruct* instISAC,
     194             :                                  int16_t* bandwidthIndex,
     195             :                                  int16_t* jitterInfo) {
     196           0 :   if ((instISAC->instLB.ISACencLB_obj.buffer_index ==
     197           0 :       (FRAMESAMPLES_10ms << 1)) &&
     198           0 :       (instISAC->instLB.ISACencLB_obj.frame_nb == 0)) {
     199             :     /* Bandwidth estimation and coding. */
     200           0 :     WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj),
     201             :                                          bandwidthIndex, jitterInfo,
     202             :                                          instISAC->decoderSamplingRateKHz);
     203             :   }
     204           0 : }
     205             : 
     206             : 
     207             : /****************************************************************************
     208             :  * WebRtcIsac_AssignSize(...)
     209             :  *
     210             :  * This function returns the size of the ISAC instance, so that the instance
     211             :  * can be created out side iSAC.
     212             :  *
     213             :  * Output:
     214             :  *        - sizeinbytes       : number of bytes needed to allocate for the
     215             :  *                              instance.
     216             :  *
     217             :  * Return value               : 0 - Ok
     218             :  *                             -1 - Error
     219             :  */
     220           0 : int16_t WebRtcIsac_AssignSize(int* sizeInBytes) {
     221           0 :   *sizeInBytes = sizeof(ISACMainStruct) * 2 / sizeof(int16_t);
     222           0 :   return 0;
     223             : }
     224             : 
     225             : 
     226             : /****************************************************************************
     227             :  * WebRtcIsac_Assign(...)
     228             :  *
     229             :  * This function assigns the memory already created to the ISAC instance.
     230             :  *
     231             :  * Input:
     232             :  *        - ISAC_main_inst    : address of the pointer to the coder instance.
     233             :  *        - instISAC_Addr     : the already allocated memory, where we put the
     234             :  *                              iSAC structure.
     235             :  *
     236             :  * Return value               : 0 - Ok
     237             :  *                             -1 - Error
     238             :  */
     239           0 : int16_t WebRtcIsac_Assign(ISACStruct** ISAC_main_inst,
     240             :                           void* instISAC_Addr) {
     241           0 :   if (instISAC_Addr != NULL) {
     242           0 :     ISACMainStruct* instISAC = (ISACMainStruct*)instISAC_Addr;
     243           0 :     instISAC->errorCode = 0;
     244           0 :     instISAC->initFlag = 0;
     245             : 
     246             :     /* Assign the address. */
     247           0 :     *ISAC_main_inst = (ISACStruct*)instISAC_Addr;
     248             : 
     249             :     /* Default is wideband. */
     250           0 :     instISAC->encoderSamplingRateKHz = kIsacWideband;
     251           0 :     instISAC->decoderSamplingRateKHz = kIsacWideband;
     252           0 :     instISAC->bandwidthKHz           = isac8kHz;
     253           0 :     instISAC->in_sample_rate_hz = 16000;
     254             : 
     255           0 :     WebRtcIsac_InitTransform(&instISAC->transform_tables);
     256           0 :     return 0;
     257             :   } else {
     258           0 :     return -1;
     259             :   }
     260             : }
     261             : 
     262             : 
     263             : /****************************************************************************
     264             :  * WebRtcIsac_Create(...)
     265             :  *
     266             :  * This function creates an ISAC instance, which will contain the state
     267             :  * information for one coding/decoding channel.
     268             :  *
     269             :  * Input:
     270             :  *        - ISAC_main_inst    : address of the pointer to the coder instance.
     271             :  *
     272             :  * Return value               : 0 - Ok
     273             :  *                             -1 - Error
     274             :  */
     275           0 : int16_t WebRtcIsac_Create(ISACStruct** ISAC_main_inst) {
     276             :   ISACMainStruct* instISAC;
     277             : 
     278           0 :   if (ISAC_main_inst != NULL) {
     279           0 :     instISAC = (ISACMainStruct*)malloc(sizeof(ISACMainStruct));
     280           0 :     *ISAC_main_inst = (ISACStruct*)instISAC;
     281           0 :     if (*ISAC_main_inst != NULL) {
     282           0 :       instISAC->errorCode = 0;
     283           0 :       instISAC->initFlag = 0;
     284             :       /* Default is wideband. */
     285           0 :       instISAC->bandwidthKHz = isac8kHz;
     286           0 :       instISAC->encoderSamplingRateKHz = kIsacWideband;
     287           0 :       instISAC->decoderSamplingRateKHz = kIsacWideband;
     288           0 :       instISAC->in_sample_rate_hz = 16000;
     289             : 
     290           0 :       WebRtcIsac_InitTransform(&instISAC->transform_tables);
     291           0 :       return 0;
     292             :     } else {
     293           0 :       return -1;
     294             :     }
     295             :   } else {
     296           0 :     return -1;
     297             :   }
     298             : }
     299             : 
     300             : 
     301             : /****************************************************************************
     302             :  * WebRtcIsac_Free(...)
     303             :  *
     304             :  * This function frees the ISAC instance created at the beginning.
     305             :  *
     306             :  * Input:
     307             :  *        - ISAC_main_inst    : a ISAC instance.
     308             :  *
     309             :  * Return value               : 0 - Ok
     310             :  *                             -1 - Error
     311             :  */
     312           0 : int16_t WebRtcIsac_Free(ISACStruct* ISAC_main_inst) {
     313           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
     314           0 :   free(instISAC);
     315           0 :   return 0;
     316             : }
     317             : 
     318             : 
     319             : /****************************************************************************
     320             :  * EncoderInitLb(...) - internal function for initialization of
     321             :  *                                Lower Band
     322             :  * EncoderInitUb(...) - internal function for initialization of
     323             :  *                                Upper Band
     324             :  * WebRtcIsac_EncoderInit(...) - API function
     325             :  *
     326             :  * This function initializes a ISAC instance prior to the encoder calls.
     327             :  *
     328             :  * Input:
     329             :  *        - ISAC_main_inst    : ISAC instance.
     330             :  *        - CodingMode        : 0 -> Bit rate and frame length are automatically
     331             :  *                                 adjusted to available bandwidth on
     332             :  *                                 transmission channel, applicable just to
     333             :  *                                 wideband mode.
     334             :  *                              1 -> User sets a frame length and a target bit
     335             :  *                                 rate which is taken as the maximum
     336             :  *                                 short-term average bit rate.
     337             :  *
     338             :  * Return value               :  0 - Ok
     339             :  *                              -1 - Error
     340             :  */
     341           0 : static int16_t EncoderInitLb(ISACLBStruct* instLB,
     342             :                              int16_t codingMode,
     343             :                              enum IsacSamplingRate sampRate) {
     344           0 :   int16_t statusInit = 0;
     345             :   int k;
     346             : 
     347             :   /* Init stream vector to zero */
     348           0 :   for (k = 0; k < STREAM_SIZE_MAX_60; k++) {
     349           0 :     instLB->ISACencLB_obj.bitstr_obj.stream[k] = 0;
     350             :   }
     351             : 
     352           0 :   if ((codingMode == 1) || (sampRate == kIsacSuperWideband)) {
     353             :     /* 30 ms frame-size if either in super-wideband or
     354             :      * instantaneous mode (I-mode). */
     355           0 :     instLB->ISACencLB_obj.new_framelength = 480;
     356             :   } else {
     357           0 :     instLB->ISACencLB_obj.new_framelength = INITIAL_FRAMESAMPLES;
     358             :   }
     359             : 
     360           0 :   WebRtcIsac_InitMasking(&instLB->ISACencLB_obj.maskfiltstr_obj);
     361           0 :   WebRtcIsac_InitPreFilterbank(&instLB->ISACencLB_obj.prefiltbankstr_obj);
     362           0 :   WebRtcIsac_InitPitchFilter(&instLB->ISACencLB_obj.pitchfiltstr_obj);
     363           0 :   WebRtcIsac_InitPitchAnalysis(
     364             :     &instLB->ISACencLB_obj.pitchanalysisstr_obj);
     365             : 
     366           0 :   instLB->ISACencLB_obj.buffer_index = 0;
     367           0 :   instLB->ISACencLB_obj.frame_nb = 0;
     368             :   /* Default for I-mode. */
     369           0 :   instLB->ISACencLB_obj.bottleneck = 32000;
     370           0 :   instLB->ISACencLB_obj.current_framesamples = 0;
     371           0 :   instLB->ISACencLB_obj.s2nr = 0;
     372           0 :   instLB->ISACencLB_obj.payloadLimitBytes30 = STREAM_SIZE_MAX_30;
     373           0 :   instLB->ISACencLB_obj.payloadLimitBytes60 = STREAM_SIZE_MAX_60;
     374           0 :   instLB->ISACencLB_obj.maxPayloadBytes = STREAM_SIZE_MAX_60;
     375           0 :   instLB->ISACencLB_obj.maxRateInBytes = STREAM_SIZE_MAX_30;
     376           0 :   instLB->ISACencLB_obj.enforceFrameSize = 0;
     377             :   /* Invalid value prevents getRedPayload to
     378             :      run before encoder is called. */
     379           0 :   instLB->ISACencLB_obj.lastBWIdx            = -1;
     380           0 :   return statusInit;
     381             : }
     382             : 
     383           0 : static int16_t EncoderInitUb(ISACUBStruct* instUB,
     384             :                              int16_t bandwidth) {
     385           0 :   int16_t statusInit = 0;
     386             :   int k;
     387             : 
     388             :   /* Init stream vector to zero. */
     389           0 :   for (k = 0; k < STREAM_SIZE_MAX_60; k++) {
     390           0 :     instUB->ISACencUB_obj.bitstr_obj.stream[k] = 0;
     391             :   }
     392             : 
     393           0 :   WebRtcIsac_InitMasking(&instUB->ISACencUB_obj.maskfiltstr_obj);
     394           0 :   WebRtcIsac_InitPreFilterbank(&instUB->ISACencUB_obj.prefiltbankstr_obj);
     395             : 
     396           0 :   if (bandwidth == isac16kHz) {
     397           0 :     instUB->ISACencUB_obj.buffer_index = LB_TOTAL_DELAY_SAMPLES;
     398             :   } else {
     399           0 :     instUB->ISACencUB_obj.buffer_index = 0;
     400             :   }
     401             :   /* Default for I-mode. */
     402           0 :   instUB->ISACencUB_obj.bottleneck = 32000;
     403             :   /* These store the limits for the wideband + super-wideband bit-stream. */
     404           0 :   instUB->ISACencUB_obj.maxPayloadSizeBytes = STREAM_SIZE_MAX_30 << 1;
     405             :   /* This has to be updated after each lower-band encoding to guarantee
     406             :    * a correct payload-limitation. */
     407           0 :   instUB->ISACencUB_obj.numBytesUsed = 0;
     408           0 :   memset(instUB->ISACencUB_obj.data_buffer_float, 0,
     409             :          (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES) * sizeof(float));
     410             : 
     411           0 :   memcpy(&(instUB->ISACencUB_obj.lastLPCVec),
     412             :          WebRtcIsac_kMeanLarUb16, sizeof(double) * UB_LPC_ORDER);
     413             : 
     414           0 :   return statusInit;
     415             : }
     416             : 
     417             : 
     418           0 : int16_t WebRtcIsac_EncoderInit(ISACStruct* ISAC_main_inst,
     419             :                                int16_t codingMode) {
     420           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
     421             :   int16_t status;
     422             : 
     423           0 :   if ((codingMode != 0) && (codingMode != 1)) {
     424           0 :     instISAC->errorCode = ISAC_DISALLOWED_CODING_MODE;
     425           0 :     return -1;
     426             :   }
     427             :   /* Default bottleneck. */
     428           0 :   instISAC->bottleneck = MAX_ISAC_BW;
     429             : 
     430           0 :   if (instISAC->encoderSamplingRateKHz == kIsacWideband) {
     431           0 :     instISAC->bandwidthKHz = isac8kHz;
     432           0 :     instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60;
     433           0 :     instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30;
     434             :   } else {
     435           0 :     instISAC->bandwidthKHz = isac16kHz;
     436           0 :     instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX;
     437           0 :     instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX;
     438             :   }
     439             : 
     440             :   /* Channel-adaptive = 0; Instantaneous (Channel-independent) = 1. */
     441           0 :   instISAC->codingMode = codingMode;
     442             : 
     443           0 :   WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj,
     444             :                                     instISAC->encoderSamplingRateKHz,
     445             :                                     instISAC->decoderSamplingRateKHz);
     446             : 
     447           0 :   WebRtcIsac_InitRateModel(&instISAC->rate_data_obj);
     448             :   /* Default for I-mode. */
     449           0 :   instISAC->MaxDelay = 10.0;
     450             : 
     451           0 :   status = EncoderInitLb(&instISAC->instLB, codingMode,
     452             :                          instISAC->encoderSamplingRateKHz);
     453           0 :   if (status < 0) {
     454           0 :     instISAC->errorCode = -status;
     455           0 :     return -1;
     456             :   }
     457             : 
     458           0 :   if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) {
     459             :     /* Initialize encoder filter-bank. */
     460           0 :     memset(instISAC->analysisFBState1, 0,
     461             :            FB_STATE_SIZE_WORD32 * sizeof(int32_t));
     462           0 :     memset(instISAC->analysisFBState2, 0,
     463             :            FB_STATE_SIZE_WORD32 * sizeof(int32_t));
     464             : 
     465           0 :     status = EncoderInitUb(&(instISAC->instUB),
     466           0 :                            instISAC->bandwidthKHz);
     467           0 :     if (status < 0) {
     468           0 :       instISAC->errorCode = -status;
     469           0 :       return -1;
     470             :     }
     471             :   }
     472             :   /* Initialization is successful, set the flag. */
     473           0 :   instISAC->initFlag |= BIT_MASK_ENC_INIT;
     474           0 :   return 0;
     475             : }
     476             : 
     477             : 
     478             : /****************************************************************************
     479             :  * WebRtcIsac_Encode(...)
     480             :  *
     481             :  * This function encodes 10ms frame(s) and inserts it into a package.
     482             :  * Input speech length has to be 160 samples (10ms). The encoder buffers those
     483             :  * 10ms frames until it reaches the chosen Framesize (480 or 960 samples
     484             :  * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
     485             :  *
     486             :  * Input:
     487             :  *        - ISAC_main_inst    : ISAC instance.
     488             :  *        - speechIn          : input speech vector.
     489             :  *
     490             :  * Output:
     491             :  *        - encoded           : the encoded data vector
     492             :  *
     493             :  * Return value:
     494             :  *                            : >0 - Length (in bytes) of coded data
     495             :  *                            :  0 - The buffer didn't reach the chosen
     496             :  *                                  frameSize so it keeps buffering speech
     497             :  *                                 samples.
     498             :  *                            : -1 - Error
     499             :  */
     500           0 : int WebRtcIsac_Encode(ISACStruct* ISAC_main_inst,
     501             :                       const int16_t* speechIn,
     502             :                       uint8_t* encoded) {
     503             :   float inFrame[FRAMESAMPLES_10ms];
     504             :   int16_t speechInLB[FRAMESAMPLES_10ms];
     505             :   int16_t speechInUB[FRAMESAMPLES_10ms];
     506           0 :   int streamLenLB = 0;
     507           0 :   int streamLenUB = 0;
     508           0 :   int streamLen = 0;
     509           0 :   size_t k = 0;
     510           0 :   uint8_t garbageLen = 0;
     511           0 :   int32_t bottleneck = 0;
     512           0 :   int16_t bottleneckIdx = 0;
     513           0 :   int16_t jitterInfo = 0;
     514             : 
     515           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
     516           0 :   ISACLBStruct* instLB = &(instISAC->instLB);
     517           0 :   ISACUBStruct* instUB = &(instISAC->instUB);
     518             : 
     519             :   /* Check if encoder initiated. */
     520           0 :   if ((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
     521             :       BIT_MASK_ENC_INIT) {
     522           0 :     instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
     523           0 :     return -1;
     524             :   }
     525             : 
     526           0 :   if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) {
     527           0 :     WebRtcSpl_AnalysisQMF(speechIn, SWBFRAMESAMPLES_10ms, speechInLB,
     528           0 :                           speechInUB, instISAC->analysisFBState1,
     529           0 :                           instISAC->analysisFBState2);
     530             : 
     531             :     /* Convert from fixed to floating point. */
     532           0 :     for (k = 0; k < FRAMESAMPLES_10ms; k++) {
     533           0 :       inFrame[k] = (float)speechInLB[k];
     534             :     }
     535             :   } else {
     536           0 :     for (k = 0; k < FRAMESAMPLES_10ms; k++) {
     537           0 :       inFrame[k] = (float) speechIn[k];
     538             :     }
     539             :   }
     540             : 
     541             :   /* Add some noise to avoid denormal numbers. */
     542           0 :   inFrame[0] += (float)1.23455334e-3;
     543           0 :   inFrame[1] -= (float)2.04324239e-3;
     544           0 :   inFrame[2] += (float)1.90854954e-3;
     545           0 :   inFrame[9] += (float)1.84854878e-3;
     546             : 
     547             :   /* This function will update the bottleneck if required. */
     548           0 :   UpdateBottleneck(instISAC);
     549             : 
     550             :   /* Get the bandwith information which has to be sent to the other side. */
     551           0 :   GetSendBandwidthInfo(instISAC, &bottleneckIdx, &jitterInfo);
     552             : 
     553             :   /* Encode lower-band. */
     554           0 :   streamLenLB = WebRtcIsac_EncodeLb(&instISAC->transform_tables,
     555             :                                     inFrame, &instLB->ISACencLB_obj,
     556           0 :                                     instISAC->codingMode, bottleneckIdx);
     557           0 :   if (streamLenLB < 0) {
     558           0 :     return -1;
     559             :   }
     560             : 
     561           0 :   if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) {
     562           0 :     instUB = &(instISAC->instUB);
     563             : 
     564             :     /* Convert to float. */
     565           0 :     for (k = 0; k < FRAMESAMPLES_10ms; k++) {
     566           0 :       inFrame[k] = (float) speechInUB[k];
     567             :     }
     568             : 
     569             :     /* Add some noise to avoid denormal numbers. */
     570           0 :     inFrame[0] += (float)1.23455334e-3;
     571           0 :     inFrame[1] -= (float)2.04324239e-3;
     572           0 :     inFrame[2] += (float)1.90854954e-3;
     573           0 :     inFrame[9] += (float)1.84854878e-3;
     574             : 
     575             :     /* Tell to upper-band the number of bytes used so far.
     576             :      * This is for payload limitation. */
     577           0 :     instUB->ISACencUB_obj.numBytesUsed =
     578           0 :         (int16_t)(streamLenLB + 1 + LEN_CHECK_SUM_WORD8);
     579             :     /* Encode upper-band. */
     580           0 :     switch (instISAC->bandwidthKHz) {
     581             :       case isac12kHz: {
     582           0 :         streamLenUB = WebRtcIsac_EncodeUb12(&instISAC->transform_tables,
     583             :                                             inFrame, &instUB->ISACencUB_obj,
     584             :                                             jitterInfo);
     585           0 :         break;
     586             :       }
     587             :       case isac16kHz: {
     588           0 :         streamLenUB = WebRtcIsac_EncodeUb16(&instISAC->transform_tables,
     589             :                                             inFrame, &instUB->ISACencUB_obj,
     590             :                                             jitterInfo);
     591           0 :         break;
     592             :       }
     593             :       case isac8kHz: {
     594           0 :         streamLenUB = 0;
     595           0 :         break;
     596             :       }
     597             :     }
     598             : 
     599           0 :     if ((streamLenUB < 0) && (streamLenUB != -ISAC_PAYLOAD_LARGER_THAN_LIMIT)) {
     600             :       /* An error has happened but this is not the error due to a
     601             :        * bit-stream larger than the limit. */
     602           0 :       return -1;
     603             :     }
     604             : 
     605           0 :     if (streamLenLB == 0) {
     606           0 :       return 0;
     607             :     }
     608             : 
     609             :     /* One byte is allocated for the length. According to older decoders
     610             :        so the length bit-stream plus one byte for size and
     611             :        LEN_CHECK_SUM_WORD8 for the checksum should be less than or equal
     612             :        to 255. */
     613           0 :     if ((streamLenUB > (255 - (LEN_CHECK_SUM_WORD8 + 1))) ||
     614             :         (streamLenUB == -ISAC_PAYLOAD_LARGER_THAN_LIMIT)) {
     615             :       /* We have got a too long bit-stream we skip the upper-band
     616             :        * bit-stream for this frame. */
     617           0 :       streamLenUB = 0;
     618             :     }
     619             : 
     620           0 :     memcpy(encoded, instLB->ISACencLB_obj.bitstr_obj.stream, streamLenLB);
     621           0 :     streamLen = streamLenLB;
     622           0 :     if (streamLenUB > 0) {
     623           0 :       encoded[streamLenLB] = (uint8_t)(streamLenUB + 1 + LEN_CHECK_SUM_WORD8);
     624           0 :       memcpy(&encoded[streamLenLB + 1],
     625           0 :              instUB->ISACencUB_obj.bitstr_obj.stream,
     626             :              streamLenUB);
     627           0 :       streamLen += encoded[streamLenLB];
     628             :     } else {
     629           0 :       encoded[streamLenLB] = 0;
     630             :     }
     631             :   } else {
     632           0 :     if (streamLenLB == 0) {
     633           0 :       return 0;
     634             :     }
     635           0 :     memcpy(encoded, instLB->ISACencLB_obj.bitstr_obj.stream, streamLenLB);
     636           0 :     streamLenUB = 0;
     637           0 :     streamLen = streamLenLB;
     638             :   }
     639             : 
     640             :   /* Add Garbage if required. */
     641           0 :   bottleneck = WebRtcIsac_GetUplinkBandwidth(&instISAC->bwestimator_obj);
     642           0 :   if (instISAC->codingMode == 0) {
     643             :     int minBytes;
     644             :     int limit;
     645             :     uint8_t* ptrGarbage;
     646             : 
     647           0 :     instISAC->MaxDelay = (double)WebRtcIsac_GetUplinkMaxDelay(
     648           0 :                            &instISAC->bwestimator_obj);
     649             : 
     650             :     /* Update rate model and get minimum number of bytes in this packet. */
     651           0 :     minBytes = WebRtcIsac_GetMinBytes(
     652             :         &(instISAC->rate_data_obj), streamLen,
     653           0 :         instISAC->instLB.ISACencLB_obj.current_framesamples, bottleneck,
     654             :         instISAC->MaxDelay, instISAC->bandwidthKHz);
     655             : 
     656             :     /* Make sure MinBytes does not exceed packet size limit. */
     657           0 :     if (instISAC->bandwidthKHz == isac8kHz) {
     658           0 :       if (instLB->ISACencLB_obj.current_framesamples == FRAMESAMPLES) {
     659           0 :         limit = instLB->ISACencLB_obj.payloadLimitBytes30;
     660             :       } else {
     661           0 :         limit = instLB->ISACencLB_obj.payloadLimitBytes60;
     662             :       }
     663             :     } else {
     664           0 :       limit = instUB->ISACencUB_obj.maxPayloadSizeBytes;
     665             :     }
     666           0 :     minBytes = (minBytes > limit) ? limit : minBytes;
     667             : 
     668             :     /* Make sure we don't allow more than 255 bytes of garbage data.
     669             :      * We store the length of the garbage data in 8 bits in the bitstream,
     670             :      * 255 is the max garbage length we can signal using 8 bits. */
     671           0 :     if ((instISAC->bandwidthKHz == isac8kHz) ||
     672             :         (streamLenUB == 0)) {
     673           0 :       ptrGarbage = &encoded[streamLenLB];
     674           0 :       limit = streamLen + 255;
     675             :     } else {
     676           0 :       ptrGarbage = &encoded[streamLenLB + 1 + streamLenUB];
     677           0 :       limit = streamLen + (255 - encoded[streamLenLB]);
     678             :     }
     679           0 :     minBytes = (minBytes > limit) ? limit : minBytes;
     680             : 
     681           0 :     garbageLen = (minBytes > streamLen) ? (uint8_t)(minBytes - streamLen) : 0;
     682             : 
     683             :     /* Save data for creation of multiple bit-streams. */
     684             :     /* If bit-stream too short then add garbage at the end. */
     685           0 :     if (garbageLen > 0) {
     686             :       /* Overwrite the garbage area to avoid leaking possibly sensitive data
     687             :          over the network. This also makes the output deterministic. */
     688           0 :       memset(ptrGarbage, 0, garbageLen);
     689             : 
     690             :       /* For a correct length of the upper-band bit-stream together
     691             :        * with the garbage. Garbage is embeded in upper-band bit-stream.
     692             :        * That is the only way to preserve backward compatibility. */
     693           0 :       if ((instISAC->bandwidthKHz == isac8kHz) ||
     694             :           (streamLenUB == 0)) {
     695           0 :         encoded[streamLenLB] = garbageLen;
     696             :       } else {
     697           0 :         encoded[streamLenLB] += garbageLen;
     698             :         /* Write the length of the garbage at the end of the upper-band
     699             :          *  bit-stream, if exists. This helps for sanity check. */
     700           0 :         encoded[streamLenLB + 1 + streamLenUB] = garbageLen;
     701             : 
     702             :       }
     703           0 :       streamLen += garbageLen;
     704             :     }
     705             :   } else {
     706             :     /* update rate model */
     707           0 :     WebRtcIsac_UpdateRateModel(
     708             :         &instISAC->rate_data_obj, streamLen,
     709           0 :         instISAC->instLB.ISACencLB_obj.current_framesamples, bottleneck);
     710           0 :     garbageLen = 0;
     711             :   }
     712             : 
     713             :   /* Generate CRC if required. */
     714           0 :   if ((instISAC->bandwidthKHz != isac8kHz) && (streamLenUB > 0)) {
     715             :     uint32_t crc;
     716             : 
     717           0 :     WebRtcIsac_GetCrc((int16_t*)(&(encoded[streamLenLB + 1])),
     718             :                       streamLenUB + garbageLen, &crc);
     719             : #ifndef WEBRTC_ARCH_BIG_ENDIAN
     720           0 :     for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) {
     721           0 :       encoded[streamLen - LEN_CHECK_SUM_WORD8 + k] =
     722           0 :           (uint8_t)(crc >> (24 - k * 8));
     723             :     }
     724             : #else
     725             :     memcpy(&encoded[streamLenLB + streamLenUB + 1], &crc, LEN_CHECK_SUM_WORD8);
     726             : #endif
     727             :   }
     728           0 :   return streamLen;
     729             : }
     730             : 
     731             : 
     732             : /******************************************************************************
     733             :  * WebRtcIsac_GetNewBitStream(...)
     734             :  *
     735             :  * This function returns encoded data, with the recieved bwe-index in the
     736             :  * stream. If the rate is set to a value less than bottleneck of codec
     737             :  * the new bistream will be re-encoded with the given target rate.
     738             :  * It should always return a complete packet, i.e. only called once
     739             :  * even for 60 msec frames.
     740             :  *
     741             :  * NOTE 1! This function does not write in the ISACStruct, it is not allowed.
     742             :  * NOTE 2! Rates larger than the bottleneck of the codec will be limited
     743             :  *         to the current bottleneck.
     744             :  *
     745             :  * Input:
     746             :  *        - ISAC_main_inst    : ISAC instance.
     747             :  *        - bweIndex          : Index of bandwidth estimate to put in new
     748             :  *                              bitstream
     749             :  *        - rate              : target rate of the transcoder is bits/sec.
     750             :  *                              Valid values are the accepted rate in iSAC,
     751             :  *                              i.e. 10000 to 56000.
     752             :  *
     753             :  * Output:
     754             :  *        - encoded           : The encoded data vector
     755             :  *
     756             :  * Return value               : >0 - Length (in bytes) of coded data
     757             :  *                              -1 - Error  or called in SWB mode
     758             :  *                                 NOTE! No error code is written to
     759             :  *                                 the struct since it is only allowed to read
     760             :  *                                 the struct.
     761             :  */
     762           0 : int16_t WebRtcIsac_GetNewBitStream(ISACStruct*  ISAC_main_inst,
     763             :                                    int16_t  bweIndex,
     764             :                                    int16_t  jitterInfo,
     765             :                                    int32_t  rate,
     766             :                                    uint8_t* encoded,
     767             :                                    int16_t  isRCU) {
     768             :   Bitstr iSACBitStreamInst;   /* Local struct for bitstream handling */
     769             :   int16_t streamLenLB;
     770             :   int16_t streamLenUB;
     771             :   int16_t totalStreamLen;
     772             :   double gain2;
     773             :   double gain1;
     774             :   float scale;
     775             :   enum ISACBandwidth bandwidthKHz;
     776             :   double rateLB;
     777             :   double rateUB;
     778             :   int32_t currentBN;
     779             :   uint32_t crc;
     780             : #ifndef WEBRTC_ARCH_BIG_ENDIAN
     781             :   int16_t  k;
     782             : #endif
     783           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
     784             : 
     785           0 :   if ((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
     786             :       BIT_MASK_ENC_INIT) {
     787           0 :     return -1;
     788             :   }
     789             : 
     790             :   /* Get the bottleneck of this iSAC and limit the
     791             :    * given rate to the current bottleneck. */
     792           0 :   WebRtcIsac_GetUplinkBw(ISAC_main_inst, &currentBN);
     793           0 :   if (rate > currentBN) {
     794           0 :     rate = currentBN;
     795             :   }
     796             : 
     797           0 :   if (WebRtcIsac_RateAllocation(rate, &rateLB, &rateUB, &bandwidthKHz) < 0) {
     798           0 :     return -1;
     799             :   }
     800             : 
     801             :   /* Cannot transcode from 16 kHz to 12 kHz. */
     802           0 :   if ((bandwidthKHz == isac12kHz) &&
     803           0 :       (instISAC->bandwidthKHz == isac16kHz)) {
     804           0 :     return -1;
     805             :   }
     806             : 
     807             :   /* A gain [dB] for the given rate. */
     808           0 :   gain1 = WebRtcIsac_GetSnr(
     809           0 :       rateLB, instISAC->instLB.ISACencLB_obj.current_framesamples);
     810             :   /* The gain [dB] of this iSAC. */
     811           0 :   gain2 = WebRtcIsac_GetSnr(
     812             :       instISAC->instLB.ISACencLB_obj.bottleneck,
     813           0 :       instISAC->instLB.ISACencLB_obj.current_framesamples);
     814             : 
     815             :   /* Scale is the ratio of two gains in normal domain. */
     816           0 :   scale = (float)pow(10, (gain1 - gain2) / 20.0);
     817             :   /* Change the scale if this is a RCU bit-stream. */
     818           0 :   scale = (isRCU) ? (scale * RCU_TRANSCODING_SCALE) : scale;
     819             : 
     820           0 :   streamLenLB = WebRtcIsac_EncodeStoredDataLb(
     821           0 :                   &instISAC->instLB.ISACencLB_obj.SaveEnc_obj,
     822             :                   &iSACBitStreamInst, bweIndex, scale);
     823             : 
     824           0 :   if (streamLenLB < 0) {
     825           0 :     return -1;
     826             :   }
     827             : 
     828             :   /* Convert from bytes to int16_t. */
     829           0 :   memcpy(encoded, iSACBitStreamInst.stream, streamLenLB);
     830             : 
     831           0 :   if (bandwidthKHz == isac8kHz) {
     832           0 :     return streamLenLB;
     833             :   }
     834             : 
     835           0 :   totalStreamLen = streamLenLB;
     836             :   /* super-wideband is always at 30ms.
     837             :    * These gains are in dB.
     838             :    * Gain for the given rate. */
     839           0 :   gain1 = WebRtcIsac_GetSnr(rateUB, FRAMESAMPLES);
     840             :   /* Gain of this iSAC */
     841           0 :   gain2 = WebRtcIsac_GetSnr(instISAC->instUB.ISACencUB_obj.bottleneck,
     842             :                             FRAMESAMPLES);
     843             : 
     844             :   /* Scale is the ratio of two gains in normal domain. */
     845           0 :   scale = (float)pow(10, (gain1 - gain2) / 20.0);
     846             : 
     847             :   /* Change the scale if this is a RCU bit-stream. */
     848           0 :   scale = (isRCU)? (scale * RCU_TRANSCODING_SCALE_UB) : scale;
     849             : 
     850           0 :   streamLenUB = WebRtcIsac_EncodeStoredDataUb(
     851           0 :                   &(instISAC->instUB.ISACencUB_obj.SaveEnc_obj),
     852             :                   &iSACBitStreamInst, jitterInfo, scale,
     853             :                   instISAC->bandwidthKHz);
     854             : 
     855           0 :   if (streamLenUB < 0) {
     856           0 :     return -1;
     857             :   }
     858             : 
     859           0 :   if (streamLenUB + 1 + LEN_CHECK_SUM_WORD8 > 255) {
     860           0 :     return streamLenLB;
     861             :   }
     862             : 
     863           0 :   totalStreamLen = streamLenLB + streamLenUB + 1 + LEN_CHECK_SUM_WORD8;
     864           0 :   encoded[streamLenLB] = streamLenUB + 1 + LEN_CHECK_SUM_WORD8;
     865             : 
     866           0 :   memcpy(&encoded[streamLenLB + 1], iSACBitStreamInst.stream,
     867             :          streamLenUB);
     868             : 
     869           0 :   WebRtcIsac_GetCrc((int16_t*)(&(encoded[streamLenLB + 1])),
     870             :                     streamLenUB, &crc);
     871             : #ifndef WEBRTC_ARCH_BIG_ENDIAN
     872           0 :   for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) {
     873           0 :     encoded[totalStreamLen - LEN_CHECK_SUM_WORD8 + k] =
     874           0 :       (uint8_t)((crc >> (24 - k * 8)) & 0xFF);
     875             :   }
     876             : #else
     877             :   memcpy(&encoded[streamLenLB + streamLenUB + 1], &crc,
     878             :          LEN_CHECK_SUM_WORD8);
     879             : #endif
     880           0 :   return totalStreamLen;
     881             : }
     882             : 
     883             : 
     884             : /****************************************************************************
     885             :  * DecoderInitLb(...) - internal function for initialization of
     886             :  *                                Lower Band
     887             :  * DecoderInitUb(...) - internal function for initialization of
     888             :  *                                Upper Band
     889             :  * WebRtcIsac_DecoderInit(...) - API function
     890             :  *
     891             :  * This function initializes a ISAC instance prior to the decoder calls.
     892             :  *
     893             :  * Input:
     894             :  *        - ISAC_main_inst    : ISAC instance.
     895             :  */
     896           0 : static void DecoderInitLb(ISACLBStruct* instISAC) {
     897             :   int i;
     898             :   /* Initialize stream vector to zero. */
     899           0 :   for (i = 0; i < STREAM_SIZE_MAX_60; i++) {
     900           0 :     instISAC->ISACdecLB_obj.bitstr_obj.stream[i] = 0;
     901             :   }
     902             : 
     903           0 :   WebRtcIsac_InitMasking(&instISAC->ISACdecLB_obj.maskfiltstr_obj);
     904           0 :   WebRtcIsac_InitPostFilterbank(
     905             :     &instISAC->ISACdecLB_obj.postfiltbankstr_obj);
     906           0 :   WebRtcIsac_InitPitchFilter(&instISAC->ISACdecLB_obj.pitchfiltstr_obj);
     907           0 : }
     908             : 
     909           0 : static void DecoderInitUb(ISACUBStruct* instISAC) {
     910             :   int i;
     911             :   /* Init stream vector to zero */
     912           0 :   for (i = 0; i < STREAM_SIZE_MAX_60; i++) {
     913           0 :     instISAC->ISACdecUB_obj.bitstr_obj.stream[i] = 0;
     914             :   }
     915             : 
     916           0 :   WebRtcIsac_InitMasking(&instISAC->ISACdecUB_obj.maskfiltstr_obj);
     917           0 :   WebRtcIsac_InitPostFilterbank(
     918             :     &instISAC->ISACdecUB_obj.postfiltbankstr_obj);
     919           0 : }
     920             : 
     921           0 : void WebRtcIsac_DecoderInit(ISACStruct* ISAC_main_inst) {
     922           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
     923             : 
     924           0 :   DecoderInitLb(&instISAC->instLB);
     925           0 :   if (instISAC->decoderSamplingRateKHz == kIsacSuperWideband) {
     926           0 :     memset(instISAC->synthesisFBState1, 0,
     927             :            FB_STATE_SIZE_WORD32 * sizeof(int32_t));
     928           0 :     memset(instISAC->synthesisFBState2, 0,
     929             :            FB_STATE_SIZE_WORD32 * sizeof(int32_t));
     930           0 :     DecoderInitUb(&(instISAC->instUB));
     931             :   }
     932           0 :   if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != BIT_MASK_ENC_INIT) {
     933           0 :     WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj,
     934             :                                       instISAC->encoderSamplingRateKHz,
     935             :                                       instISAC->decoderSamplingRateKHz);
     936             :   }
     937           0 :   instISAC->initFlag |= BIT_MASK_DEC_INIT;
     938           0 :   instISAC->resetFlag_8kHz = 0;
     939           0 : }
     940             : 
     941             : 
     942             : /****************************************************************************
     943             :  * WebRtcIsac_UpdateBwEstimate(...)
     944             :  *
     945             :  * This function updates the estimate of the bandwidth.
     946             :  *
     947             :  * NOTE:
     948             :  * The estimates of bandwidth is not valid if the sample rate of the far-end
     949             :  * encoder is set to 48 kHz and send timestamps are increamented according to
     950             :  * 48 kHz sampling rate.
     951             :  *
     952             :  * Input:
     953             :  *        - ISAC_main_inst    : ISAC instance.
     954             :  *        - encoded           : encoded ISAC frame(s).
     955             :  *        - packet_size       : size of the packet.
     956             :  *        - rtp_seq_number    : the RTP number of the packet.
     957             :  *        - arr_ts            : the arrival time of the packet (from NetEq)
     958             :  *                              in samples.
     959             :  *
     960             :  * Return value               :  0 - Ok
     961             :  *                              -1 - Error
     962             :  */
     963           0 : int16_t WebRtcIsac_UpdateBwEstimate(ISACStruct* ISAC_main_inst,
     964             :                                     const uint8_t* encoded,
     965             :                                     size_t packet_size,
     966             :                                     uint16_t rtp_seq_number,
     967             :                                     uint32_t send_ts,
     968             :                                     uint32_t arr_ts) {
     969           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
     970             :   Bitstr streamdata;
     971             : #ifndef WEBRTC_ARCH_BIG_ENDIAN
     972             :   int k;
     973             : #endif
     974             :   int16_t err;
     975             : 
     976             :   /* Check if decoder initiated. */
     977           0 :   if ((instISAC->initFlag & BIT_MASK_DEC_INIT) != BIT_MASK_DEC_INIT) {
     978           0 :     instISAC->errorCode = ISAC_DECODER_NOT_INITIATED;
     979           0 :     return -1;
     980             :   }
     981             : 
     982             :   /* Check that the size of the packet is valid, and if not return without
     983             :    * updating the bandwidth estimate. A valid size is at least 10 bytes. */
     984           0 :   if (packet_size < 10) {
     985             :     /* Return error code if the packet length is null. */
     986           0 :     instISAC->errorCode = ISAC_EMPTY_PACKET;
     987           0 :     return -1;
     988             :   }
     989             : 
     990           0 :   WebRtcIsac_ResetBitstream(&(streamdata));
     991             : 
     992             : #ifndef WEBRTC_ARCH_BIG_ENDIAN
     993           0 :   for (k = 0; k < 10; k++) {
     994           0 :     uint16_t ek = ((const uint16_t*)encoded)[k >> 1];
     995           0 :     streamdata.stream[k] = (uint8_t)((ek >> ((k & 1) << 3)) & 0xff);
     996             :   }
     997             : #else
     998             :   memcpy(streamdata.stream, encoded, 10);
     999             : #endif
    1000             : 
    1001           0 :   err = WebRtcIsac_EstimateBandwidth(&instISAC->bwestimator_obj, &streamdata,
    1002             :                                      packet_size, rtp_seq_number, send_ts,
    1003             :                                      arr_ts, instISAC->encoderSamplingRateKHz,
    1004             :                                      instISAC->decoderSamplingRateKHz);
    1005           0 :   if (err < 0) {
    1006             :     /* Return error code if something went wrong. */
    1007           0 :     instISAC->errorCode = -err;
    1008           0 :     return -1;
    1009             :   }
    1010           0 :   return 0;
    1011             : }
    1012             : 
    1013           0 : static int Decode(ISACStruct* ISAC_main_inst,
    1014             :                   const uint8_t* encoded,
    1015             :                   size_t lenEncodedBytes,
    1016             :                   int16_t* decoded,
    1017             :                   int16_t* speechType,
    1018             :                   int16_t isRCUPayload) {
    1019             :   /* Number of samples (480 or 960), output from decoder
    1020             :      that were actually used in the encoder/decoder
    1021             :      (determined on the fly). */
    1022             :   int16_t numSamplesLB;
    1023             :   int16_t numSamplesUB;
    1024             :   int16_t speechIdx;
    1025             :   float outFrame[MAX_FRAMESAMPLES];
    1026             :   int16_t outFrameLB[MAX_FRAMESAMPLES];
    1027             :   int16_t outFrameUB[MAX_FRAMESAMPLES];
    1028             :   int numDecodedBytesLBint;
    1029             :   size_t numDecodedBytesLB;
    1030             :   int numDecodedBytesUB;
    1031             :   size_t lenEncodedLBBytes;
    1032           0 :   int16_t validChecksum = 1;
    1033             :   int16_t k;
    1034             :   uint16_t numLayer;
    1035             :   size_t totSizeBytes;
    1036             :   int16_t err;
    1037             : 
    1038           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    1039           0 :   ISACUBDecStruct* decInstUB = &(instISAC->instUB.ISACdecUB_obj);
    1040           0 :   ISACLBDecStruct* decInstLB = &(instISAC->instLB.ISACdecLB_obj);
    1041             : 
    1042             :   /* Check if decoder initiated. */
    1043           0 :   if ((instISAC->initFlag & BIT_MASK_DEC_INIT) !=
    1044             :       BIT_MASK_DEC_INIT) {
    1045           0 :     instISAC->errorCode = ISAC_DECODER_NOT_INITIATED;
    1046           0 :     return -1;
    1047             :   }
    1048             : 
    1049           0 :   if (lenEncodedBytes == 0) {
    1050             :     /* return error code if the packet length is null. */
    1051           0 :     instISAC->errorCode = ISAC_EMPTY_PACKET;
    1052           0 :     return -1;
    1053             :   }
    1054             : 
    1055             :   /* The size of the encoded lower-band is bounded by
    1056             :    * STREAM_SIZE_MAX. If a payload with the size larger than STREAM_SIZE_MAX
    1057             :    * is received, it is not considered erroneous. */
    1058           0 :   lenEncodedLBBytes = (lenEncodedBytes > STREAM_SIZE_MAX) ?
    1059             :       STREAM_SIZE_MAX : lenEncodedBytes;
    1060             : 
    1061             :   /* Copy to lower-band bit-stream structure. */
    1062           0 :   memcpy(instISAC->instLB.ISACdecLB_obj.bitstr_obj.stream, encoded,
    1063             :          lenEncodedLBBytes);
    1064             : 
    1065             :   /* We need to initialize numSamplesLB to something; otherwise, in the test
    1066             :      for whether we should return -1 below, the compiler might generate code
    1067             :      that fools Memcheck (Valgrind) into thinking that the control flow depends
    1068             :      on the uninitialized value in numSamplesLB (since WebRtcIsac_DecodeLb will
    1069             :      not fill it in if it fails and returns -1). */
    1070           0 :   numSamplesLB = 0;
    1071             : 
    1072             :   /* Regardless of that the current codec is setup to work in
    1073             :    * wideband or super-wideband, the decoding of the lower-band
    1074             :    * has to be performed. */
    1075           0 :   numDecodedBytesLBint = WebRtcIsac_DecodeLb(&instISAC->transform_tables,
    1076             :                                              outFrame, decInstLB,
    1077             :                                              &numSamplesLB, isRCUPayload);
    1078           0 :   numDecodedBytesLB = (size_t)numDecodedBytesLBint;
    1079           0 :   if ((numDecodedBytesLBint < 0) ||
    1080           0 :       (numDecodedBytesLB > lenEncodedLBBytes) ||
    1081           0 :       (numSamplesLB > MAX_FRAMESAMPLES)) {
    1082           0 :     instISAC->errorCode = ISAC_LENGTH_MISMATCH;
    1083           0 :     return -1;
    1084             :   }
    1085             : 
    1086             :   /* Error Check, we accept multi-layer bit-stream This will limit number
    1087             :    * of iterations of the while loop. Even without this the number
    1088             :    * of iterations is limited. */
    1089           0 :   numLayer = 1;
    1090           0 :   totSizeBytes = numDecodedBytesLB;
    1091           0 :   while (totSizeBytes != lenEncodedBytes) {
    1092           0 :     if ((totSizeBytes > lenEncodedBytes) ||
    1093           0 :         (encoded[totSizeBytes] == 0) ||
    1094             :         (numLayer > MAX_NUM_LAYERS)) {
    1095           0 :       instISAC->errorCode = ISAC_LENGTH_MISMATCH;
    1096           0 :       return -1;
    1097             :     }
    1098           0 :     totSizeBytes += encoded[totSizeBytes];
    1099           0 :     numLayer++;
    1100             :   }
    1101             : 
    1102           0 :   if (instISAC->decoderSamplingRateKHz == kIsacWideband) {
    1103           0 :     for (k = 0; k < numSamplesLB; k++) {
    1104           0 :       if (outFrame[k] > 32767) {
    1105           0 :         decoded[k] = 32767;
    1106           0 :       } else if (outFrame[k] < -32768) {
    1107           0 :         decoded[k] = -32768;
    1108             :       } else {
    1109           0 :         decoded[k] = (int16_t)WebRtcIsac_lrint(outFrame[k]);
    1110             :       }
    1111             :     }
    1112           0 :     numSamplesUB = 0;
    1113             :   } else {
    1114             :     uint32_t crc;
    1115             :     /* We don't accept larger than 30ms (480 samples at lower-band)
    1116             :      * frame-size. */
    1117           0 :     for (k = 0; k < numSamplesLB; k++) {
    1118           0 :       if (outFrame[k] > 32767) {
    1119           0 :         outFrameLB[k] = 32767;
    1120           0 :       } else if (outFrame[k] < -32768) {
    1121           0 :         outFrameLB[k] = -32768;
    1122             :       } else {
    1123           0 :         outFrameLB[k] = (int16_t)WebRtcIsac_lrint(outFrame[k]);
    1124             :       }
    1125             :     }
    1126             : 
    1127             :     /* Check for possible error, and if upper-band stream exists. */
    1128           0 :     if (numDecodedBytesLB == lenEncodedBytes) {
    1129             :       /* Decoding was successful. No super-wideband bit-stream exists. */
    1130           0 :       numSamplesUB = numSamplesLB;
    1131           0 :       memset(outFrameUB, 0, sizeof(int16_t) *  numSamplesUB);
    1132             : 
    1133             :       /* Prepare for the potential increase of signal bandwidth. */
    1134           0 :       instISAC->resetFlag_8kHz = 2;
    1135             :     } else {
    1136             :       /* This includes the checksum and the bytes that stores the length. */
    1137           0 :       int16_t lenNextStream = encoded[numDecodedBytesLB];
    1138             : 
    1139             :       /* Is this garbage or valid super-wideband bit-stream?
    1140             :        * Check if checksum is valid. */
    1141           0 :       if (lenNextStream <= (LEN_CHECK_SUM_WORD8 + 1)) {
    1142             :         /* Such a small second layer cannot be super-wideband layer.
    1143             :          * It must be a short garbage. */
    1144           0 :         validChecksum = 0;
    1145             :       } else {
    1146             :         /* Run CRC to see if the checksum match. */
    1147           0 :         WebRtcIsac_GetCrc((int16_t*)(&encoded[numDecodedBytesLB + 1]),
    1148             :                           lenNextStream - LEN_CHECK_SUM_WORD8 - 1, &crc);
    1149             : 
    1150           0 :         validChecksum = 1;
    1151           0 :         for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) {
    1152           0 :           validChecksum &= (((crc >> (24 - k * 8)) & 0xFF) ==
    1153           0 :                             encoded[numDecodedBytesLB + lenNextStream -
    1154           0 :                                           LEN_CHECK_SUM_WORD8 + k]);
    1155             :         }
    1156             :       }
    1157             : 
    1158           0 :       if (!validChecksum) {
    1159             :         /* This is a garbage, we have received a wideband
    1160             :          * bit-stream with garbage. */
    1161           0 :         numSamplesUB = numSamplesLB;
    1162           0 :         memset(outFrameUB, 0, sizeof(int16_t) * numSamplesUB);
    1163             :       } else {
    1164             :         /* A valid super-wideband biststream exists. */
    1165             :         enum ISACBandwidth bandwidthKHz;
    1166             :         int32_t maxDelayBit;
    1167             : 
    1168             :         /* If we have super-wideband bit-stream, we cannot
    1169             :          * have 60 ms frame-size. */
    1170           0 :         if (numSamplesLB > FRAMESAMPLES) {
    1171           0 :           instISAC->errorCode = ISAC_LENGTH_MISMATCH;
    1172           0 :           return -1;
    1173             :         }
    1174             : 
    1175             :         /* The rest of the bit-stream contains the upper-band
    1176             :          * bit-stream curently this is the only thing there,
    1177             :          * however, we might add more layers. */
    1178             : 
    1179             :         /* Have to exclude one byte where the length is stored
    1180             :          * and last 'LEN_CHECK_SUM_WORD8' bytes where the
    1181             :          * checksum is stored. */
    1182           0 :         lenNextStream -= (LEN_CHECK_SUM_WORD8 + 1);
    1183             : 
    1184           0 :         memcpy(decInstUB->bitstr_obj.stream,
    1185           0 :                &encoded[numDecodedBytesLB + 1], lenNextStream);
    1186             : 
    1187             :         /* Reset bit-stream object, this is the first decoding. */
    1188           0 :         WebRtcIsac_ResetBitstream(&(decInstUB->bitstr_obj));
    1189             : 
    1190             :         /* Decode jitter information. */
    1191           0 :         err = WebRtcIsac_DecodeJitterInfo(&decInstUB->bitstr_obj, &maxDelayBit);
    1192           0 :         if (err < 0) {
    1193           0 :           instISAC->errorCode = -err;
    1194           0 :           return -1;
    1195             :         }
    1196             : 
    1197             :         /* Update jitter info which is in the upper-band bit-stream
    1198             :          * only if the encoder is in super-wideband. Otherwise,
    1199             :          * the jitter info is already embedded in bandwidth index
    1200             :          * and has been updated. */
    1201           0 :         if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) {
    1202           0 :           err = WebRtcIsac_UpdateUplinkJitter(
    1203             :                   &(instISAC->bwestimator_obj), maxDelayBit);
    1204           0 :           if (err < 0) {
    1205           0 :             instISAC->errorCode = -err;
    1206           0 :             return -1;
    1207             :           }
    1208             :         }
    1209             : 
    1210             :         /* Decode bandwidth information. */
    1211           0 :         err = WebRtcIsac_DecodeBandwidth(&decInstUB->bitstr_obj,
    1212             :                                          &bandwidthKHz);
    1213           0 :         if (err < 0) {
    1214           0 :           instISAC->errorCode = -err;
    1215           0 :           return -1;
    1216             :         }
    1217             : 
    1218           0 :         switch (bandwidthKHz) {
    1219             :           case isac12kHz: {
    1220           0 :             numDecodedBytesUB = WebRtcIsac_DecodeUb12(
    1221           0 :                 &instISAC->transform_tables, outFrame, decInstUB, isRCUPayload);
    1222             : 
    1223             :             /* Hang-over for transient alleviation -
    1224             :              * wait two frames to add the upper band going up from 8 kHz. */
    1225           0 :             if (instISAC->resetFlag_8kHz > 0) {
    1226           0 :               if (instISAC->resetFlag_8kHz == 2) {
    1227             :                 /* Silence first and a half frame. */
    1228           0 :                 memset(outFrame, 0, MAX_FRAMESAMPLES *
    1229             :                        sizeof(float));
    1230             :               } else {
    1231           0 :                 const float rampStep = 2.0f / MAX_FRAMESAMPLES;
    1232           0 :                 float rampVal = 0;
    1233           0 :                 memset(outFrame, 0, (MAX_FRAMESAMPLES >> 1) *
    1234             :                        sizeof(float));
    1235             : 
    1236             :                 /* Ramp up second half of second frame. */
    1237           0 :                 for (k = MAX_FRAMESAMPLES / 2; k < MAX_FRAMESAMPLES; k++) {
    1238           0 :                   outFrame[k] *= rampVal;
    1239           0 :                   rampVal += rampStep;
    1240             :                 }
    1241             :               }
    1242           0 :               instISAC->resetFlag_8kHz -= 1;
    1243             :             }
    1244             : 
    1245           0 :             break;
    1246             :           }
    1247             :           case isac16kHz: {
    1248           0 :             numDecodedBytesUB = WebRtcIsac_DecodeUb16(
    1249           0 :                 &instISAC->transform_tables, outFrame, decInstUB, isRCUPayload);
    1250           0 :             break;
    1251             :           }
    1252             :           default:
    1253           0 :             return -1;
    1254             :         }
    1255             : 
    1256           0 :         if (numDecodedBytesUB < 0) {
    1257           0 :           instISAC->errorCode = numDecodedBytesUB;
    1258           0 :           return -1;
    1259             :         }
    1260           0 :         if (numDecodedBytesLB + numDecodedBytesUB > lenEncodedBytes) {
    1261             :           // We have supposedly decoded more bytes than we were given. Likely
    1262             :           // caused by bad input data.
    1263           0 :           instISAC->errorCode = ISAC_LENGTH_MISMATCH;
    1264           0 :           return -1;
    1265             :         }
    1266             : 
    1267             :         /* It might be less due to garbage. */
    1268           0 :         if ((numDecodedBytesUB != lenNextStream) &&
    1269           0 :             (numDecodedBytesUB != (lenNextStream -
    1270           0 :                 encoded[numDecodedBytesLB + 1 + numDecodedBytesUB]))) {
    1271           0 :           instISAC->errorCode = ISAC_LENGTH_MISMATCH;
    1272           0 :           return -1;
    1273             :         }
    1274             : 
    1275             :         /* If there is no error Upper-band always decodes
    1276             :          * 30 ms (480 samples). */
    1277           0 :         numSamplesUB = FRAMESAMPLES;
    1278             : 
    1279             :         /* Convert to W16. */
    1280           0 :         for (k = 0; k < numSamplesUB; k++) {
    1281           0 :           if (outFrame[k] > 32767) {
    1282           0 :             outFrameUB[k] = 32767;
    1283           0 :           } else if (outFrame[k] < -32768) {
    1284           0 :             outFrameUB[k] = -32768;
    1285             :           } else {
    1286           0 :             outFrameUB[k] = (int16_t)WebRtcIsac_lrint(
    1287           0 :                               outFrame[k]);
    1288             :           }
    1289             :         }
    1290             :       }
    1291             :     }
    1292             : 
    1293           0 :     speechIdx = 0;
    1294           0 :     while (speechIdx < numSamplesLB) {
    1295           0 :       WebRtcSpl_SynthesisQMF(&outFrameLB[speechIdx], &outFrameUB[speechIdx],
    1296           0 :                              FRAMESAMPLES_10ms, &decoded[(speechIdx << 1)],
    1297           0 :                              instISAC->synthesisFBState1,
    1298           0 :                              instISAC->synthesisFBState2);
    1299             : 
    1300           0 :       speechIdx += FRAMESAMPLES_10ms;
    1301             :     }
    1302             :   }
    1303           0 :   *speechType = 0;
    1304           0 :   return (numSamplesLB + numSamplesUB);
    1305             : }
    1306             : 
    1307             : 
    1308             : 
    1309             : 
    1310             : 
    1311             : 
    1312             : 
    1313             : /****************************************************************************
    1314             :  * WebRtcIsac_Decode(...)
    1315             :  *
    1316             :  * This function decodes a ISAC frame. Output speech length
    1317             :  * will be a multiple of 480 samples: 480 or 960 samples,
    1318             :  * depending on the  frameSize (30 or 60 ms).
    1319             :  *
    1320             :  * Input:
    1321             :  *        - ISAC_main_inst    : ISAC instance.
    1322             :  *        - encoded           : encoded ISAC frame(s)
    1323             :  *        - len               : bytes in encoded vector
    1324             :  *
    1325             :  * Output:
    1326             :  *        - decoded           : The decoded vector
    1327             :  *
    1328             :  * Return value               : >0 - number of samples in decoded vector
    1329             :  *                              -1 - Error
    1330             :  */
    1331             : 
    1332           0 : int WebRtcIsac_Decode(ISACStruct* ISAC_main_inst,
    1333             :                       const uint8_t* encoded,
    1334             :                       size_t lenEncodedBytes,
    1335             :                       int16_t* decoded,
    1336             :                       int16_t* speechType) {
    1337           0 :   int16_t isRCUPayload = 0;
    1338           0 :   return Decode(ISAC_main_inst, encoded, lenEncodedBytes, decoded,
    1339             :                 speechType, isRCUPayload);
    1340             : }
    1341             : 
    1342             : /****************************************************************************
    1343             :  * WebRtcIsac_DecodeRcu(...)
    1344             :  *
    1345             :  * This function decodes a redundant (RCU) iSAC frame. Function is called in
    1346             :  * NetEq with a stored RCU payload in case of packet loss. Output speech length
    1347             :  * will be a multiple of 480 samples: 480 or 960 samples,
    1348             :  * depending on the framesize (30 or 60 ms).
    1349             :  *
    1350             :  * Input:
    1351             :  *      - ISAC_main_inst     : ISAC instance.
    1352             :  *      - encoded            : encoded ISAC RCU frame(s)
    1353             :  *      - len                : bytes in encoded vector
    1354             :  *
    1355             :  * Output:
    1356             :  *      - decoded            : The decoded vector
    1357             :  *
    1358             :  * Return value              : >0 - number of samples in decoded vector
    1359             :  *                             -1 - Error
    1360             :  */
    1361             : 
    1362             : 
    1363             : 
    1364           0 : int WebRtcIsac_DecodeRcu(ISACStruct* ISAC_main_inst,
    1365             :                          const uint8_t* encoded,
    1366             :                          size_t lenEncodedBytes,
    1367             :                          int16_t* decoded,
    1368             :                          int16_t* speechType) {
    1369           0 :   int16_t isRCUPayload = 1;
    1370           0 :   return Decode(ISAC_main_inst, encoded, lenEncodedBytes, decoded,
    1371             :                 speechType, isRCUPayload);
    1372             : }
    1373             : 
    1374             : 
    1375             : /****************************************************************************
    1376             :  * WebRtcIsac_DecodePlc(...)
    1377             :  *
    1378             :  * This function conducts PLC for ISAC frame(s). Output speech length
    1379             :  * will be a multiple of 480 samples: 480 or 960 samples,
    1380             :  * depending on the  frameSize (30 or 60 ms).
    1381             :  *
    1382             :  * Input:
    1383             :  *        - ISAC_main_inst    : ISAC instance.
    1384             :  *        - noOfLostFrames    : Number of PLC frames to produce
    1385             :  *
    1386             :  * Output:
    1387             :  *        - decoded           : The decoded vector
    1388             :  *
    1389             :  * Return value               : Number of samples in decoded PLC vector
    1390             :  */
    1391           0 : size_t WebRtcIsac_DecodePlc(ISACStruct* ISAC_main_inst,
    1392             :                             int16_t* decoded,
    1393             :                             size_t noOfLostFrames) {
    1394           0 :   size_t numSamples = 0;
    1395           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    1396             : 
    1397             :   /* Limit number of frames to two = 60 millisecond.
    1398             :    * Otherwise we exceed data vectors. */
    1399           0 :   if (noOfLostFrames > 2) {
    1400           0 :     noOfLostFrames = 2;
    1401             :   }
    1402             : 
    1403             :   /* Get the number of samples per frame */
    1404           0 :   switch (instISAC->decoderSamplingRateKHz) {
    1405             :     case kIsacWideband: {
    1406           0 :       numSamples = 480 * noOfLostFrames;
    1407           0 :       break;
    1408             :     }
    1409             :     case kIsacSuperWideband: {
    1410           0 :       numSamples = 960 * noOfLostFrames;
    1411           0 :       break;
    1412             :     }
    1413             :   }
    1414             : 
    1415             :   /* Set output samples to zero. */
    1416           0 :   memset(decoded, 0, numSamples * sizeof(int16_t));
    1417           0 :   return numSamples;
    1418             : }
    1419             : 
    1420             : 
    1421             : /****************************************************************************
    1422             :  * ControlLb(...) - Internal function for controlling Lower Band
    1423             :  * ControlUb(...) - Internal function for controlling Upper Band
    1424             :  * WebRtcIsac_Control(...) - API function
    1425             :  *
    1426             :  * This function sets the limit on the short-term average bit rate and the
    1427             :  * frame length. Should be used only in Instantaneous mode.
    1428             :  *
    1429             :  * Input:
    1430             :  *        - ISAC_main_inst    : ISAC instance.
    1431             :  *        - rate              : limit on the short-term average bit rate,
    1432             :  *                              in bits/second (between 10000 and 32000)
    1433             :  *        - frameSize         : number of milliseconds per frame (30 or 60)
    1434             :  *
    1435             :  * Return value               : 0 - ok
    1436             :  *                             -1 - Error
    1437             :  */
    1438           0 : static int16_t ControlLb(ISACLBStruct* instISAC, double rate,
    1439             :                          int16_t frameSize) {
    1440           0 :   if ((rate >= 10000) && (rate <= 32000)) {
    1441           0 :     instISAC->ISACencLB_obj.bottleneck = rate;
    1442             :   } else {
    1443           0 :     return -ISAC_DISALLOWED_BOTTLENECK;
    1444             :   }
    1445             : 
    1446           0 :   if ((frameSize == 30) || (frameSize == 60)) {
    1447           0 :     instISAC->ISACencLB_obj.new_framelength = (FS / 1000) *  frameSize;
    1448             :   } else {
    1449           0 :     return -ISAC_DISALLOWED_FRAME_LENGTH;
    1450             :   }
    1451             : 
    1452           0 :   return 0;
    1453             : }
    1454             : 
    1455           0 : static int16_t ControlUb(ISACUBStruct* instISAC, double rate) {
    1456           0 :   if ((rate >= 10000) && (rate <= 32000)) {
    1457           0 :     instISAC->ISACencUB_obj.bottleneck = rate;
    1458             :   } else {
    1459           0 :     return -ISAC_DISALLOWED_BOTTLENECK;
    1460             :   }
    1461           0 :   return 0;
    1462             : }
    1463             : 
    1464           0 : int16_t WebRtcIsac_Control(ISACStruct* ISAC_main_inst,
    1465             :                            int32_t bottleneckBPS,
    1466             :                            int frameSize) {
    1467           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    1468             :   int16_t status;
    1469             :   double rateLB;
    1470             :   double rateUB;
    1471             :   enum ISACBandwidth bandwidthKHz;
    1472             : 
    1473           0 :   if (instISAC->codingMode == 0) {
    1474             :     /* In adaptive mode. */
    1475           0 :     instISAC->errorCode = ISAC_MODE_MISMATCH;
    1476           0 :     return -1;
    1477             :   }
    1478             : 
    1479             :   /* Check if encoder initiated */
    1480           0 :   if ((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
    1481             :       BIT_MASK_ENC_INIT) {
    1482           0 :     instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
    1483           0 :     return -1;
    1484             :   }
    1485             : 
    1486           0 :   if (instISAC->encoderSamplingRateKHz == kIsacWideband) {
    1487             :     /* If the sampling rate is 16kHz then bandwith should be 8kHz,
    1488             :      * regardless of bottleneck. */
    1489           0 :     bandwidthKHz = isac8kHz;
    1490           0 :     rateLB = (bottleneckBPS > 32000) ? 32000 : bottleneckBPS;
    1491           0 :     rateUB = 0;
    1492             :   } else {
    1493           0 :     if (WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB,
    1494             :                                   &bandwidthKHz) < 0) {
    1495           0 :       return -1;
    1496             :     }
    1497             :   }
    1498             : 
    1499           0 :   if ((instISAC->encoderSamplingRateKHz == kIsacSuperWideband) &&
    1500           0 :       (frameSize != 30) &&
    1501           0 :       (bandwidthKHz != isac8kHz)) {
    1502             :     /* Cannot have 60 ms in super-wideband. */
    1503           0 :     instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH;
    1504           0 :     return -1;
    1505             :   }
    1506             : 
    1507           0 :   status = ControlLb(&instISAC->instLB, rateLB, (int16_t)frameSize);
    1508           0 :   if (status < 0) {
    1509           0 :     instISAC->errorCode = -status;
    1510           0 :     return -1;
    1511             :   }
    1512           0 :   if (bandwidthKHz != isac8kHz) {
    1513           0 :     status = ControlUb(&(instISAC->instUB), rateUB);
    1514           0 :     if (status < 0) {
    1515           0 :       instISAC->errorCode = -status;
    1516           0 :       return -1;
    1517             :     }
    1518             :   }
    1519             : 
    1520             : 
    1521             :   /* Check if bandwidth is changing from wideband to super-wideband
    1522             :    * then we have to synch data buffer of lower & upper-band. Also
    1523             :    * clean up the upper-band data buffer. */
    1524             : 
    1525           0 :   if ((instISAC->bandwidthKHz == isac8kHz) && (bandwidthKHz != isac8kHz)) {
    1526           0 :     memset(instISAC->instUB.ISACencUB_obj.data_buffer_float, 0,
    1527             :            sizeof(float) * (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES));
    1528             : 
    1529           0 :     if (bandwidthKHz == isac12kHz) {
    1530           0 :       instISAC->instUB.ISACencUB_obj.buffer_index =
    1531           0 :         instISAC->instLB.ISACencLB_obj.buffer_index;
    1532             :     } else {
    1533           0 :       instISAC->instUB.ISACencUB_obj.buffer_index =
    1534           0 :           LB_TOTAL_DELAY_SAMPLES + instISAC->instLB.ISACencLB_obj.buffer_index;
    1535             : 
    1536           0 :       memcpy(&(instISAC->instUB.ISACencUB_obj.lastLPCVec),
    1537             :              WebRtcIsac_kMeanLarUb16, sizeof(double) * UB_LPC_ORDER);
    1538             :     }
    1539             :   }
    1540             : 
    1541             :   /* Update the payload limit if the bandwidth is changing. */
    1542           0 :   if (instISAC->bandwidthKHz != bandwidthKHz) {
    1543           0 :     instISAC->bandwidthKHz = bandwidthKHz;
    1544           0 :     UpdatePayloadSizeLimit(instISAC);
    1545             :   }
    1546           0 :   instISAC->bottleneck = bottleneckBPS;
    1547           0 :   return 0;
    1548             : }
    1549             : 
    1550           0 : void WebRtcIsac_SetInitialBweBottleneck(ISACStruct* ISAC_main_inst,
    1551             :                                         int bottleneck_bits_per_second) {
    1552           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    1553           0 :   RTC_DCHECK_GE(bottleneck_bits_per_second, 10000);
    1554           0 :   RTC_DCHECK_LE(bottleneck_bits_per_second, 32000);
    1555           0 :   instISAC->bwestimator_obj.send_bw_avg = (float)bottleneck_bits_per_second;
    1556           0 : }
    1557             : 
    1558             : /****************************************************************************
    1559             :  * WebRtcIsac_ControlBwe(...)
    1560             :  *
    1561             :  * This function sets the initial values of bottleneck and frame-size if
    1562             :  * iSAC is used in channel-adaptive mode. Through this API, users can
    1563             :  * enforce a frame-size for all values of bottleneck. Then iSAC will not
    1564             :  * automatically change the frame-size.
    1565             :  *
    1566             :  *
    1567             :  * Input:
    1568             :  *        - ISAC_main_inst    : ISAC instance.
    1569             :  *        - rateBPS           : initial value of bottleneck in bits/second
    1570             :  *                              10000 <= rateBPS <= 32000 is accepted
    1571             :  *                              For default bottleneck set rateBPS = 0
    1572             :  *        - frameSizeMs       : number of milliseconds per frame (30 or 60)
    1573             :  *        - enforceFrameSize  : 1 to enforce the given frame-size through out
    1574             :  *                              the adaptation process, 0 to let iSAC change
    1575             :  *                              the frame-size if required.
    1576             :  *
    1577             :  * Return value               : 0 - ok
    1578             :  *                             -1 - Error
    1579             :  */
    1580           0 : int16_t WebRtcIsac_ControlBwe(ISACStruct* ISAC_main_inst,
    1581             :                               int32_t bottleneckBPS,
    1582             :                               int frameSizeMs,
    1583             :                               int16_t enforceFrameSize) {
    1584           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    1585             :   enum ISACBandwidth bandwidth;
    1586             : 
    1587             :    /* Check if encoder initiated */
    1588           0 :   if ((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
    1589             :       BIT_MASK_ENC_INIT) {
    1590           0 :     instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
    1591           0 :     return -1;
    1592             :   }
    1593             : 
    1594             :   /* Check that we are in channel-adaptive mode, otherwise, return (-1) */
    1595           0 :   if (instISAC->codingMode != 0) {
    1596           0 :     instISAC->errorCode = ISAC_MODE_MISMATCH;
    1597           0 :     return -1;
    1598             :   }
    1599           0 :   if ((frameSizeMs != 30) &&
    1600           0 :       (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) {
    1601           0 :     return -1;
    1602             :   }
    1603             : 
    1604             :   /* Set structure variable if enforceFrameSize is set. ISAC will then
    1605             :    * keep the chosen frame size. */
    1606           0 :   if (enforceFrameSize != 0) {
    1607           0 :     instISAC->instLB.ISACencLB_obj.enforceFrameSize = 1;
    1608             :   } else {
    1609           0 :     instISAC->instLB.ISACencLB_obj.enforceFrameSize = 0;
    1610             :   }
    1611             : 
    1612             :   /* Set the initial rate. If the input value is zero then the default intial
    1613             :    * rate is used. Otehrwise, values between 10 to 32 kbps are accepted. */
    1614           0 :   if (bottleneckBPS != 0) {
    1615             :     double rateLB;
    1616             :     double rateUB;
    1617           0 :     if (WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB,
    1618             :                                   &bandwidth) < 0) {
    1619           0 :       return -1;
    1620             :     }
    1621           0 :     instISAC->bwestimator_obj.send_bw_avg = (float)bottleneckBPS;
    1622           0 :     instISAC->bandwidthKHz = bandwidth;
    1623             :   }
    1624             : 
    1625             :   /* Set the initial frame-size. If 'enforceFrameSize' is set, the frame-size
    1626             :    *  will not change */
    1627           0 :   if (frameSizeMs != 0) {
    1628           0 :     if ((frameSizeMs  == 30) || (frameSizeMs == 60)) {
    1629           0 :       instISAC->instLB.ISACencLB_obj.new_framelength =
    1630           0 :           (int16_t)((FS / 1000) * frameSizeMs);
    1631             :     } else {
    1632           0 :       instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH;
    1633           0 :       return -1;
    1634             :     }
    1635             :   }
    1636           0 :   return 0;
    1637             : }
    1638             : 
    1639             : 
    1640             : /****************************************************************************
    1641             :  * WebRtcIsac_GetDownLinkBwIndex(...)
    1642             :  *
    1643             :  * This function returns index representing the Bandwidth estimate from
    1644             :  * the other side to this side.
    1645             :  *
    1646             :  * Input:
    1647             :  *        - ISAC_main_inst    : iSAC structure
    1648             :  *
    1649             :  * Output:
    1650             :  *        - bweIndex         : Bandwidth estimate to transmit to other side.
    1651             :  *
    1652             :  */
    1653           0 : int16_t WebRtcIsac_GetDownLinkBwIndex(ISACStruct* ISAC_main_inst,
    1654             :                                       int16_t* bweIndex,
    1655             :                                       int16_t* jitterInfo) {
    1656           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    1657             : 
    1658             :   /* Check if encoder initialized. */
    1659           0 :   if ((instISAC->initFlag & BIT_MASK_DEC_INIT) !=
    1660             :       BIT_MASK_DEC_INIT) {
    1661           0 :     instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
    1662           0 :     return -1;
    1663             :   }
    1664             : 
    1665             :   /* Call function to get Bandwidth Estimate. */
    1666           0 :   WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj), bweIndex,
    1667             :                                        jitterInfo,
    1668             :                                        instISAC->decoderSamplingRateKHz);
    1669           0 :   return 0;
    1670             : }
    1671             : 
    1672             : 
    1673             : /****************************************************************************
    1674             :  * WebRtcIsac_UpdateUplinkBw(...)
    1675             :  *
    1676             :  * This function takes an index representing the Bandwidth estimate from
    1677             :  * this side to other side and updates BWE.
    1678             :  *
    1679             :  * Input:
    1680             :  *        - ISAC_main_inst    : iSAC structure
    1681             :  *        - rateIndex         : Bandwidth estimate from other side.
    1682             :  *
    1683             :  * Return value               : 0 - ok
    1684             :  *                             -1 - index out of range
    1685             :  */
    1686           0 : int16_t WebRtcIsac_UpdateUplinkBw(ISACStruct* ISAC_main_inst,
    1687             :                                   int16_t bweIndex) {
    1688           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    1689             :   int16_t returnVal;
    1690             : 
    1691             :   /* Check if encoder initiated. */
    1692           0 :   if ((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
    1693             :       BIT_MASK_ENC_INIT) {
    1694           0 :     instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
    1695           0 :     return -1;
    1696             :   }
    1697             : 
    1698             :   /* Call function to get Bandwidth Estimate. */
    1699           0 :   returnVal = WebRtcIsac_UpdateUplinkBwImpl(
    1700             :                 &(instISAC->bwestimator_obj), bweIndex,
    1701             :                 instISAC->encoderSamplingRateKHz);
    1702             : 
    1703           0 :   if (returnVal < 0) {
    1704           0 :     instISAC->errorCode = -returnVal;
    1705           0 :     return -1;
    1706             :   } else {
    1707           0 :     return 0;
    1708             :   }
    1709             : }
    1710             : 
    1711             : 
    1712             : /****************************************************************************
    1713             :  * WebRtcIsac_ReadBwIndex(...)
    1714             :  *
    1715             :  * This function returns the index of the Bandwidth estimate from the
    1716             :  * bit-stream.
    1717             :  *
    1718             :  * Input:
    1719             :  *        - encoded           : Encoded bit-stream
    1720             :  *
    1721             :  * Output:
    1722             :  *        - frameLength       : Length of frame in packet (in samples)
    1723             :  *        - bweIndex          : Bandwidth estimate in bit-stream
    1724             :  *
    1725             :  */
    1726           0 : int16_t WebRtcIsac_ReadBwIndex(const uint8_t* encoded,
    1727             :                                int16_t* bweIndex) {
    1728             :   Bitstr streamdata;
    1729             : #ifndef WEBRTC_ARCH_BIG_ENDIAN
    1730             :   int k;
    1731             : #endif
    1732             :   int16_t err;
    1733             : 
    1734           0 :   WebRtcIsac_ResetBitstream(&(streamdata));
    1735             : 
    1736             : #ifndef WEBRTC_ARCH_BIG_ENDIAN
    1737           0 :   for (k = 0; k < 10; k++) {
    1738           0 :     int16_t ek2 = ((const int16_t*)encoded)[k >> 1];
    1739           0 :     streamdata.stream[k] = (uint8_t)((ek2 >> ((k & 1) << 3)) & 0xff);
    1740             :   }
    1741             : #else
    1742             :   memcpy(streamdata.stream, encoded, 10);
    1743             : #endif
    1744             : 
    1745             :   /* Decode frame length. */
    1746           0 :   err = WebRtcIsac_DecodeFrameLen(&streamdata, bweIndex);
    1747           0 :   if (err < 0) {
    1748           0 :     return err;
    1749             :   }
    1750             : 
    1751             :   /* Decode BW estimation. */
    1752           0 :   err = WebRtcIsac_DecodeSendBW(&streamdata, bweIndex);
    1753           0 :   if (err < 0) {
    1754           0 :     return err;
    1755             :   }
    1756             : 
    1757           0 :   return 0;
    1758             : }
    1759             : 
    1760             : 
    1761             : /****************************************************************************
    1762             :  * WebRtcIsac_ReadFrameLen(...)
    1763             :  *
    1764             :  * This function returns the number of samples the decoder will generate if
    1765             :  * the given payload is decoded.
    1766             :  *
    1767             :  * Input:
    1768             :  *        - encoded           : Encoded bitstream
    1769             :  *
    1770             :  * Output:
    1771             :  *        - frameLength       : Length of frame in packet (in samples)
    1772             :  *
    1773             :  */
    1774           0 : int16_t WebRtcIsac_ReadFrameLen(ISACStruct* ISAC_main_inst,
    1775             :                                 const uint8_t* encoded,
    1776             :                                 int16_t* frameLength) {
    1777             :   Bitstr streamdata;
    1778             : #ifndef WEBRTC_ARCH_BIG_ENDIAN
    1779             :   int k;
    1780             : #endif
    1781             :   int16_t err;
    1782             :   ISACMainStruct* instISAC;
    1783             : 
    1784           0 :   WebRtcIsac_ResetBitstream(&(streamdata));
    1785             : 
    1786             : #ifndef WEBRTC_ARCH_BIG_ENDIAN
    1787           0 :   for (k = 0; k < 10; k++) {
    1788           0 :     int16_t ek2 = ((const int16_t*)encoded)[k >> 1];
    1789           0 :     streamdata.stream[k] = (uint8_t)((ek2 >> ((k & 1) << 3)) & 0xff);
    1790             :   }
    1791             : #else
    1792             :   memcpy(streamdata.stream, encoded, 10);
    1793             : #endif
    1794             : 
    1795             :   /* Decode frame length. */
    1796           0 :   err = WebRtcIsac_DecodeFrameLen(&streamdata, frameLength);
    1797           0 :   if (err < 0) {
    1798           0 :     return -1;
    1799             :   }
    1800           0 :   instISAC = (ISACMainStruct*)ISAC_main_inst;
    1801             : 
    1802           0 :   if (instISAC->decoderSamplingRateKHz == kIsacSuperWideband) {
    1803             :     /* The decoded frame length indicates the number of samples in
    1804             :      * lower-band in this case, multiply by 2 to get the total number
    1805             :      * of samples. */
    1806           0 :     *frameLength <<= 1;
    1807             :   }
    1808           0 :   return 0;
    1809             : }
    1810             : 
    1811             : 
    1812             : /*******************************************************************************
    1813             :  * WebRtcIsac_GetNewFrameLen(...)
    1814             :  *
    1815             :  * This function returns the frame length (in samples) of the next packet.
    1816             :  * In the case of channel-adaptive mode, iSAC decides on its frame length based
    1817             :  * on the estimated bottleneck, this AOI allows a user to prepare for the next
    1818             :  * packet (at the encoder).
    1819             :  *
    1820             :  * The primary usage is in CE to make the iSAC works in channel-adaptive mode
    1821             :  *
    1822             :  * Input:
    1823             :  *        - ISAC_main_inst     : iSAC struct
    1824             :  *
    1825             :  * Return Value                : frame lenght in samples
    1826             :  *
    1827             :  */
    1828           0 : int16_t WebRtcIsac_GetNewFrameLen(ISACStruct* ISAC_main_inst) {
    1829           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    1830             : 
    1831             :   /* Return new frame length. */
    1832           0 :   if (instISAC->in_sample_rate_hz == 16000)
    1833           0 :     return (instISAC->instLB.ISACencLB_obj.new_framelength);
    1834             :   else  /* 32000 Hz */
    1835           0 :     return ((instISAC->instLB.ISACencLB_obj.new_framelength) * 2);
    1836             : }
    1837             : 
    1838             : 
    1839             : /****************************************************************************
    1840             :  * WebRtcIsac_GetErrorCode(...)
    1841             :  *
    1842             :  * This function can be used to check the error code of an iSAC instance.
    1843             :  * When a function returns -1 an error code will be set for that instance.
    1844             :  * The function below extracts the code of the last error that occurred in
    1845             :  * the specified instance.
    1846             :  *
    1847             :  * Input:
    1848             :  *        - ISAC_main_inst    : ISAC instance
    1849             :  *
    1850             :  * Return value               : Error code
    1851             :  */
    1852           0 : int16_t WebRtcIsac_GetErrorCode(ISACStruct* ISAC_main_inst) {
    1853           0 :  return ((ISACMainStruct*)ISAC_main_inst)->errorCode;
    1854             : }
    1855             : 
    1856             : 
    1857             : /****************************************************************************
    1858             :  * WebRtcIsac_GetUplinkBw(...)
    1859             :  *
    1860             :  * This function outputs the target bottleneck of the codec. In
    1861             :  * channel-adaptive mode, the target bottleneck is specified through an in-band
    1862             :  * signalling retrieved by bandwidth estimator.
    1863             :  * In channel-independent, also called instantaneous mode, the target
    1864             :  * bottleneck is provided to the encoder by calling xxx_control(...) (if
    1865             :  * xxx_control is never called, the default values are used.).
    1866             :  * Note that the output is the iSAC internal operating bottleneck which might
    1867             :  * differ slightly from the one provided through xxx_control().
    1868             :  *
    1869             :  * Input:
    1870             :  *        - ISAC_main_inst    : iSAC instance
    1871             :  *
    1872             :  * Output:
    1873             :  *        - *bottleneck       : bottleneck in bits/sec
    1874             :  *
    1875             :  * Return value               : -1 if error happens
    1876             :  *                               0 bit-rates computed correctly.
    1877             :  */
    1878           0 : int16_t WebRtcIsac_GetUplinkBw(ISACStruct*  ISAC_main_inst,
    1879             :                                int32_t* bottleneck) {
    1880           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    1881             : 
    1882           0 :   if (instISAC->codingMode == 0) {
    1883             :     /* We are in adaptive mode then get the bottleneck from BWE. */
    1884           0 :     *bottleneck = (int32_t)instISAC->bwestimator_obj.send_bw_avg;
    1885             :   } else {
    1886           0 :     *bottleneck = instISAC->bottleneck;
    1887             :   }
    1888             : 
    1889           0 :   if ((*bottleneck > 32000) && (*bottleneck < 38000)) {
    1890           0 :     *bottleneck = 32000;
    1891           0 :   } else if ((*bottleneck > 45000) && (*bottleneck < 50000)) {
    1892           0 :     *bottleneck = 45000;
    1893           0 :   } else if (*bottleneck > 56000) {
    1894           0 :     *bottleneck = 56000;
    1895             :   }
    1896           0 :   return 0;
    1897             : }
    1898             : 
    1899             : 
    1900             : /******************************************************************************
    1901             :  * WebRtcIsac_SetMaxPayloadSize(...)
    1902             :  *
    1903             :  * This function sets a limit for the maximum payload size of iSAC. The same
    1904             :  * value is used both for 30 and 60 ms packets. If the encoder sampling rate
    1905             :  * is 16 kHz the maximum payload size is between 120 and 400 bytes. If the
    1906             :  * encoder sampling rate is 32 kHz the maximum payload size is between 120
    1907             :  * and 600 bytes.
    1908             :  *
    1909             :  * ---------------
    1910             :  * IMPORTANT NOTES
    1911             :  * ---------------
    1912             :  * The size of a packet is limited to the minimum of 'max-payload-size' and
    1913             :  * 'max-rate.' For instance, let's assume the max-payload-size is set to
    1914             :  * 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps
    1915             :  * translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms
    1916             :  * frame-size. Then a packet with a frame-size of 30 ms is limited to 150,
    1917             :  * i.e. min(170, 150), and a packet with 60 ms frame-size is limited to
    1918             :  * 170 bytes, i.e. min(170, 300).
    1919             :  *
    1920             :  * Input:
    1921             :  *        - ISAC_main_inst    : iSAC instance
    1922             :  *        - maxPayloadBytes   : maximum size of the payload in bytes
    1923             :  *                              valid values are between 100 and 400 bytes
    1924             :  *                              if encoder sampling rate is 16 kHz. For
    1925             :  *                              32 kHz encoder sampling rate valid values
    1926             :  *                              are between 100 and 600 bytes.
    1927             :  *
    1928             :  * Return value               : 0 if successful
    1929             :  *                             -1 if error happens
    1930             :  */
    1931           0 : int16_t WebRtcIsac_SetMaxPayloadSize(ISACStruct* ISAC_main_inst,
    1932             :                                      int16_t maxPayloadBytes) {
    1933           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    1934           0 :   int16_t status = 0;
    1935             : 
    1936             :   /* Check if encoder initiated */
    1937           0 :   if ((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
    1938             :       BIT_MASK_ENC_INIT) {
    1939           0 :     instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
    1940           0 :     return -1;
    1941             :   }
    1942             : 
    1943           0 :   if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) {
    1944             :     /* Sanity check. */
    1945           0 :     if (maxPayloadBytes < 120) {
    1946             :       /* 'maxRate' is out of valid range
    1947             :        * set to the acceptable value and return -1. */
    1948           0 :       maxPayloadBytes = 120;
    1949           0 :       status = -1;
    1950             :     }
    1951             : 
    1952             :     /* sanity check */
    1953           0 :     if (maxPayloadBytes > STREAM_SIZE_MAX) {
    1954             :       /* maxRate is out of valid range,
    1955             :        * set to the acceptable value and return -1. */
    1956           0 :       maxPayloadBytes = STREAM_SIZE_MAX;
    1957           0 :       status = -1;
    1958             :     }
    1959             :   } else {
    1960           0 :     if (maxPayloadBytes < 120) {
    1961             :       /* Max payload-size is out of valid range
    1962             :        * set to the acceptable value and return -1. */
    1963           0 :       maxPayloadBytes = 120;
    1964           0 :       status = -1;
    1965             :     }
    1966           0 :     if (maxPayloadBytes > STREAM_SIZE_MAX_60) {
    1967             :       /* Max payload-size is out of valid range
    1968             :        * set to the acceptable value and return -1. */
    1969           0 :       maxPayloadBytes = STREAM_SIZE_MAX_60;
    1970           0 :       status = -1;
    1971             :     }
    1972             :   }
    1973           0 :   instISAC->maxPayloadSizeBytes = maxPayloadBytes;
    1974           0 :   UpdatePayloadSizeLimit(instISAC);
    1975           0 :   return status;
    1976             : }
    1977             : 
    1978             : 
    1979             : /******************************************************************************
    1980             :  * WebRtcIsac_SetMaxRate(...)
    1981             :  *
    1982             :  * This function sets the maximum rate which the codec may not exceed for
    1983             :  * any signal packet. The maximum rate is defined and payload-size per
    1984             :  * frame-size in bits per second.
    1985             :  *
    1986             :  * The codec has a maximum rate of 53400 bits per second (200 bytes per 30
    1987             :  * ms) if the encoder sampling rate is 16kHz, and 160 kbps (600 bytes/30 ms)
    1988             :  * if the encoder sampling rate is 32 kHz.
    1989             :  *
    1990             :  * It is possible to set a maximum rate between 32000 and 53400 bits/sec
    1991             :  * in wideband mode, and 32000 to 160000 bits/sec in super-wideband mode.
    1992             :  *
    1993             :  * ---------------
    1994             :  * IMPORTANT NOTES
    1995             :  * ---------------
    1996             :  * The size of a packet is limited to the minimum of 'max-payload-size' and
    1997             :  * 'max-rate.' For instance, let's assume the max-payload-size is set to
    1998             :  * 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps
    1999             :  * translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms
    2000             :  * frame-size. Then a packet with a frame-size of 30 ms is limited to 150,
    2001             :  * i.e. min(170, 150), and a packet with 60 ms frame-size is limited to
    2002             :  * 170 bytes, min(170, 300).
    2003             :  *
    2004             :  * Input:
    2005             :  *        - ISAC_main_inst    : iSAC instance
    2006             :  *        - maxRate           : maximum rate in bits per second,
    2007             :  *                              valid values are 32000 to 53400 bits/sec in
    2008             :  *                              wideband mode, and 32000 to 160000 bits/sec in
    2009             :  *                              super-wideband mode.
    2010             :  *
    2011             :  * Return value               : 0 if successful
    2012             :  *                             -1 if error happens
    2013             :  */
    2014           0 : int16_t WebRtcIsac_SetMaxRate(ISACStruct* ISAC_main_inst,
    2015             :                               int32_t maxRate) {
    2016           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    2017             :   int16_t maxRateInBytesPer30Ms;
    2018           0 :   int16_t status = 0;
    2019             : 
    2020             :   /* check if encoder initiated */
    2021           0 :   if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != BIT_MASK_ENC_INIT) {
    2022           0 :     instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
    2023           0 :     return -1;
    2024             :   }
    2025             :   /* Calculate maximum number of bytes per 30 msec packets for the
    2026             :      given maximum rate. Multiply with 30/1000 to get number of
    2027             :      bits per 30 ms, divide by 8 to get number of bytes per 30 ms:
    2028             :      maxRateInBytes = floor((maxRate * 30/1000) / 8); */
    2029           0 :   maxRateInBytesPer30Ms = (int16_t)(maxRate * 3 / 800);
    2030             : 
    2031           0 :   if (instISAC->encoderSamplingRateKHz == kIsacWideband) {
    2032           0 :     if (maxRate < 32000) {
    2033             :       /* 'maxRate' is out of valid range.
    2034             :        * Set to the acceptable value and return -1. */
    2035           0 :       maxRateInBytesPer30Ms = 120;
    2036           0 :       status = -1;
    2037             :     }
    2038             : 
    2039           0 :     if (maxRate > 53400) {
    2040             :       /* 'maxRate' is out of valid range.
    2041             :        * Set to the acceptable value and return -1. */
    2042           0 :       maxRateInBytesPer30Ms = 200;
    2043           0 :       status = -1;
    2044             :     }
    2045             :   } else {
    2046           0 :     if (maxRateInBytesPer30Ms < 120) {
    2047             :       /* 'maxRate' is out of valid range
    2048             :        * Set to the acceptable value and return -1. */
    2049           0 :       maxRateInBytesPer30Ms = 120;
    2050           0 :       status = -1;
    2051             :     }
    2052             : 
    2053           0 :     if (maxRateInBytesPer30Ms > STREAM_SIZE_MAX) {
    2054             :       /* 'maxRate' is out of valid range.
    2055             :        * Set to the acceptable value and return -1. */
    2056           0 :       maxRateInBytesPer30Ms = STREAM_SIZE_MAX;
    2057           0 :       status = -1;
    2058             :     }
    2059             :   }
    2060           0 :   instISAC->maxRateBytesPer30Ms = maxRateInBytesPer30Ms;
    2061           0 :   UpdatePayloadSizeLimit(instISAC);
    2062           0 :   return status;
    2063             : }
    2064             : 
    2065             : 
    2066             : /****************************************************************************
    2067             :  * WebRtcIsac_GetRedPayload(...)
    2068             :  *
    2069             :  * This function populates "encoded" with the redundant payload of the recently
    2070             :  * encodedframe. This function has to be called once that WebRtcIsac_Encode(...)
    2071             :  * returns a positive value. Regardless of the frame-size this function will
    2072             :  * be called only once after encoding is completed. The bit-stream is
    2073             :  * targeted for 16000 bit/sec.
    2074             :  *
    2075             :  * Input:
    2076             :  *        - ISAC_main_inst    : iSAC struct
    2077             :  *
    2078             :  * Output:
    2079             :  *        - encoded           : the encoded data vector
    2080             :  *
    2081             :  *
    2082             :  * Return value               : >0 - Length (in bytes) of coded data
    2083             :  *                            : -1 - Error
    2084             :  */
    2085           0 : int16_t WebRtcIsac_GetRedPayload(ISACStruct* ISAC_main_inst,
    2086             :                                  uint8_t* encoded) {
    2087             :   Bitstr iSACBitStreamInst;
    2088             :   int16_t streamLenLB;
    2089             :   int16_t streamLenUB;
    2090             :   int16_t streamLen;
    2091             :   int16_t totalLenUB;
    2092           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    2093             : #ifndef WEBRTC_ARCH_BIG_ENDIAN
    2094             :   int k;
    2095             : #endif
    2096             : 
    2097           0 :   if ((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
    2098             :       BIT_MASK_ENC_INIT) {
    2099           0 :     instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED;
    2100             :   }
    2101             : 
    2102           0 :   WebRtcIsac_ResetBitstream(&(iSACBitStreamInst));
    2103             : 
    2104           0 :   streamLenLB = WebRtcIsac_EncodeStoredDataLb(
    2105           0 :                   &instISAC->instLB.ISACencLB_obj.SaveEnc_obj,
    2106             :                   &iSACBitStreamInst,
    2107           0 :                   instISAC->instLB.ISACencLB_obj.lastBWIdx,
    2108             :                   RCU_TRANSCODING_SCALE);
    2109           0 :   if (streamLenLB < 0) {
    2110           0 :     return -1;
    2111             :   }
    2112             : 
    2113             :   /* convert from bytes to int16_t. */
    2114           0 :   memcpy(encoded, iSACBitStreamInst.stream, streamLenLB);
    2115           0 :   streamLen = streamLenLB;
    2116           0 :   if (instISAC->bandwidthKHz == isac8kHz) {
    2117           0 :     return streamLenLB;
    2118             :   }
    2119             : 
    2120           0 :   streamLenUB = WebRtcIsac_GetRedPayloadUb(
    2121           0 :                   &instISAC->instUB.ISACencUB_obj.SaveEnc_obj,
    2122             :                   &iSACBitStreamInst, instISAC->bandwidthKHz);
    2123           0 :   if (streamLenUB < 0) {
    2124             :     /* An error has happened but this is not the error due to a
    2125             :      * bit-stream larger than the limit. */
    2126           0 :     return -1;
    2127             :   }
    2128             : 
    2129             :   /* We have one byte to write the total length of the upper-band.
    2130             :    * The length includes the bit-stream length, check-sum and the
    2131             :    * single byte where the length is written to. This is according to
    2132             :    * iSAC wideband and how the "garbage" is dealt. */
    2133           0 :   totalLenUB = streamLenUB + 1 + LEN_CHECK_SUM_WORD8;
    2134           0 :   if (totalLenUB > 255) {
    2135           0 :     streamLenUB = 0;
    2136             :   }
    2137             : 
    2138             :   /* Generate CRC if required. */
    2139           0 :   if ((instISAC->bandwidthKHz != isac8kHz) &&
    2140             :       (streamLenUB > 0)) {
    2141             :     uint32_t crc;
    2142           0 :     streamLen += totalLenUB;
    2143           0 :     encoded[streamLenLB] = (uint8_t)totalLenUB;
    2144           0 :     memcpy(&encoded[streamLenLB + 1], iSACBitStreamInst.stream,
    2145             :            streamLenUB);
    2146             : 
    2147           0 :     WebRtcIsac_GetCrc((int16_t*)(&(encoded[streamLenLB + 1])),
    2148             :                       streamLenUB, &crc);
    2149             : #ifndef WEBRTC_ARCH_BIG_ENDIAN
    2150           0 :     for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) {
    2151           0 :       encoded[streamLen - LEN_CHECK_SUM_WORD8 + k] =
    2152           0 :         (uint8_t)((crc >> (24 - k * 8)) & 0xFF);
    2153             :     }
    2154             : #else
    2155             :     memcpy(&encoded[streamLenLB + streamLenUB + 1], &crc,
    2156             :            LEN_CHECK_SUM_WORD8);
    2157             : #endif
    2158             :   }
    2159           0 :   return streamLen;
    2160             : }
    2161             : 
    2162             : 
    2163             : /****************************************************************************
    2164             :  * WebRtcIsac_version(...)
    2165             :  *
    2166             :  * This function returns the version number.
    2167             :  *
    2168             :  * Output:
    2169             :  *        - version      : Pointer to character string
    2170             :  *
    2171             :  */
    2172           0 : void WebRtcIsac_version(char* version) {
    2173           0 :   strcpy(version, "4.3.0");
    2174           0 : }
    2175             : 
    2176             : 
    2177             : /******************************************************************************
    2178             :  * WebRtcIsac_SetEncSampRate()
    2179             :  * This function sets the sampling rate of the encoder. Initialization of the
    2180             :  * encoder WILL NOT overwrite the sampling rate of the encoder. The default
    2181             :  * value is 16 kHz which is set when the instance is created. The encoding-mode
    2182             :  * and the bottleneck remain unchanged by this call, however, the maximum rate
    2183             :  * and maximum payload-size will be reset to their default values.
    2184             :  *
    2185             :  * Input:
    2186             :  *        - ISAC_main_inst    : iSAC instance
    2187             :  *        - sample_rate_hz    : sampling rate in Hertz, valid values are 16000
    2188             :  *                              and 32000.
    2189             :  *
    2190             :  * Return value               : 0 if successful
    2191             :  *                             -1 if failed.
    2192             :  */
    2193           0 : int16_t WebRtcIsac_SetEncSampRate(ISACStruct* ISAC_main_inst,
    2194             :                                   uint16_t sample_rate_hz) {
    2195           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    2196             :   enum IsacSamplingRate encoder_operational_rate;
    2197             : 
    2198           0 :   if ((sample_rate_hz != 16000) && (sample_rate_hz != 32000)) {
    2199             :     /* Sampling Frequency is not supported. */
    2200           0 :     instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY;
    2201           0 :     return -1;
    2202             :   }
    2203           0 :   if (sample_rate_hz == 16000) {
    2204           0 :     encoder_operational_rate = kIsacWideband;
    2205             :   } else {
    2206           0 :     encoder_operational_rate = kIsacSuperWideband;
    2207             :   }
    2208             : 
    2209           0 :   if ((instISAC->initFlag & BIT_MASK_ENC_INIT) !=
    2210             :       BIT_MASK_ENC_INIT) {
    2211           0 :     if (encoder_operational_rate == kIsacWideband) {
    2212           0 :       instISAC->bandwidthKHz = isac8kHz;
    2213             :     } else {
    2214           0 :       instISAC->bandwidthKHz = isac16kHz;
    2215             :     }
    2216             :   } else {
    2217           0 :     ISACUBStruct* instUB = &(instISAC->instUB);
    2218           0 :     ISACLBStruct* instLB = &(instISAC->instLB);
    2219           0 :     int32_t bottleneck = instISAC->bottleneck;
    2220           0 :     int16_t codingMode = instISAC->codingMode;
    2221           0 :     int16_t frameSizeMs = instLB->ISACencLB_obj.new_framelength /
    2222             :         (FS / 1000);
    2223             : 
    2224           0 :     if ((encoder_operational_rate == kIsacWideband) &&
    2225           0 :         (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) {
    2226             :       /* Changing from super-wideband to wideband.
    2227             :        * we don't need to re-initialize the encoder of the lower-band. */
    2228           0 :       instISAC->bandwidthKHz = isac8kHz;
    2229           0 :       if (codingMode == 1) {
    2230           0 :         ControlLb(instLB,
    2231           0 :                   (bottleneck > 32000) ? 32000 : bottleneck, FRAMESIZE);
    2232             :       }
    2233           0 :       instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60;
    2234           0 :       instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30;
    2235           0 :     } else if ((encoder_operational_rate == kIsacSuperWideband) &&
    2236           0 :                (instISAC->encoderSamplingRateKHz == kIsacWideband)) {
    2237           0 :       double bottleneckLB = 0;
    2238           0 :       double bottleneckUB = 0;
    2239           0 :       if (codingMode == 1) {
    2240           0 :         WebRtcIsac_RateAllocation(bottleneck, &bottleneckLB, &bottleneckUB,
    2241             :                                   &(instISAC->bandwidthKHz));
    2242             :       }
    2243             : 
    2244           0 :       instISAC->bandwidthKHz = isac16kHz;
    2245           0 :       instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX;
    2246           0 :       instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX;
    2247             : 
    2248           0 :       EncoderInitLb(instLB, codingMode, encoder_operational_rate);
    2249           0 :       EncoderInitUb(instUB, instISAC->bandwidthKHz);
    2250             : 
    2251           0 :       memset(instISAC->analysisFBState1, 0,
    2252             :              FB_STATE_SIZE_WORD32 * sizeof(int32_t));
    2253           0 :       memset(instISAC->analysisFBState2, 0,
    2254             :              FB_STATE_SIZE_WORD32 * sizeof(int32_t));
    2255             : 
    2256           0 :       if (codingMode == 1) {
    2257           0 :         instISAC->bottleneck = bottleneck;
    2258           0 :         ControlLb(instLB, bottleneckLB,
    2259           0 :                   (instISAC->bandwidthKHz == isac8kHz) ? frameSizeMs:FRAMESIZE);
    2260           0 :         if (instISAC->bandwidthKHz > isac8kHz) {
    2261           0 :           ControlUb(instUB, bottleneckUB);
    2262             :         }
    2263             :       } else {
    2264           0 :         instLB->ISACencLB_obj.enforceFrameSize = 0;
    2265           0 :         instLB->ISACencLB_obj.new_framelength = FRAMESAMPLES;
    2266             :       }
    2267             :     }
    2268             :   }
    2269           0 :   instISAC->encoderSamplingRateKHz = encoder_operational_rate;
    2270           0 :   instISAC->in_sample_rate_hz = sample_rate_hz;
    2271           0 :   return 0;
    2272             : }
    2273             : 
    2274             : 
    2275             : /******************************************************************************
    2276             :  * WebRtcIsac_SetDecSampRate()
    2277             :  * This function sets the sampling rate of the decoder. Initialization of the
    2278             :  * decoder WILL NOT overwrite the sampling rate of the encoder. The default
    2279             :  * value is 16 kHz which is set when the instance is created.
    2280             :  *
    2281             :  * Input:
    2282             :  *        - ISAC_main_inst    : iSAC instance
    2283             :  *        - sample_rate_hz    : sampling rate in Hertz, valid values are 16000
    2284             :  *                              and 32000.
    2285             :  *
    2286             :  * Return value               : 0 if successful
    2287             :  *                             -1 if failed.
    2288             :  */
    2289           0 : int16_t WebRtcIsac_SetDecSampRate(ISACStruct* ISAC_main_inst,
    2290             :                                   uint16_t sample_rate_hz) {
    2291           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    2292             :   enum IsacSamplingRate decoder_operational_rate;
    2293             : 
    2294           0 :   if (sample_rate_hz == 16000) {
    2295           0 :     decoder_operational_rate = kIsacWideband;
    2296           0 :   } else if (sample_rate_hz == 32000) {
    2297           0 :     decoder_operational_rate = kIsacSuperWideband;
    2298             :   } else {
    2299             :     /* Sampling Frequency is not supported. */
    2300           0 :     instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY;
    2301           0 :     return -1;
    2302             :   }
    2303             : 
    2304           0 :   if ((instISAC->decoderSamplingRateKHz == kIsacWideband) &&
    2305             :         (decoder_operational_rate == kIsacSuperWideband)) {
    2306             :       /* Switching from wideband to super-wideband at the decoder
    2307             :        * we need to reset the filter-bank and initialize upper-band decoder. */
    2308           0 :       memset(instISAC->synthesisFBState1, 0,
    2309             :              FB_STATE_SIZE_WORD32 * sizeof(int32_t));
    2310           0 :       memset(instISAC->synthesisFBState2, 0,
    2311             :              FB_STATE_SIZE_WORD32 * sizeof(int32_t));
    2312             : 
    2313           0 :       DecoderInitUb(&instISAC->instUB);
    2314             :   }
    2315           0 :   instISAC->decoderSamplingRateKHz = decoder_operational_rate;
    2316           0 :   return 0;
    2317             : }
    2318             : 
    2319             : 
    2320             : /******************************************************************************
    2321             :  * WebRtcIsac_EncSampRate()
    2322             :  *
    2323             :  * Input:
    2324             :  *        - ISAC_main_inst    : iSAC instance
    2325             :  *
    2326             :  * Return value               : sampling rate in Hertz. The input to encoder
    2327             :  *                              is expected to be sampled in this rate.
    2328             :  *
    2329             :  */
    2330           0 : uint16_t WebRtcIsac_EncSampRate(ISACStruct* ISAC_main_inst) {
    2331           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    2332           0 :   return instISAC->in_sample_rate_hz;
    2333             : }
    2334             : 
    2335             : 
    2336             : /******************************************************************************
    2337             :  * WebRtcIsac_DecSampRate()
    2338             :  * Return the sampling rate of the decoded audio.
    2339             :  *
    2340             :  * Input:
    2341             :  *        - ISAC_main_inst    : iSAC instance
    2342             :  *
    2343             :  * Return value               : sampling rate in Hertz. Decoder output is
    2344             :  *                              sampled at this rate.
    2345             :  *
    2346             :  */
    2347           0 : uint16_t WebRtcIsac_DecSampRate(ISACStruct* ISAC_main_inst) {
    2348           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst;
    2349           0 :   return instISAC->decoderSamplingRateKHz == kIsacWideband ? 16000 : 32000;
    2350             : }
    2351             : 
    2352           0 : void WebRtcIsac_GetBandwidthInfo(ISACStruct* inst,
    2353             :                                  IsacBandwidthInfo* bwinfo) {
    2354           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)inst;
    2355           0 :   RTC_DCHECK_NE(0, instISAC->initFlag & BIT_MASK_DEC_INIT);
    2356           0 :   WebRtcIsacBw_GetBandwidthInfo(&instISAC->bwestimator_obj,
    2357             :                                 instISAC->decoderSamplingRateKHz, bwinfo);
    2358           0 : }
    2359             : 
    2360           0 : void WebRtcIsac_SetBandwidthInfo(ISACStruct* inst,
    2361             :                                  const IsacBandwidthInfo* bwinfo) {
    2362           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)inst;
    2363           0 :   RTC_DCHECK_NE(0, instISAC->initFlag & BIT_MASK_ENC_INIT);
    2364           0 :   WebRtcIsacBw_SetBandwidthInfo(&instISAC->bwestimator_obj, bwinfo);
    2365           0 : }
    2366             : 
    2367           0 : void WebRtcIsac_SetEncSampRateInDecoder(ISACStruct* inst,
    2368             :                                         int sample_rate_hz) {
    2369           0 :   ISACMainStruct* instISAC = (ISACMainStruct*)inst;
    2370           0 :   RTC_DCHECK_NE(0, instISAC->initFlag & BIT_MASK_DEC_INIT);
    2371           0 :   RTC_DCHECK(!(instISAC->initFlag & BIT_MASK_ENC_INIT));
    2372           0 :   RTC_DCHECK(sample_rate_hz == 16000 || sample_rate_hz == 32000);
    2373           0 :   instISAC->encoderSamplingRateKHz = sample_rate_hz / 1000;
    2374           0 : }

Generated by: LCOV version 1.13