isacfix.c revision 3258db26ed7cedd20e1e21aca70d8304c7cef218
1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
2715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Use of this source code is governed by a BSD-style license
5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  that can be found in the LICENSE file in the root of the source
6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  tree. An additional intellectual property rights grant can be found
7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  in the file PATENTS.  All contributing project authors may
8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  be found in the AUTHORS file in the root of the source tree.
9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
11470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * isacfix.c
13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
14470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This C file contains the functions for the ISAC API
15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
17470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
18262e676a08fc29ee6c414f5858d68697be983515andresp@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h"
19715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org
207ee24a79065a655dcc62a27fd22e0cc77fee6d68kwiberg@webrtc.org#include <assert.h>
21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include <stdlib.h>
22470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
23262e676a08fc29ee6c414f5858d68697be983515andresp@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.h"
24262e676a08fc29ee6c414f5858d68697be983515andresp@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/fix/source/codec.h"
25262e676a08fc29ee6c414f5858d68697be983515andresp@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/fix/source/entropy_coding.h"
26262e676a08fc29ee6c414f5858d68697be983515andresp@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h"
27262e676a08fc29ee6c414f5858d68697be983515andresp@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
28262e676a08fc29ee6c414f5858d68697be983515andresp@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/fix/source/structs.h"
29262e676a08fc29ee6c414f5858d68697be983515andresp@webrtc.org#include "webrtc/system_wrappers/interface/cpu_features_wrapper.h"
30470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
31c4373bc7372a92fe988b6ea8db92eacba538d40bkma@webrtc.org// Declare function pointers.
32c4373bc7372a92fe988b6ea8db92eacba538d40bkma@webrtc.orgFilterMaLoopFix WebRtcIsacfix_FilterMaLoopFix;
33c4373bc7372a92fe988b6ea8db92eacba538d40bkma@webrtc.orgSpec2Time WebRtcIsacfix_Spec2Time;
34c4373bc7372a92fe988b6ea8db92eacba538d40bkma@webrtc.orgTime2Spec WebRtcIsacfix_Time2Spec;
3523da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgMatrixProduct1 WebRtcIsacfix_MatrixProduct1;
3623da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.orgMatrixProduct2 WebRtcIsacfix_MatrixProduct2;
37470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
38532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org/* This method assumes that |stream_size_bytes| is in valid range,
39532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org * i.e. >= 0 && <=  STREAM_MAXW16_60MS
40532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org */
41532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.orgstatic void InitializeDecoderBitstream(int stream_size_bytes,
42532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org                                       Bitstr_dec* bitstream) {
43532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  bitstream->W_upper = 0xFFFFFFFF;
44532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  bitstream->streamval = 0;
45532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  bitstream->stream_index = 0;
46532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  bitstream->full = 1;
47532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  bitstream->stream_size = (stream_size_bytes + 1) >> 1;
48532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  memset(bitstream->stream, 0, sizeof(bitstream->stream));
49532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org}
50532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org
51470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/**************************************************************************
52470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_AssignSize(...)
53470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
54470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Functions used when malloc is not allowed
55470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Returns number of bytes needed to allocate for iSAC struct.
56470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
57470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
58470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
590946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_AssignSize(int *sizeinbytes) {
600946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  *sizeinbytes=sizeof(ISACFIX_SubStruct)*2/sizeof(int16_t);
61470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return(0);
62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
63470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
64470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/***************************************************************************
65470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_Assign(...)
66470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
67470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Functions used when malloc is not allowed
68470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Place struct at given address
69470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
70470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * If successful, Return 0, else Return -1
71470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
72470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_Assign(ISACFIX_MainStruct **inst, void *ISACFIX_inst_Addr) {
74470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (ISACFIX_inst_Addr!=NULL) {
752224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg    ISACFIX_SubStruct* self = ISACFIX_inst_Addr;
762224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg    *inst = (ISACFIX_MainStruct*)self;
772224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg    self->errorcode = 0;
782224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg    self->initflag = 0;
792224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg    self->ISACenc_obj.SaveEnc_ptr = NULL;
802224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg    WebRtcIsacfix_InitBandwidthEstimator(&self->bwestimator_obj);
81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return(0);
82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else {
83470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return(-1);
84470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
86470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef ISACFIX_NO_DYNAMIC_MEM
89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
90470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_Create(...)
92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function creates a ISAC instance, which will contain the state
94470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * information for one coding/decoding channel.
95470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
96470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
97470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - *ISAC_main_inst   : a pointer to the coder instance.
98470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             :  0 - Ok
100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1030946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_Create(ISACFIX_MainStruct **ISAC_main_inst)
104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *tempo;
106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  tempo = malloc(1 * sizeof(ISACFIX_SubStruct));
107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  *ISAC_main_inst = (ISACFIX_MainStruct *)tempo;
108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (*ISAC_main_inst!=NULL) {
109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    (*(ISACFIX_SubStruct**)ISAC_main_inst)->errorcode = 0;
110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    (*(ISACFIX_SubStruct**)ISAC_main_inst)->initflag = 0;
111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    (*(ISACFIX_SubStruct**)ISAC_main_inst)->ISACenc_obj.SaveEnc_ptr = NULL;
112ac4d70de04acabec539753eef6e1252cb2dd1fbckma@webrtc.org    WebRtcSpl_Init();
1132224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg    WebRtcIsacfix_InitBandwidthEstimator(&tempo->bwestimator_obj);
114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return(0);
115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else {
116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return(-1);
117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_CreateInternal(...)
123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function creates the memory that is used to store data in the encoder
125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - *ISAC_main_inst   : a pointer to the coder instance.
128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             :  0 - Ok
130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1330946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_CreateInternal(ISACFIX_MainStruct *ISAC_main_inst)
134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Allocate memory for storing encoder data */
141eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.org  ISAC_inst->ISACenc_obj.SaveEnc_ptr = malloc(1 * sizeof(IsacSaveEncoderData));
142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (ISAC_inst->ISACenc_obj.SaveEnc_ptr!=NULL) {
144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return(0);
145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else {
146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return(-1);
147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif
152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_Free(...)
157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function frees the ISAC instance created at the beginning.
159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : a ISAC instance.
162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             :  0 - Ok
164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1670946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_Free(ISACFIX_MainStruct *ISAC_main_inst)
168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  free(ISAC_main_inst);
170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return(0);
171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_FreeInternal(...)
175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function frees the internal memory for storing encoder data.
177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *       - ISAC_main_inst    : a ISAC instance.
180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value              :  0 - Ok
182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                             -1 - Error
183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1850946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct *ISAC_main_inst)
186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Release memory */
193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  free(ISAC_inst->ISACenc_obj.SaveEnc_ptr);
194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return(0);
196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
199919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org * WebRtcIsacfix_InitNeon(...)
200715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org *
201715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org * This function initializes function pointers for ARM Neon platform.
202715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org */
203715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org
204cb7f8ce2df7564546936d3041a96ccc86a90f988Andrew MacDonald#if defined(WEBRTC_DETECT_NEON) || defined(WEBRTC_HAS_NEON)
205715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.orgstatic void WebRtcIsacfix_InitNeon(void) {
206715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org  WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrNeon;
207715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org  WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopNeon;
208fa5b6bf4f43032ed6db4544c84b42849bdfa3223kma@webrtc.org  WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeNeon;
209478291157282e87c261cc1f7351dc53c60184365kma@webrtc.org  WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecNeon;
210e8a197bd071ed08a90ca455370d4da909025861aZhongwei Yao// Disable AllpassFilter2FixDec16Neon function due to a clang bug.
211e8a197bd071ed08a90ca455370d4da909025861aZhongwei Yao// Refer more details at:
212e8a197bd071ed08a90ca455370d4da909025861aZhongwei Yao// https://code.google.com/p/webrtc/issues/detail?id=4567
213cb7f8ce2df7564546936d3041a96ccc86a90f988Andrew MacDonald#if !defined(__clang__) || !defined(WEBRTC_ARCH_ARM64)
214fa65c851feeaebdfd514cacd453fd585b069b06dkma@webrtc.org  WebRtcIsacfix_AllpassFilter2FixDec16 =
215fa65c851feeaebdfd514cacd453fd585b069b06dkma@webrtc.org      WebRtcIsacfix_AllpassFilter2FixDec16Neon;
216e8a197bd071ed08a90ca455370d4da909025861aZhongwei Yao#endif
21723da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org  WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1Neon;
21823da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org  WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2Neon;
219715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org}
220715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org#endif
221715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org
222715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org/****************************************************************************
223919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org * WebRtcIsacfix_InitMIPS(...)
224919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org *
225919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org * This function initializes function pointers for MIPS platform.
226919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org */
227919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
228919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if defined(MIPS32_LE)
229919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.orgstatic void WebRtcIsacfix_InitMIPS(void) {
230919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrMIPS;
231919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopMIPS;
232ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org  WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeMIPS;
233ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org  WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecMIPS;
234f86b2625889b065ccf67e580a8456f0b5e42b261andrew@webrtc.org  WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1MIPS;
235f86b2625889b065ccf67e580a8456f0b5e42b261andrew@webrtc.org  WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2MIPS;
236919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if defined(MIPS_DSP_R1_LE)
237919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  WebRtcIsacfix_AllpassFilter2FixDec16 =
238919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      WebRtcIsacfix_AllpassFilter2FixDec16MIPS;
239ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org  WebRtcIsacfix_HighpassFilterFixDec32 =
240ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org      WebRtcIsacfix_HighpassFilterFixDec32MIPS;
241ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org#endif
242ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org#if defined(MIPS_DSP_R2_LE)
243ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org  WebRtcIsacfix_CalculateResidualEnergy =
244ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org      WebRtcIsacfix_CalculateResidualEnergyMIPS;
245919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
246919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org}
247919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
248919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
249919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org/****************************************************************************
250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_EncoderInit(...)
251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function initializes a ISAC instance prior to the encoder calls.
253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - CodingMode        : 0 -> Bit rate and frame length are automatically
257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                                 adjusted to available bandwidth on
258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                                 transmission channel.
259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            1 -> User sets a frame length and a target bit
260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                                 rate which is taken as the maximum short-term
261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                                 average bit rate.
262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             :  0 - Ok
264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2670946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst,
2680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                  int16_t  CodingMode)
269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  int k;
2710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t statusInit;
272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  statusInit = 0;
275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to rela structure */
276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* flag encoder init */
279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->initflag |= 2;
280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (CodingMode == 0)
282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Adaptive mode */
283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->ISACenc_obj.new_framelength  = INITIAL_FRAMESAMPLES;
284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else if (CodingMode == 1)
285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Instantaneous mode */
286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->ISACenc_obj.new_framelength = 480;    /* default for I-mode */
287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else {
288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DISALLOWED_CODING_MODE;
289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    statusInit = -1;
290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->CodingMode = CodingMode;
293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitMaskingEnc(&ISAC_inst->ISACenc_obj.maskfiltstr_obj);
295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACenc_obj.prefiltbankstr_obj);
296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACenc_obj.pitchfiltstr_obj);
297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPitchAnalysis(&ISAC_inst->ISACenc_obj.pitchanalysisstr_obj);
298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitRateModel(&ISAC_inst->ISACenc_obj.rate_data_obj);
300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.buffer_index   = 0;
303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.frame_nb    = 0;
304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.BottleNeck      = 32000; /* default for I-mode */
305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.MaxDelay    = 10;    /* default for I-mode */
306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.current_framesamples = 0;
307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.s2nr     = 0;
308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.MaxBits    = 0;
309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.bitstr_seed   = 4447;
310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.payloadLimitBytes30  = STREAM_MAXW16_30MS << 1;
311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.payloadLimitBytes60  = STREAM_MAXW16_60MS << 1;
312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.maxPayloadBytes      = STREAM_MAXW16_60MS << 1;
313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.maxRateInBytes       = STREAM_MAXW16_30MS << 1;
314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.enforceFrameSize     = 0;
315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Init the bistream data area to zero */
317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (k=0; k<STREAM_MAXW16_60MS; k++){
318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->ISACenc_obj.bitstr_obj.stream[k] = 0;
319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
3217796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACenc_obj.interpolatorstr_obj);
323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif
324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
325f0a964dc0a287469c68ca4fd195f95aaf24be45fkma@webrtc.org  // Initiaze function pointers.
326f0a964dc0a287469c68ca4fd195f95aaf24be45fkma@webrtc.org  WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrC;
327f0a964dc0a287469c68ca4fd195f95aaf24be45fkma@webrtc.org  WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopC;
328a15ea4965ef07f6aa074339f206383028e3b8898kma@webrtc.org  WebRtcIsacfix_CalculateResidualEnergy =
329a15ea4965ef07f6aa074339f206383028e3b8898kma@webrtc.org      WebRtcIsacfix_CalculateResidualEnergyC;
330478291157282e87c261cc1f7351dc53c60184365kma@webrtc.org  WebRtcIsacfix_AllpassFilter2FixDec16 = WebRtcIsacfix_AllpassFilter2FixDec16C;
331ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org  WebRtcIsacfix_HighpassFilterFixDec32 = WebRtcIsacfix_HighpassFilterFixDec32C;
332478291157282e87c261cc1f7351dc53c60184365kma@webrtc.org  WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecC;
333478291157282e87c261cc1f7351dc53c60184365kma@webrtc.org  WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeC;
33423da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org  WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1C;
335ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org  WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2C;
336f0a964dc0a287469c68ca4fd195f95aaf24be45fkma@webrtc.org
337cb7f8ce2df7564546936d3041a96ccc86a90f988Andrew MacDonald#ifdef WEBRTC_DETECT_NEON
338715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org  if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) {
339715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org    WebRtcIsacfix_InitNeon();
340715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org  }
341cb7f8ce2df7564546936d3041a96ccc86a90f988Andrew MacDonald#elif defined(WEBRTC_HAS_NEON)
342715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org  WebRtcIsacfix_InitNeon();
343f0a964dc0a287469c68ca4fd195f95aaf24be45fkma@webrtc.org#endif
344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
345919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if defined(MIPS32_LE)
346919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  WebRtcIsacfix_InitMIPS();
347919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
348919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return statusInit;
350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
3520552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org/* Read the given number of bytes of big-endian 16-bit integers from |src| and
3530552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   write them to |dest| in host endian. If |nbytes| is odd, the number of
3540552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   output elements is rounded up, and the least significant byte of the last
3550552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   element is set to 0. */
3560552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.orgstatic void read_be16(const uint8_t* src, size_t nbytes, uint16_t* dest) {
3570552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  size_t i;
3580552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  for (i = 0; i < nbytes / 2; ++i)
3590552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org    dest[i] = src[2 * i] << 8 | src[2 * i + 1];
3600552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  if (nbytes % 2 == 1)
3610552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org    dest[nbytes / 2] = src[nbytes - 1] << 8;
3620552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org}
3630552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org
3640552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org/* Read the given number of bytes of host-endian 16-bit integers from |src| and
3650552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   write them to |dest| in big endian. If |nbytes| is odd, the number of source
3660552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   elements is rounded up (but only the most significant byte of the last
3670552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   element is used), and the number of output bytes written will be
3680552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   nbytes + 1. */
3690552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.orgstatic void write_be16(const uint16_t* src, size_t nbytes, uint8_t* dest) {
3700552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  size_t i;
3710552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  for (i = 0; i < nbytes / 2; ++i) {
3720552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org    dest[2 * i] = src[i] >> 8;
3730552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org    dest[2 * i + 1] = src[i];
3740552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  }
3750552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  if (nbytes % 2 == 1) {
3760552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org    dest[nbytes - 1] = src[nbytes / 2] >> 8;
3770552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org    dest[nbytes] = 0;
3780552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  }
3790552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org}
3800552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org
381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_Encode(...)
383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function encodes 10ms frame(s) and inserts it into a package.
385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input speech length has to be 160 samples (10ms). The encoder buffers those
386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 10ms frames until it reaches the chosen Framesize (480 or 960 samples
387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - speechIn          : input speech vector.
392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : the encoded data vector
395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value:
397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          : >0 - Length (in bytes) of coded data
398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          :  0 - The buffer didn't reach the chosen framesize
399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            so it keeps buffering speech samples.
400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          : -1 - Error
401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
403aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kastingint WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst,
404aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                         const int16_t    *speechIn,
405aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                         uint8_t* encoded)
406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
408aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting  int stream_len;
409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to rela structure */
411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if encoder initiated */
415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 2) != 2) {
416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
4200946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  stream_len = WebRtcIsacfix_EncodeImpl((int16_t*)speechIn,
4210946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        &ISAC_inst->ISACenc_obj,
4220946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        &ISAC_inst->bwestimator_obj,
4230946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        ISAC_inst->CodingMode);
424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (stream_len<0) {
425aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting    ISAC_inst->errorcode = -(int16_t)stream_len;
426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
429b7e5054414ff524f9db81dab7917729b8c4c8bcbPeter Kasting  write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream, (size_t)stream_len,
430b7e5054414ff524f9db81dab7917729b8c4c8bcbPeter Kasting             encoded);
431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return stream_len;
432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_EncodeNb(...)
440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function encodes 10ms narrow band (8 kHz sampling) frame(s) and inserts
442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * it into a package. Input speech length has to be 80 samples (10ms). The encoder
443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * interpolates into wide-band (16 kHz sampling) buffers those
444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 10ms frames until it reaches the chosen Framesize (480 or 960 wide-band samples
445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
4477796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
4487796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com *
449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - speechIn          : input speech vector.
452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : the encoded data vector
455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value:
457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          : >0 - Length (in bytes) of coded data
458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          :  0 - The buffer didn't reach the chosen framesize
459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            so it keeps buffering speech samples.
460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          : -1 - Error
461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
4627796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
4630946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_EncodeNb(ISACFIX_MainStruct *ISAC_main_inst,
4640946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                               const int16_t    *speechIn,
4650946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                               int16_t          *encoded)
466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
4680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t stream_len;
4690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t speechInWB[FRAMESAMPLES_10ms];
4700946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t Vector_Word16_1[FRAMESAMPLES_10ms/2];
4710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t Vector_Word16_2[FRAMESAMPLES_10ms/2];
472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  int k;
474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to rela structure */
477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if encoder initiated */
481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 2) != 2) {
482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Oversample to WB */
488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Form polyphase signals, and compensate for DC offset */
490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (k=0;k<FRAMESAMPLES_10ms/2;k++) {
491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    Vector_Word16_1[k] = speechIn[k] + 1;
492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    Vector_Word16_2[k] = speechIn[k];
493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_FilterAndCombine2(Vector_Word16_1, Vector_Word16_2, speechInWB, &ISAC_inst->ISACenc_obj.interpolatorstr_obj, FRAMESAMPLES_10ms);
495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Encode WB signal */
4980946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  stream_len = WebRtcIsacfix_EncodeImpl((int16_t*)speechInWB,
4990946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        &ISAC_inst->ISACenc_obj,
5000946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        &ISAC_inst->bwestimator_obj,
5010946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        ISAC_inst->CodingMode);
502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (stream_len<0) {
503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = - stream_len;
504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
5070552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream,
5080552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org             stream_len,
5090552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org             (uint8_t*)encoded);
510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return stream_len;
511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
5127796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#endif  /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_GetNewBitStream(...)
517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function returns encoded data, with the recieved bwe-index in the
519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * stream. It should always return a complete packet, i.e. only called once
520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * even for 60 msec frames
521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - bweIndex          : index of bandwidth estimate to put in new bitstream
525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : the encoded data vector
528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value:
530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          : >0 - Length (in bytes) of coded data
531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          : -1 - Error
532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
5340946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct *ISAC_main_inst,
5350946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                      int16_t      bweIndex,
5360946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                      float              scale,
5371172988c794d15706b4c951dcbaa57b11221d225kwiberg@webrtc.org                                      uint8_t* encoded)
538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
5400946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t stream_len;
541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to rela structure */
543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if encoder initiated */
547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 2) != 2) {
548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  stream_len = WebRtcIsacfix_EncodeStoredData(&ISAC_inst->ISACenc_obj,
553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                              bweIndex,
554ebb2744337bf26c8e02197da467b14a95df6c718turajs@google.com                                              scale);
555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (stream_len<0) {
556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = - stream_len;
557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
5600552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream, stream_len, encoded);
561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return stream_len;
562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_DecoderInit(...)
568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function initializes a ISAC instance prior to the decoder calls.
570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value
575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          :  0 - Ok
576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
5790946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct *ISAC_main_inst)
580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* flag decoder init */
587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->initflag |= 1;
588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitMaskingDec(&ISAC_inst->ISACdec_obj.maskfiltstr_obj);
590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACdec_obj.postfiltbankstr_obj);
591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACdec_obj.pitchfiltstr_obj);
592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* TS */
594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPlc( &ISAC_inst->ISACdec_obj.plcstr_obj );
595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
5977796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACdec_obj.decimatorstr_obj);
599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif
600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_UpdateBwEstimate1(...)
607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function updates the estimate of the bandwidth.
609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : encoded ISAC frame(s).
613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - packet_size       : size of the packet.
614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rtp_seq_number    : the RTP number of the packet.
615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - arr_ts            : the arrival time of the packet (from NetEq)
616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            in samples.
617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             :  0 - Ok
619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
6220946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst,
6233f7f899a15c2685a8e45484f7b2c540771d28d90kwiberg@webrtc.org                                        const uint8_t* encoded,
624728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                        int32_t packet_size,
625728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                        uint16_t rtp_seq_number,
626728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                        uint32_t arr_ts)
627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  Bitstr_dec streamdata;
6300946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t err;
631532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  const int kRequiredEncodedLenBytes = 10;
632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Sanity check of packet length */
637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (packet_size <= 0) {
638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if the packet length is null or less */
639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else if (packet_size > (STREAM_MAXW16<<1)) {
642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if length of stream is too long */
643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if decoder initiated */
648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 1) != 1) {
649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
653532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  InitializeDecoderBitstream(packet_size, &streamdata);
654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
6550552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        &streamdata,
659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        packet_size,
660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        rtp_seq_number,
661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        0,
662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        arr_ts);
663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err < 0)
666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if something went wrong */
668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = -err;
669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_UpdateBwEstimate(...)
678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function updates the estimate of the bandwidth.
680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : encoded ISAC frame(s).
684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - packet_size       : size of the packet.
685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rtp_seq_number    : the RTP number of the packet.
686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - send_ts           : Send Time Stamp from RTP header
687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - arr_ts            : the arrival time of the packet (from NetEq)
688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            in samples.
689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             :  0 - Ok
691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
6940946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
6953f7f899a15c2685a8e45484f7b2c540771d28d90kwiberg@webrtc.org                                       const uint8_t* encoded,
696728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                       int32_t packet_size,
697728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                       uint16_t rtp_seq_number,
698728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                       uint32_t send_ts,
699728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                       uint32_t arr_ts)
700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  Bitstr_dec streamdata;
7030946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t err;
704532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  const int kRequiredEncodedLenBytes = 10;
705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Sanity check of packet length */
710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (packet_size <= 0) {
711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if the packet length is null  or less */
712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
714532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  } else if (packet_size < kRequiredEncodedLenBytes) {
715532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    ISAC_inst->errorcode = ISAC_PACKET_TOO_SHORT;
716532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    return -1;
717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else if (packet_size > (STREAM_MAXW16<<1)) {
718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if length of stream is too long */
719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if decoder initiated */
724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 1) != 1) {
725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
729532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  InitializeDecoderBitstream(packet_size, &streamdata);
730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
7310552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        &streamdata,
735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        packet_size,
736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        rtp_seq_number,
737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        send_ts,
738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        arr_ts);
739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err < 0)
741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if something went wrong */
743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = -err;
744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_Decode(...)
753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function decodes a ISAC frame. Output speech length
755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * will be a multiple of 480 samples: 480 or 960 samples,
756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * depending on the framesize (30 or 60 ms).
757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : encoded ISAC frame(s)
761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - len               : bytes in encoded vector
762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - decoded           : The decoded vector
765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : >0 - number of samples in decoded vector
767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
771aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kastingint WebRtcIsacfix_Decode(ISACFIX_MainStruct* ISAC_main_inst,
772aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                         const uint8_t* encoded,
773aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                         int16_t len,
774aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                         int16_t* decoded,
775aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                         int16_t* speechType)
776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* number of samples (480 or 960), output from decoder */
779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* that were actually used in the encoder/decoder (determined on the fly) */
7800946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t     number_of_samples;
781aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting  int declen = 0;
782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if decoder initiated */
787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 1) != 1) {
788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Sanity check of packet length */
793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (len <= 0) {
794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if the packet length is null  or less */
795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else if (len > (STREAM_MAXW16<<1)) {
798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if length of stream is too long */
799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
803532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj);
804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
8050552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  read_be16(encoded, len, ISAC_inst->ISACdec_obj.bitstr_obj.stream);
806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* added for NetEq purposes (VAD/DTX related) */
808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  *speechType=1;
809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  declen = WebRtcIsacfix_DecodeImpl(decoded,&ISAC_inst->ISACdec_obj, &number_of_samples);
811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (declen < 0) {
813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Some error inside the decoder */
814aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting    ISAC_inst->errorcode = -(int16_t)declen;
8150946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    memset(decoded, 0, sizeof(int16_t) * MAX_FRAMESAMPLES);
816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* error check */
820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (declen & 0x0001) {
822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) & 0x00FF) ) {
823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
8240946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      memset(decoded, 0, sizeof(int16_t) * number_of_samples);
825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return -1;
826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else {
828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) >> 8) ) {
829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
8300946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      memset(decoded, 0, sizeof(int16_t) * number_of_samples);
831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return -1;
832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return number_of_samples;
836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_DecodeNb(...)
844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function decodes a ISAC frame in narrow-band (8 kHz sampling).
846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output speech length will be a multiple of 240 samples: 240 or 480 samples,
847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * depending on the framesize (30 or 60 ms).
848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
8497796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
8507796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com *
851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : encoded ISAC frame(s)
854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - len               : bytes in encoded vector
855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - decoded           : The decoded vector
858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : >0 - number of samples in decoded vector
860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
8637796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
864aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kastingint WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst,
865aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                           const uint16_t   *encoded,
866aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                           int16_t          len,
867aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                           int16_t          *decoded,
868aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                           int16_t    *speechType)
869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* twice the number of samples (480 or 960), output from decoder */
872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* that were actually used in the encoder/decoder (determined on the fly) */
8730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t     number_of_samples;
874aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting  int declen = 0;
8750946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t dummy[FRAMESAMPLES/2];
876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if decoder initiated */
882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 1) != 1) {
883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
887532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  if (len <= 0) {
888532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    /* return error code if the packet length is null  or less */
889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
891532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  } else if (len > (STREAM_MAXW16<<1)) {
892532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    /* return error code if length of stream is too long */
893532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
894532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    return -1;
895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
897532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj);
898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
8990552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  read_be16(encoded, len, ISAC_inst->ISACdec_obj.bitstr_obj.stream);
900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* added for NetEq purposes (VAD/DTX related) */
902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  *speechType=1;
903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  declen = WebRtcIsacfix_DecodeImpl(decoded,&ISAC_inst->ISACdec_obj, &number_of_samples);
905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (declen < 0) {
907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Some error inside the decoder */
908aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting    ISAC_inst->errorcode = -(int16_t)declen;
9090946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    memset(decoded, 0, sizeof(int16_t) * FRAMESAMPLES);
910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* error check */
914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (declen & 0x0001) {
916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) & 0x00FF) ) {
917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
9180946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      memset(decoded, 0, sizeof(int16_t) * number_of_samples);
919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return -1;
920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else {
922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) >> 8) ) {
923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
9240946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      memset(decoded, 0, sizeof(int16_t) * number_of_samples);
925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return -1;
926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_SplitAndFilter2(decoded, decoded, dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (number_of_samples>FRAMESAMPLES) {
932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WebRtcIsacfix_SplitAndFilter2(decoded + FRAMESAMPLES, decoded + FRAMESAMPLES/2,
933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                  dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return number_of_samples/2;
937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
9387796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_DecodePlcNb(...)
943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function conducts PLC for ISAC frame(s) in narrow-band (8kHz sampling).
945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output speech length  will be "240*noOfLostFrames" samples
946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that is equevalent of "30*noOfLostFrames" millisecond.
947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
9487796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
9497796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com *
950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - noOfLostFrames    : Number of PLC frames (240 sample=30ms) to produce
953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - decoded           : The decoded vector
956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : >0 - number of samples in decoded PLC vector
958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
9617796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
9620946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_DecodePlcNb(ISACFIX_MainStruct *ISAC_main_inst,
9630946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                  int16_t          *decoded,
9640946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                  int16_t noOfLostFrames )
965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
9660946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t no_of_samples, declen, k, ok;
9670946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t outframeNB[FRAMESAMPLES];
9680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t outframeWB[FRAMESAMPLES];
9690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t dummy[FRAMESAMPLES/2];
970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */
977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (noOfLostFrames > 2){
978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    noOfLostFrames = 2;
979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  k = 0;
982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  declen = 0;
983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  while( noOfLostFrames > 0 )
984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
985728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting    WebRtcIsacfix_DecodePlcImpl(outframeWB, &ISAC_inst->ISACdec_obj,
986728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                &no_of_samples);
987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WebRtcIsacfix_SplitAndFilter2(outframeWB, &(outframeNB[k*240]), dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    declen += no_of_samples;
991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    noOfLostFrames--;
992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    k++;
993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  declen>>=1;
996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (k=0;k<declen;k++) {
998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    decoded[k] = outframeNB[k];
999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return declen;
1002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
10037796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
1004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_DecodePlc(...)
1010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function conducts PLC for ISAC frame(s) in wide-band (16kHz sampling).
1012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output speech length  will be "480*noOfLostFrames" samples
1013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that is equevalent of "30*noOfLostFrames" millisecond.
1014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
1017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - noOfLostFrames    : Number of PLC frames (480sample = 30ms)
1018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                                to produce
1019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
1021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - decoded           : The decoded vector
1022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : >0 - number of samples in decoded PLC vector
1024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
1025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
10270946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_DecodePlc(ISACFIX_MainStruct *ISAC_main_inst,
10280946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                int16_t          *decoded,
10290946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                int16_t noOfLostFrames)
1030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1032728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting  int16_t no_of_samples, declen, k;
10330946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t outframe16[MAX_FRAMESAMPLES];
1034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */
1040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (noOfLostFrames > 2) {
1041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    noOfLostFrames = 2;
1042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  k = 0;
1044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  declen = 0;
1045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  while( noOfLostFrames > 0 )
1046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
1047728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting    WebRtcIsacfix_DecodePlcImpl(&(outframe16[k*480]), &ISAC_inst->ISACdec_obj,
1048728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                &no_of_samples);
1049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    declen += no_of_samples;
1050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    noOfLostFrames--;
1051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    k++;
1052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (k=0;k<declen;k++) {
1055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    decoded[k] = outframe16[k];
1056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return declen;
1059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_Control(...)
1064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function sets the limit on the short-term average bit rate and the
1066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * frame length. Should be used only in Instantaneous mode.
1067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
1070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rate              : limit on the short-term average bit rate,
1071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            in bits/second (between 10000 and 32000)
1072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - framesize         : number of milliseconds per frame (30 or 60)
1073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : 0  - ok
1075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
1076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
10780946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_Control(ISACFIX_MainStruct *ISAC_main_inst,
1079aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                              int16_t rate,
1080aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                              int framesize)
1081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (ISAC_inst->CodingMode == 0)
1087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
1088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* in adaptive mode */
1089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_MODE_MISMATCH;
1090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (rate >= 10000 && rate <= 32000)
1095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->ISACenc_obj.BottleNeck = rate;
1096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else {
1097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK;
1098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (framesize  == 30 || framesize == 60)
1104aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting    ISAC_inst->ISACenc_obj.new_framelength = (int16_t)((FS/1000) * framesize);
1105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else {
1106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH;
1107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
11133258db26ed7cedd20e1e21aca70d8304c7cef218kwibergvoid WebRtcIsacfix_SetInitialBweBottleneck(ISACFIX_MainStruct* ISAC_main_inst,
11143258db26ed7cedd20e1e21aca70d8304c7cef218kwiberg                                           int bottleneck_bits_per_second) {
11153258db26ed7cedd20e1e21aca70d8304c7cef218kwiberg  ISACFIX_SubStruct* inst = (ISACFIX_SubStruct*)ISAC_main_inst;
11163258db26ed7cedd20e1e21aca70d8304c7cef218kwiberg  assert(bottleneck_bits_per_second >= 10000 &&
11173258db26ed7cedd20e1e21aca70d8304c7cef218kwiberg         bottleneck_bits_per_second <= 32000);
11183258db26ed7cedd20e1e21aca70d8304c7cef218kwiberg  inst->bwestimator_obj.sendBwAvg = ((uint32_t)bottleneck_bits_per_second) << 7;
11193258db26ed7cedd20e1e21aca70d8304c7cef218kwiberg}
1120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_ControlBwe(...)
1123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function sets the initial values of bottleneck and frame-size if
1125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * iSAC is used in channel-adaptive mode. Through this API, users can
1126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * enforce a frame-size for all values of bottleneck. Then iSAC will not
1127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * automatically change the frame-size.
1128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  - ISAC_main_inst : ISAC instance.
1132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rateBPS           : initial value of bottleneck in bits/second
1133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            10000 <= rateBPS <= 32000 is accepted
1134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            For default bottleneck set rateBPS = 0
1135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - frameSizeMs       : number of milliseconds per frame (30 or 60)
1136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - enforceFrameSize  : 1 to enforce the given frame-size through out
1137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            the adaptation process, 0 to let iSAC change
1138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            the frame-size if required.
1139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value    : 0  - ok
1141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *         -1 - Error
1142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
11440946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_ControlBwe(ISACFIX_MainStruct *ISAC_main_inst,
11450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                 int16_t rateBPS,
1146aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                                 int frameSizeMs,
11470946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                 int16_t enforceFrameSize)
1148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Typecast pointer to real structure */
1151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if encoder initiated */
1154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 2) != 2) {
1155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
1156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
1157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Check that we are in channel-adaptive mode, otherwise, return -1 */
1160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (ISAC_inst->CodingMode != 0) {
1161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_MODE_MISMATCH;
1162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
1163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Set struct variable if enforceFrameSize is set. ISAC will then keep the */
1166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* chosen frame size.                                                      */
1167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.enforceFrameSize = (enforceFrameSize != 0)? 1:0;
1168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Set initial rate, if value between 10000 and 32000,                */
1170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* if rateBPS is 0, keep the default initial bottleneck value (15000) */
1171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((rateBPS >= 10000) && (rateBPS <= 32000)) {
11720946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    ISAC_inst->bwestimator_obj.sendBwAvg = (((uint32_t)rateBPS) << 7);
1173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else if (rateBPS != 0) {
1174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK;
1175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Set initial framesize. If enforceFrameSize is set the frame size will not change */
1179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((frameSizeMs  == 30) || (frameSizeMs == 60)) {
1180aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting    ISAC_inst->ISACenc_obj.new_framelength = (int16_t)((FS/1000) * frameSizeMs);
1181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else {
1182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH;
1183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_GetDownLinkBwIndex(...)
1195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function returns index representing the Bandwidth estimate from
1197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * other side to this side.
1198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst: iSAC struct
1201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
1203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rateIndex     : Bandwidth estimate to transmit to other side.
1204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
12070946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_GetDownLinkBwIndex(ISACFIX_MainStruct* ISAC_main_inst,
12080946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                         int16_t*     rateIndex)
1209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Call function to get Bandwidth Estimate */
1216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  *rateIndex = WebRtcIsacfix_GetDownlinkBwIndexImpl(&ISAC_inst->bwestimator_obj);
1217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_UpdateUplinkBw(...)
1224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function takes an index representing the Bandwidth estimate from
1226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * this side to other side and updates BWE.
1227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst: iSAC struct
1230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rateIndex     : Bandwidth estimate from other side.
1231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
12340946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct* ISAC_main_inst,
12350946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                     int16_t     rateIndex)
1236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
12370946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t err = 0;
1238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Call function to update BWE with received Bandwidth Estimate */
1244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = WebRtcIsacfix_UpdateUplinkBwRec(&ISAC_inst->bwestimator_obj, rateIndex);
1245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err < 0) {
1246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = -err;
1247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
1248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_ReadFrameLen(...)
1255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function returns the length of the frame represented in the packet.
1257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded       : Encoded bitstream
1260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
1262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - frameLength   : Length of frame in packet (in samples)
1263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
12661172988c794d15706b4c951dcbaa57b11221d225kwiberg@webrtc.orgint16_t WebRtcIsacfix_ReadFrameLen(const uint8_t* encoded,
1267532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org                                   int encoded_len_bytes,
12680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                   int16_t* frameLength)
1269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  Bitstr_dec streamdata;
12710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t err;
1272532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  const int kRequiredEncodedLenBytes = 10;
1273532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org
1274532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  if (encoded_len_bytes < kRequiredEncodedLenBytes) {
1275532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    return -1;
1276532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  }
1277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1278532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  InitializeDecoderBitstream(encoded_len_bytes, &streamdata);
1279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
12800552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
1281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* decode frame length */
1283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = WebRtcIsacfix_DecodeFrameLen(&streamdata, frameLength);
1284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err<0)  // error check
1285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
1286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_ReadBwIndex(...)
1293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function returns the index of the Bandwidth estimate from the bitstream.
1295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded       : Encoded bitstream
1298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
1300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - frameLength   : Length of frame in packet (in samples)
1301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rateIndex     : Bandwidth estimate in bitstream
1302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13051172988c794d15706b4c951dcbaa57b11221d225kwiberg@webrtc.orgint16_t WebRtcIsacfix_ReadBwIndex(const uint8_t* encoded,
1306532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org                                  int encoded_len_bytes,
13070946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                  int16_t* rateIndex)
1308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  Bitstr_dec streamdata;
13100946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t err;
1311532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  const int kRequiredEncodedLenBytes = 10;
1312532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org
1313532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  if (encoded_len_bytes < kRequiredEncodedLenBytes) {
1314532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    return -1;
1315532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  }
1316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1317532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  InitializeDecoderBitstream(encoded_len_bytes, &streamdata);
1318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13190552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
1320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* decode frame length, needed to get to the rateIndex in the bitstream */
1322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = WebRtcIsacfix_DecodeFrameLen(&streamdata, rateIndex);
1323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err<0)  // error check
1324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
1325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* decode BW estimation */
1327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = WebRtcIsacfix_DecodeSendBandwidth(&streamdata, rateIndex);
1328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err<0)  // error check
1329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
1330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_GetErrorCode(...)
1339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function can be used to check the error code of an iSAC instance. When
1341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * a function returns -1 a error code will be set for that instance. The
1342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * function below extract the code of the last error that occured in the
1343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * specified instance.
1344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance
1347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : Error code
1349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13510946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_GetErrorCode(ISACFIX_MainStruct *ISAC_main_inst)
1352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return ISAC_inst->errorcode;
1358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_GetUplinkBw(...)
1364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function returns the inst quantized iSAC send bitrate
1366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : iSAC instance
1369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : bitrate
1371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint32_t WebRtcIsacfix_GetUplinkBw(ISACFIX_MainStruct *ISAC_main_inst)
1374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  BwEstimatorstr * bw = (BwEstimatorstr*)&(ISAC_inst->bwestimator_obj);
1377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13780946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  return (int32_t) WebRtcIsacfix_GetUplinkBandwidth(bw);
1379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_GetNewFrameLen(...)
1383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function return the next frame length (in samples) of iSAC.
1385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : iSAC instance
1388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             :  frame lenght in samples
1390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13920946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_GetNewFrameLen(ISACFIX_MainStruct *ISAC_main_inst)
1393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return ISAC_inst->ISACenc_obj.new_framelength;
1396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_SetMaxPayloadSize(...)
1401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function sets a limit for the maximum payload size of iSAC. The same
1403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * value is used both for 30 and 60 msec packets.
1404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * The absolute max will be valid until next time the function is called.
1405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * NOTE! This function may override the function WebRtcIsacfix_SetMaxRate()
1406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : iSAC instance
1409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - maxPayloadBytes   : maximum size of the payload in bytes
1410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            valid values are between 100 and 400 bytes
1411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : 0 if sucessful
1414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                           -1 if error happens
1415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
14170946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_MainStruct *ISAC_main_inst,
14180946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        int16_t maxPayloadBytes)
1419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if((maxPayloadBytes < 100) || (maxPayloadBytes > 400))
1426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
1427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* maxPayloadBytes is out of valid range */
1428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else
1431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
1432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Set new absolute max, which will not change unless this function
1433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       is called again with a new value */
1434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->ISACenc_obj.maxPayloadBytes = maxPayloadBytes;
1435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Set new maximum values for 30 and 60 msec packets */
1437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (maxPayloadBytes < ISAC_inst->ISACenc_obj.maxRateInBytes) {
1438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxPayloadBytes;
1439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    } else {
1440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxRateInBytes;
1441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
1442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if ( maxPayloadBytes < (ISAC_inst->ISACenc_obj.maxRateInBytes << 1)) {
1444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes60 = maxPayloadBytes;
1445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    } else {
1446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (ISAC_inst->ISACenc_obj.maxRateInBytes << 1);
1447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
1448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_SetMaxRate(...)
1455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function sets the maximum rate which the codec may not exceed for a
1457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * singel packet. The maximum rate is set in bits per second.
1458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * The codec has an absolute maximum rate of 53400 bits per second (200 bytes
1459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * per 30 msec).
1460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * It is possible to set a maximum rate between 32000 and 53400 bits per second.
1461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * The rate limit is valid until next time the function is called.
1463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * NOTE! Packet size will never go above the value set if calling
1465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_SetMaxPayloadSize() (default max packet size is 400 bytes).
1466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : iSAC instance
1469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - maxRateInBytes    : maximum rate in bits per second,
1470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            valid values are 32000 to 53400 bits
1471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : 0 if sucessful
1473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                           -1 if error happens
1474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
14760946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_SetMaxRate(ISACFIX_MainStruct *ISAC_main_inst,
14770946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                 int32_t maxRate)
1478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
14800946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t maxRateInBytes;
1481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if((maxRate < 32000) || (maxRate > 53400))
1486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
1487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* maxRate is out of valid range */
1488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else
1491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
1492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Calculate maximum number of bytes per 30 msec packets for the given
1493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       maximum rate. Multiply with 30/1000 to get number of bits per 30 msec,
1494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       divide by 8 to get number of bytes per 30 msec:
1495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       maxRateInBytes = floor((maxRate * 30/1000) / 8); */
14960946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    maxRateInBytes = (int16_t)( WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_MUL(maxRate, 3), 800) );
1497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Store the value for usage in the WebRtcIsacfix_SetMaxPayloadSize-function */
1499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->ISACenc_obj.maxRateInBytes = maxRateInBytes;
1500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* For 30 msec packets: if the new limit is below the maximum
1502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       payload size, set a new limit */
1503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (maxRateInBytes < ISAC_inst->ISACenc_obj.maxPayloadBytes) {
1504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxRateInBytes;
1505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    } else {
1506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxPayloadBytes;
1507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
1508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* For 60 msec packets: if the new limit (times 2) is below the
1510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       maximum payload size, set a new limit */
1511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if ( (maxRateInBytes << 1) < ISAC_inst->ISACenc_obj.maxPayloadBytes) {
1512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (maxRateInBytes << 1);
1513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    } else {
1514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes60 = ISAC_inst->ISACenc_obj.maxPayloadBytes;
1515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
1516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_version(...)
1525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function returns the version number.
1527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
1529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - version  : Pointer to character string
1530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid WebRtcIsacfix_version(char *version)
1534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  strcpy(version, "3.6.0");
1536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
15372224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg
15382224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wibergvoid WebRtcIsacfix_GetBandwidthInfo(ISACFIX_MainStruct* ISAC_main_inst,
15392224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg                                    IsacBandwidthInfo* bwinfo) {
15402224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg  ISACFIX_SubStruct* inst = (ISACFIX_SubStruct*)ISAC_main_inst;
15412224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg  assert(inst->initflag & 1);  // Decoder initialized.
15422224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg  WebRtcIsacfixBw_GetBandwidthInfo(&inst->bwestimator_obj, bwinfo);
15432224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg}
15442224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg
15452224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wibergvoid WebRtcIsacfix_SetBandwidthInfo(ISACFIX_MainStruct* ISAC_main_inst,
15462224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg                                    const IsacBandwidthInfo* bwinfo) {
15472224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg  ISACFIX_SubStruct* inst = (ISACFIX_SubStruct*)ISAC_main_inst;
15482224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg  assert(inst->initflag & 2);  // Encoder initialized.
15492224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg  WebRtcIsacfixBw_SetBandwidthInfo(&inst->bwestimator_obj, bwinfo);
15502224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg}
1551