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