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